diff --git a/DEPS b/DEPS index dd60cf8..fa37d7e 100644 --- a/DEPS +++ b/DEPS
@@ -309,11 +309,11 @@ # 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': '2e4223a5f4bf0d20e9862ddd9c44bd0db669482a', + 'skia_revision': 'b0c40a307d34a229b789420f5f149d734d84e47c', # 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': '6c11bd07c6f7e8152f4276beb5af0c241ad93d7a', + 'v8_revision': 'ac70c755230f2856e08aa06d6fecbc3f01822758', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -336,7 +336,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:12.20230413.0.1', + 'fuchsia_version': 'version:12.20230413.2.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. @@ -396,7 +396,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': '4054d1ec6a7211c707847713eda35c00d047cbe9', + 'devtools_frontend_revision': 'ea48b9015d8560c423b7e3fbdc996a6fdf0f7f0a', # 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. @@ -436,11 +436,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '2200823afd79add9701ba456845763e32b4716a8', + 'dawn_revision': 'a49353d4cd62655ecb72f4cbdb4dce7e370013ec', # 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': '385be0b4fa0b5eb5259d6673f154554dbc316250', + 'quiche_revision': 'e7e19a41c1475cc580bc1dccb558354261cc3ca9', # 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. @@ -460,7 +460,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': '472a1d847b581b73bb577de6a063214606d9a685', + 'nearby_revision': 'b023a666b95f94be4f9b2070c4d0055ced78ea19', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -472,7 +472,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'cros_components_revision': '0ce149215c1ecdca92181f4a9e77d3f74c3669ad', + 'cros_components_revision': '65e9533990a11364d8b6581ebe1255ea40e30b85', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -800,7 +800,7 @@ }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + 'c61ffdadc523af5cf7d0bf68edb58c466b443a91', + 'url': Var('chromium_git') + '/website.git' + '@' + 'f0e80c7e5b02717591271b37a222dc763b426bd2', }, 'src/ios/third_party/earl_grey2/src': { @@ -894,7 +894,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'uDGU2Ho9AnZfBoc805SH7xFdhWLLOPRhbxyF24AkdUAC', + 'version': 'a-BAF4nZtxy5GieXXwU6QcnVvIpMbb_WEOAHnFpa644C', }, ], 'dep_type': 'cipd', @@ -905,7 +905,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'mDjfc8yVzZMzhUvuI1FMQt8zWpwmr_iZSA0P2KjotRwC', + 'version': '7ZTAd_iLzn-5i-ZFBMaPt1fNwITxyIzW4_YWC7gScZoC', }, ], 'dep_type': 'cipd', @@ -916,7 +916,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'IhLVcXE4gfcVOfXHbRbharUD-8UZwImuHYQOoLcASS4C', + 'version': '7mKIUu9bLXVEGqWoJ6YaUB-ahi4p-gDJmHEsV4EQkOgC', }, ], 'dep_type': 'cipd', @@ -1187,7 +1187,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9e7b29e1352dcdb45bf135a29ac5b16eb018a6a7', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '530a1bcfd20a273cc5cc0589c0b9fbd9071d7fcb', 'condition': 'checkout_chromeos', }, @@ -1225,7 +1225,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b1a213f3fa53081ef7e40ed6237e706cff33692e', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '82ce0c2b01d5f959d297b0b0a5b4363b75143249', 'condition': 'checkout_src_internal', }, @@ -1700,7 +1700,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '1c46d9577664f7cd811b4fe9c884f66a99697615', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b57a685175d3070783d25958e0851b8d077b6280', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1740,7 +1740,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'Qs7IdwPHgKR42jCzqTBPNEMjs0uPNpDXs29NfiBcsHIC', + 'version': 'OJEhACoTcZTFN4k6C2BsgW7xzXm818cNOV_6yhZZHwkC', }, ], 'condition': 'checkout_android', @@ -1885,7 +1885,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0ac5d460dab4d56f3c07c43eee895557c9d3b9e4', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'fb8e3de0a8b9b2bba8098ed07be06115c13e904e', + Var('webrtc_git') + '/src.git' + '@' + 'c087d0cce50d2fa75f55e0aeb3f8f0763a80a960', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1975,7 +1975,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@898ea6e5c95b3a47aaae29d026df0378138f4a5b', + 'url': Var('chrome_git') + '/chrome/src-internal.git@3146ac33668eafeb7543f352648247a9f259a4a0', 'condition': 'checkout_src_internal', }, @@ -2005,7 +2005,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'OQ8TTfE9eVFq9aK45B6-vVJURPnY9bNoDKVV95dTfigC', + 'version': 'V4TW7Y9dWTSn1F8PEo5M7YQlsYWDZNgOg31yr_XkTwcC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2016,7 +2016,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'tZ6xpb46Nvrf9SRtFBItPe2hnGhvPic5fASnC7Gdw7gC', + 'version': 'TmF_BE4yuQjofhnuDyEoQ5g27UrDSbXneqBjyNNckGsC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 6c2ac729..462700ed 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1568,6 +1568,18 @@ False, [] ), + BanRule( + r'objc/objc.h', + ( + 'Do not include <objc/objc.h>. It defines away ARC lifetime ' + 'annotations, and is thus dangerous.', + 'Please use the pimpl pattern; search for `ObjCStorage` for examples.', + 'For further reading on how to safely mix C++ and Obj-C, see', + 'https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md' + ), + True, + [] + ), ) _BANNED_MOJOM_PATTERNS : Sequence[BanRule] = (
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 5b5c4192..127e8e42 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -795,6 +795,7 @@ "//third_party/blink/public/common:common_java", "//third_party/blink/renderer/platform/scheduler:blink_scheduler_java", "//ui/accessibility:accessibility_features_java", + "//ui/android:ui_android_features_java", ] srcjar_deps = [ ":common_java_features_srcjar",
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index c9f9fff..984aa27 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -27,6 +27,7 @@ import org.chromium.services.network.NetworkServiceFeatures; import org.chromium.services.tracing.TracingServiceFeatures; import org.chromium.ui.accessibility.AccessibilityFeatures; +import org.chromium.ui.base.UiAndroidFeatures; /** * List of experimental features/flags supported for user devices. Add features/flags to this list @@ -411,6 +412,10 @@ Flag.baseFeature(AwFeatures.WEBVIEW_SAFE_BROWSING_SAFE_MODE, "Enable doing a JNI call to check safe browsing safe mode status " + "before doing a safe browsing check."), + Flag.baseFeature(UiAndroidFeatures.CONVERT_TRACKPAD_EVENTS_TO_MOUSE, + "Enables converting trackpad click gestures to mouse events" + + " in order for them to be interpreted similar to a desktop" + + " experience (i.e. double-click to select word.)"), // Add new commandline switches and features above. The final entry should have a // trailing comma for cleaner diffs. };
diff --git a/ash/accessibility/magnifier/docked_magnifier_controller.cc b/ash/accessibility/magnifier/docked_magnifier_controller.cc index 399621f..5f1181b 100644 --- a/ash/accessibility/magnifier/docked_magnifier_controller.cc +++ b/ash/accessibility/magnifier/docked_magnifier_controller.cc
@@ -20,7 +20,6 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/work_area_insets.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_registry_simple.h" @@ -148,7 +147,7 @@ if (active_user_pref_service_) { active_user_pref_service_->SetDouble( prefs::kDockedMagnifierScale, - base::clamp(scale, kMinMagnifierScale, kMaxMagnifierScale)); + std::clamp(scale, kMinMagnifierScale, kMaxMagnifierScale)); } } @@ -157,8 +156,8 @@ if (active_user_pref_service_) { active_user_pref_service_->SetDouble( prefs::kDockedMagnifierScreenHeightDivisor, - base::clamp(screen_height_divisor, kMinScreenHeightDivisor, - kMaxScreenHeightDivisor)); + std::clamp(screen_height_divisor, kMinScreenHeightDivisor, + kMaxScreenHeightDivisor)); } } @@ -468,9 +467,9 @@ case ui::ET_MOUSE_DRAGGED: // User continues holding and drags separator to resize Docked Magnifier. if (is_resizing_) { - SetScreenHeightDivisor(base::clamp(new_screen_height_divisor, - kMinScreenHeightDivisor, - kMaxScreenHeightDivisor)); + SetScreenHeightDivisor(std::clamp(new_screen_height_divisor, + kMinScreenHeightDivisor, + kMaxScreenHeightDivisor)); OnDisplayConfigurationChanged(); } break;
diff --git a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc index 4245ce21..c52d35a 100644 --- a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc +++ b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc
@@ -19,7 +19,6 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/shell.h" -#include "base/cxx17_backports.h" #include "ui/accessibility/accessibility_switches.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/window.h" @@ -750,7 +749,7 @@ } void FullscreenMagnifierController::ValidateScale(float* scale) { - *scale = base::clamp(*scale, kNonMagnifiedScale, kMaxMagnifiedScale); + *scale = std::clamp(*scale, kNonMagnifiedScale, kMaxMagnifiedScale); DCHECK(kNonMagnifiedScale <= *scale && *scale <= kMaxMagnifiedScale); }
diff --git a/ash/accessibility/magnifier/magnifier_utils.cc b/ash/accessibility/magnifier/magnifier_utils.cc index efb62ad..4b4756c7 100644 --- a/ash/accessibility/magnifier/magnifier_utils.cc +++ b/ash/accessibility/magnifier/magnifier_utils.cc
@@ -11,7 +11,6 @@ #include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h" #include "ash/shell.h" #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/ime/ash/ime_bridge.h" @@ -57,7 +56,7 @@ const int current_index = IndexFromScale(current_scale); const int new_scale_index = current_index + delta_index; const float new_scale = std::pow(kMagnificationScaleFactor, new_scale_index); - return base::clamp(new_scale, min_scale, max_scale); + return std::clamp(new_scale, min_scale, max_scale); } gfx::Rect GetViewportWidgetBoundsInRoot(aura::Window* root,
diff --git a/ash/accessibility/ui/layer_animation_info.cc b/ash/accessibility/ui/layer_animation_info.cc index 1556da9..63d6af4 100644 --- a/ash/accessibility/ui/layer_animation_info.cc +++ b/ash/accessibility/ui/layer_animation_info.cc
@@ -4,7 +4,7 @@ #include "ash/accessibility/ui/layer_animation_info.h" -#include "base/cxx17_backports.h" +#include <algorithm> namespace ash { @@ -33,7 +33,7 @@ opacity = 1.0 - (change_delta / (fade_in_time + fade_out_time)); // Layer::SetOpacity will throw an error if we're not within 0...1. - animation_info->opacity = base::clamp(opacity, 0.0f, 1.0f); + animation_info->opacity = std::clamp(opacity, 0.0f, 1.0f); } } // namespace ash
diff --git a/ash/app_list/app_list_bubble_presenter.cc b/ash/app_list/app_list_bubble_presenter.cc index eed43a99..3fb0a0df 100644 --- a/ash/app_list/app_list_bubble_presenter.cc +++ b/ash/app_list/app_list_bubble_presenter.cc
@@ -4,6 +4,7 @@ #include "ash/app_list/app_list_bubble_presenter.h" +#include <algorithm> #include <memory> #include <utility> @@ -27,7 +28,6 @@ #include "ash/wm/container_finder.h" #include "base/check.h" #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/i18n/rtl.h" #include "base/logging.h" @@ -106,7 +106,7 @@ int max_height = (work_area.height() - shelf_size - kExtraTopOfScreenSpacing) / 2; DCHECK_GE(max_height, default_height); - height = base::clamp(height_to_fit_all_apps, default_height, max_height); + height = std::clamp(height_to_fit_all_apps, default_height, max_height); } return gfx::Size(width, height);
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 441635e..5b89b39 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -1913,10 +1913,11 @@ return bubble_presenter_->GetPreferredBubbleWidth(root_window); } -void AppListControllerImpl::SetHomeButtonQuickApp(const std::string& app_id) { - if (features::IsHomeButtonQuickAppAccessEnabled()) { - model_provider_->quick_app_access_model()->SetQuickApp(app_id); +bool AppListControllerImpl::SetHomeButtonQuickApp(const std::string& app_id) { + if (!features::IsHomeButtonQuickAppAccessEnabled()) { + return false; } + return model_provider_->quick_app_access_model()->SetQuickApp(app_id); } } // namespace ash
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index fd4d3d74..a4b553a 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -348,7 +348,9 @@ // Set the launchable quick app button shown next to the home button. This app // icon is shown next to the home button until the app is launched or the // launcher is opened. - void SetHomeButtonQuickApp(const std::string& app_id); + // Returns true when the quick app was changed to a valid `app_id` or reset + // using an empty `app_id`. + bool SetHomeButtonQuickApp(const std::string& app_id); private: // Convenience methods for getting models from `model_provider_`.
diff --git a/ash/app_list/app_list_model_provider.h b/ash/app_list/app_list_model_provider.h index 0e5c4c6..523c060 100644 --- a/ash/app_list/app_list_model_provider.h +++ b/ash/app_list/app_list_model_provider.h
@@ -83,7 +83,8 @@ AppListModel* model_ = &default_model_; SearchModel* search_model_ = &default_search_model_; - QuickAppAccessModel* quick_app_access_model_; + QuickAppAccessModel* quick_app_access_model_ = + &default_quick_app_access_model_; base::ObserverList<Observer> observers_; };
diff --git a/ash/app_list/model/app_list_item.cc b/ash/app_list/model/app_list_item.cc index 9232dd2..58f15bf6 100644 --- a/ash/app_list/model/app_list_item.cc +++ b/ash/app_list/model/app_list_item.cc
@@ -73,6 +73,10 @@ observer.ItemIconChanged(config_type); } } + + for (auto& observer : observers_) { + observer.ItemDefaultIconChanged(); + } } const gfx::ImageSkia& AppListItem::GetDefaultIcon() const {
diff --git a/ash/app_list/model/app_list_item_observer.h b/ash/app_list/model/app_list_item_observer.h index a7b2fa1..ea4767e 100644 --- a/ash/app_list/model/app_list_item_observer.h +++ b/ash/app_list/model/app_list_item_observer.h
@@ -18,6 +18,9 @@ // changed. virtual void ItemIconChanged(AppListConfigType config_type) {} + // Invoked after the item's default icon changes. + virtual void ItemDefaultIconChanged() {} + // Invoked after item's icon version number is changed. virtual void ItemIconVersionChanged() {}
diff --git a/ash/app_list/quick_app_access_model.cc b/ash/app_list/quick_app_access_model.cc index 52e8c0af..a9f69738 100644 --- a/ash/app_list/quick_app_access_model.cc +++ b/ash/app_list/quick_app_access_model.cc
@@ -4,6 +4,15 @@ #include "ash/app_list/quick_app_access_model.h" +#include <string> + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/app_list_model_provider.h" +#include "ash/app_list/model/app_list_item.h" +#include "ash/shell.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/gfx/image/image_skia_rep.h" + namespace ash { QuickAppAccessModel::QuickAppAccessModel() = default; @@ -18,14 +27,131 @@ observers_.RemoveObserver(observer); } -void QuickAppAccessModel::SetQuickApp(const std::string& app_id) { - quick_app_id_ = app_id; - for (auto& observer : observers_) { - // TODO(b/266734005): Check whether the app has an icon already loaded, if - // not, then call LoadIcon() to begin the icon loading process for the quick - // app. Call OnQuickAppChanged once the icon is loaded. - observer.OnQuickAppChanged(); +bool QuickAppAccessModel::SetQuickApp(const std::string& app_id) { + if (quick_app_id_ == app_id) { + return false; } + + if (app_id.empty()) { + // Remove quick app when setting a quick app with an empty app id. + ClearQuickApp(); + UpdateQuickAppShouldShowState(); + return true; + } + + AppListItem* item = AppListModelProvider::Get()->model()->FindItem(app_id); + if (!item) { + // Return and don't set the quick app id if the app item doesn't exist. + return false; + } + + ClearQuickApp(); + quick_app_id_ = app_id; + item_observation_.Observe(item); + + // Request to load in the icon when the app item's icon is null. + if (item->GetDefaultIcon().isNull()) { + // TODO(b/266734005): add a histogram that tracks delay between calling + // LoadIcon and getting an icon loaded + Shell::Get()->app_list_controller()->LoadIcon(app_id); + } + + // When quick app is already in a show state, notify that the app icon has + // changed to cover the case where the shown quick app is changed to another + // app. + if (quick_app_should_show_state_) { + for (auto& observer : observers_) { + observer.OnQuickAppIconChanged(); + } + } + + UpdateQuickAppShouldShowState(); + return true; +} + +void QuickAppAccessModel::SetQuickAppActivated() { + quick_app_activated_ = true; + UpdateQuickAppShouldShowState(); +} + +gfx::ImageSkia QuickAppAccessModel::GetAppIcon(gfx::Size icon_size) { + AppListItem* item = GetQuickAppItem(); + + if (!item) { + return gfx::ImageSkia(); + } + + gfx::ImageSkia image = item->GetDefaultIcon(); + + if (item->GetDefaultIcon().isNull()) { + return gfx::ImageSkia(); + } + + image = gfx::ImageSkiaOperations::CreateResizedImage( + image, skia::ImageOperations::RESIZE_BEST, icon_size); + return image; +} + +void QuickAppAccessModel::ItemDefaultIconChanged() { + if (quick_app_should_show_state_) { + // If quick app should already be shown, notify observers when the changed + // icon is not null. + if (!GetQuickAppItem()->GetDefaultIcon().isNull()) { + for (auto& observer : observers_) { + observer.OnQuickAppIconChanged(); + } + } + } else { + UpdateQuickAppShouldShowState(); + } +} + +void QuickAppAccessModel::ItemBeingDestroyed() { + ClearQuickApp(); + UpdateQuickAppShouldShowState(); +} + +void QuickAppAccessModel::OnAppListVisibilityChanged(bool shown, + int64_t display_id) { + if (shown) { + app_list_shown_ = true; + UpdateQuickAppShouldShowState(); + } +} + +AppListItem* QuickAppAccessModel::GetQuickAppItem() { + return AppListModelProvider::Get()->model()->FindItem(quick_app_id_); +} + +void QuickAppAccessModel::UpdateQuickAppShouldShowState() { + const bool prev_should_show_quick_app = quick_app_should_show_state_; + quick_app_should_show_state_ = ShouldShowQuickApp(); + + if (prev_should_show_quick_app == quick_app_should_show_state_) { + return; + } + + if (!quick_app_should_show_state_) { + app_list_controller_observer_.Reset(); + } else { + app_list_controller_observer_.Observe(Shell::Get()->app_list_controller()); + } + + for (auto& observer : observers_) { + observer.OnQuickAppShouldShowChanged(quick_app_should_show_state_); + } +} + +bool QuickAppAccessModel::ShouldShowQuickApp() { + return !quick_app_id_.empty() && !app_list_shown_ && !quick_app_activated_ && + !GetQuickAppItem()->GetDefaultIcon().isNull(); +} + +void QuickAppAccessModel::ClearQuickApp() { + quick_app_id_ = ""; + app_list_shown_ = false; + quick_app_activated_ = false; + item_observation_.Reset(); } } // namespace ash
diff --git a/ash/app_list/quick_app_access_model.h b/ash/app_list/quick_app_access_model.h index b617fe4..c7b7fb7 100644 --- a/ash/app_list/quick_app_access_model.h +++ b/ash/app_list/quick_app_access_model.h
@@ -8,42 +8,99 @@ #include <string> #include "ash/app_list/model/app_list_item_observer.h" +#include "ash/public/cpp/app_list/app_list_controller_observer.h" #include "base/observer_list.h" +#include "base/scoped_observation.h" + +namespace gfx { +class ImageSkia; +class Size; +} // namespace gfx namespace ash { +class AppListItem; +class AppListController; + // The model which holds information on which app is currently set as the quick // app. Shelf home buttons observe changes to this model and will show/hide the // quick app button accordingly. -class QuickAppAccessModel { +class QuickAppAccessModel : public AppListItemObserver, + public AppListControllerObserver { public: class Observer : public base::CheckedObserver { public: ~Observer() override = default; - // Called when the currently set quick app changes. - virtual void OnQuickAppChanged() = 0; + // Called when the quick app shown state changes. + virtual void OnQuickAppShouldShowChanged(bool show_quick_app) = 0; + + // Called when the default icon for the quick app icon changes. + virtual void OnQuickAppIconChanged() = 0; }; QuickAppAccessModel(); QuickAppAccessModel(const QuickAppAccessModel&) = delete; QuickAppAccessModel& operator=(const QuickAppAccessModel&) = delete; - ~QuickAppAccessModel(); + ~QuickAppAccessModel() override; void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - // Set the quick app to be shown next to home buttons in the shelf. - void SetQuickApp(const std::string& app_id); + // Set the quick app what will be shown next to home buttons in the shelf. + // Returns true when the quick app was changed to a valid `app_id` or reset + // using an empty `app_id`. + bool SetQuickApp(const std::string& app_id); + + // Set the quick app as activated and update the quick app shown state. + void SetQuickAppActivated(); + + // Returns the quick app's icon as an image, sized to 'icon_size'. + gfx::ImageSkia GetAppIcon(gfx::Size icon_size); const std::string& quick_app_id() { return quick_app_id_; } + bool quick_app_should_show_state() { return quick_app_should_show_state_; } private: + // AppListItemObserver: + void ItemDefaultIconChanged() override; + void ItemBeingDestroyed() override; + + // AppListControllerObserver: + void OnAppListVisibilityChanged(bool shown, int64_t display_id) override; + + AppListItem* GetQuickAppItem(); + + // Checks if the should show state of the quick app has changed, and notifies + // observers when the state does change. + void UpdateQuickAppShouldShowState(); + + // Calculates and returns whether the quick app should show. + bool ShouldShowQuickApp(); + + // Reset the quick app id and other associated variables to their default + // values. + void ClearQuickApp(); + + // Whether the app list has shown for the currently set quick app. + bool app_list_shown_ = false; + + // Whether the currently set quick app has been activated. + bool quick_app_activated_ = false; + base::ObserverList<Observer> observers_; + base::ScopedObservation<AppListItem, AppListItemObserver> item_observation_{ + this}; + base::ScopedObservation<AppListController, AppListControllerObserver> + app_list_controller_observer_{this}; + // The app id for the quick app. std::string quick_app_id_; + + // Whether the quick app is in a state such that it should be shown. + bool quick_app_should_show_state_ = false; }; } // namespace ash
diff --git a/ash/app_list/test_app_list_client.cc b/ash/app_list/test_app_list_client.cc index eb00dc8c..ddca556 100644 --- a/ash/app_list/test_app_list_client.cc +++ b/ash/app_list/test_app_list_client.cc
@@ -101,6 +101,10 @@ void TestAppListClient::OpenSearchBoxIphUrl() {} +void TestAppListClient::LoadIcon(int profile_id, const std::string& app_id) { + loaded_icon_app_ids_.push_back(app_id); +} + std::vector<TestAppListClient::SearchResultActionId> TestAppListClient::GetAndResetInvokedResultActions() { std::vector<SearchResultActionId> result;
diff --git a/ash/app_list/test_app_list_client.h b/ash/app_list/test_app_list_client.h index 7a2df45..36e6fc5 100644 --- a/ash/app_list/test_app_list_client.h +++ b/ash/app_list/test_app_list_client.h
@@ -62,7 +62,7 @@ void RecalculateWouldTriggerLauncherSearchIph() override; std::unique_ptr<ScopedIphSession> CreateLauncherSearchIphSession() override; void OpenSearchBoxIphUrl() override; - void LoadIcon(int profile_id, const std::string& app_id) override {} + void LoadIcon(int profile_id, const std::string& app_id) override; ash::AppListSortOrder GetPermanentSortingOrder() const override; void CommitTemporarySortOrder() override; @@ -88,6 +88,10 @@ return last_opened_search_result_; } + std::vector<std::string> load_icon_app_ids() const { + return loaded_icon_app_ids_; + } + using SearchResultActionId = std::pair<std::string, int>; std::vector<SearchResultActionId> GetAndResetInvokedResultActions(); @@ -117,6 +121,7 @@ int activate_item_count_ = 0; std::string activate_item_last_id_; std::string last_opened_search_result_; + std::vector<std::string> loaded_icon_app_ids_; // If not null, callback that will be run on each search request. It can be // used by tests to inject results to search model in response to search
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 27b22645..da4a7f2 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -38,7 +38,6 @@ #include "ash/public/cpp/metrics_util.h" #include "ash/strings/grit/ash_strings.h" #include "ash/utility/haptics_util.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_macros.h" @@ -1881,7 +1880,7 @@ int col = (point.x() - bounds.x() + x_offset - GetGridCenteringOffset(selected_page).x()) / total_tile_size.width(); - col = base::clamp(col, 0, cols_ - 1); + col = std::clamp(col, 0, cols_ - 1); GridIndex max_target_index; if (selected_page == GetTotalPages() - 1) { @@ -2159,7 +2158,7 @@ cols_ = 1; } else { int preferred_cols = std::sqrt(item_list_->item_count() - 1) + 1; - cols_ = base::clamp(preferred_cols, 1, max_cols_); + cols_ = std::clamp(preferred_cols, 1, max_cols_); } PreferredSizeChanged(); @@ -2938,7 +2937,7 @@ const gfx::Vector2d grid_offset = GetGridCenteringOffset(current_page); DCHECK_GT(total_tile_size.width(), 0); - int col = base::clamp( + int col = std::clamp( (point.x() - bounds.x() - grid_offset.x()) / total_tile_size.width(), 0, cols_ - 1); @@ -2947,7 +2946,7 @@ (point.y() - bounds.y() - grid_offset.y()) / total_tile_size.height(); const absl::optional<int> tiles_per_page = TilesPerPage(current_page); const int row = tiles_per_page - ? base::clamp(ideal_row, 0, *tiles_per_page / cols_ - 1) + ? std::clamp(ideal_row, 0, *tiles_per_page / cols_ - 1) : std::max(ideal_row, 0); return GridIndex(current_page, row * cols_ + col); }
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc index c7add44c..d4f6013 100644 --- a/ash/app_list/views/contents_view.cc +++ b/ash/app_list/views/contents_view.cc
@@ -20,7 +20,6 @@ #include "ash/keyboard/ui/keyboard_ui_controller.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/notreached.h" #include "ui/compositor/layer.h" @@ -208,7 +207,7 @@ const int padded_width = GetContentsBounds().width() - 2 * AppsContainerView::kHorizontalMargin; return gfx::Size( - base::clamp(padded_width, kSearchBarMinWidth, preferred_size.width()), + std::clamp(padded_width, kSearchBarMinWidth, preferred_size.width()), preferred_size.height()); }
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index 4a54c8c3..d79cd980 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -23,10 +23,13 @@ #include "ash/public/cpp/ash_typography.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_id.h" +#include "ash/style/typography.h" #include "base/dcheck_is_on.h" #include "base/time/time.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator.h" #include "ui/gfx/geometry/insets.h" @@ -105,7 +108,14 @@ u"", CONTEXT_SEARCH_RESULT_CATEGORY_LABEL, STYLE_LAUNCHER)); title_label_->SetBackgroundColor(SK_ColorTRANSPARENT); title_label_->SetAutoColorReadabilityEnabled(false); - title_label_->SetEnabledColorId(kColorAshTextColorSecondary); + if (chromeos::features::IsJellyEnabled()) { + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody2, + *title_label_); + title_label_->SetEnabledColorId( + static_cast<ui::ColorId>(cros_tokens::kCrosSysOnSurfaceVariant)); + } else { + title_label_->SetEnabledColorId(kColorAshTextColorSecondary); + } title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); title_label_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR( kPreferredTitleTopMargins, kPreferredTitleHorizontalMargins,
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 6efb2afb..60219ee 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -28,10 +28,13 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_id.h" #include "ash/style/ash_color_provider.h" +#include "ash/style/typography.h" #include "base/functional/bind.h" #include "base/i18n/number_formatting.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" @@ -141,6 +144,10 @@ case SearchResult::Tag::DIM: ABSL_FALLTHROUGH_INTENDED; case SearchResult::Tag::MATCH: + if (chromeos::features::IsJellyEnabled()) { + return is_title ? cros_tokens::kCrosSysOnSurface + : cros_tokens::kCrosSysOnSurfaceVariant; + } return is_title ? kColorAshTextColorPrimary : kColorAshTextColorSecondary; case SearchResult::Tag::URL: return kColorAshTextColorURL; @@ -198,6 +205,47 @@ .WithOrder(flex_order)); // Apply label text styling. + if (chromeos::features::IsJellyEnabled()) { + switch (label_type) { + case SearchResultView::LabelType::kBigTitle: + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay2, + *label); + label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + break; + case SearchResultView::LabelType::kBigTitleSuperscript: + label->SetVerticalAlignment(gfx::ALIGN_TOP); + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay7, + *label); + label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + break; + case SearchResultView::LabelType::kTitle: + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1, + *label); + label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + break; + case SearchResultView::LabelType::kDetails: + // has_keyboard_shortcut_contents forces inline title and details text + // for answer cards so title and details text should use the same + // context. + if (view_type == SearchResultView::SearchResultViewType::kAnswerCard && + !has_keyboard_shortcut_contents) { + TypographyProvider::Get()->StyleLabel( + TypographyToken::kCrosAnnotation1, *label); + } else { + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1, + *label); + } + label->SetEnabledColorId(cros_tokens::kCrosSysOnSurfaceVariant); + break; + case SearchResultView::LabelType::kKeyboardShortcut: + TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosAnnotation1, + *label); + label->SetEnabledColorId(cros_tokens::kCrosSysPrimary); + break; + } + return label; + } + ash::AshTextContext text_context; switch (label_type) { case SearchResultView::LabelType::kBigTitle: @@ -916,8 +964,10 @@ void SearchResultView::StyleLabel(views::Label* label, const SearchResult::Tags& tags) { - // Reset font weight styling for label. - label->ApplyBaselineTextStyle(); + if (!chromeos::features::IsJellyEnabled()) { + // Reset font weight styling for label. + label->ApplyBaselineTextStyle(); + } for (const auto& tag : tags) { bool has_match_tag = (tag.styles & SearchResult::Tag::MATCH);
diff --git a/ash/clipboard/views/clipboard_history_main_button.cc b/ash/clipboard/views/clipboard_history_main_button.cc index 2a7c815..1b21432 100644 --- a/ash/clipboard/views/clipboard_history_main_button.cc +++ b/ash/clipboard/views/clipboard_history_main_button.cc
@@ -6,12 +6,13 @@ #include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/views/clipboard_history_item_view.h" -#include "ash/constants/ash_features.h" #include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_id.h" #include "ash/style/style_util.h" #include "base/functional/bind.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/color/color_provider.h" #include "ui/gfx/canvas.h" #include "ui/views/accessibility/view_accessibility.h" @@ -112,12 +113,11 @@ // is not enabled, and light mode is the default color of NativeTheme. If // dark/light mode is enabled, the background color of the context menus // inside SystemUI will be overridden to align with current system color mode. - const SkColor color = - features::IsDarkLightModeEnabled() - ? GetColorProvider()->GetColor(kColorAshInkDrop) - : SkColorSetA(SK_ColorBLACK, - StyleUtil::kLightInkDropOpacity * SK_AlphaOPAQUE); - flags.setColor(color); + const auto color_id = + chromeos::features::IsJellyEnabled() + ? static_cast<ui::ColorId>(cros_tokens::kCrosSysHoverOnSubtle) + : kColorAshInkDrop; + flags.setColor(GetColorProvider()->GetColor(color_id)); flags.setStyle(cc::PaintFlags::kFill_Style); canvas->DrawRect(GetLocalBounds(), flags); }
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index 7d06f84..985aa3a 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -4,10 +4,10 @@ #include "ash/constants/ash_switches.h" +#include <algorithm> #include <string> #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/metrics/field_trial.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" @@ -1114,8 +1114,8 @@ kAshContextualNudgesInterval), &numeric_cooldown_time)) { base::TimeDelta cooldown_time = base::Seconds(numeric_cooldown_time); - cooldown_time = base::clamp(cooldown_time, kAshContextualNudgesMinInterval, - kAshContextualNudgesMaxInterval); + cooldown_time = std::clamp(cooldown_time, kAshContextualNudgesMinInterval, + kAshContextualNudgesMaxInterval); return absl::optional<base::TimeDelta>(cooldown_time); } return absl::nullopt;
diff --git a/ash/hud_display/cpu_graph_page_view.cc b/ash/hud_display/cpu_graph_page_view.cc index e498eca..083260b 100644 --- a/ash/hud_display/cpu_graph_page_view.cc +++ b/ash/hud_display/cpu_graph_page_view.cc
@@ -4,10 +4,10 @@ #include "ash/hud_display/cpu_graph_page_view.h" +#include <algorithm> #include <numeric> #include "ash/hud_display/hud_constants.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -62,7 +62,7 @@ Legend::Formatter formatter = base::BindRepeating([](float value) { return base::ASCIIToUTF16( - base::StringPrintf("%d %%", base::clamp((int)(value * 100), 0, 100))); + base::StringPrintf("%d %%", std::clamp((int)(value * 100), 0, 100))); }); const std::vector<Legend::Entry> legend(
diff --git a/ash/hud_display/data_source.cc b/ash/hud_display/data_source.cc index 223b59a..dfdac978 100644 --- a/ash/hud_display/data_source.cc +++ b/ash/hud_display/data_source.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include "ash/hud_display/memory_status.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/threading/thread_restrictions.h" @@ -96,7 +95,7 @@ // Makes sure that the given value is between 0 and 1 and converts to // float. auto to_0_1 = [](const double& value) -> float { - return base::clamp(static_cast<float>(value), 0.0f, 1.0f); + return std::clamp(static_cast<float>(value), 0.0f, 1.0f); }; snapshot.cpu_idle_part = cpu_stats_delta.idle / cpu_ticks_total;
diff --git a/ash/public/cpp/pagination/pagination_model.cc b/ash/public/cpp/pagination/pagination_model.cc index 309dbbff..ddb6586 100644 --- a/ash/public/cpp/pagination/pagination_model.cc +++ b/ash/public/cpp/pagination/pagination_model.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include "ash/public/cpp/pagination/pagination_model_observer.h" -#include "base/cxx17_backports.h" #include "ui/gfx/animation/slide_animation.h" namespace ash { @@ -249,7 +248,7 @@ else if (target_page > end_page && selected_page_ == end_page) end_page = total_pages_; - return base::clamp(target_page, start_page, end_page); + return std::clamp(target_page, start_page, end_page); } base::TimeDelta PaginationModel::GetTransitionAnimationSlideDuration() const {
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 9430f3e..29a1d1b9 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -80,7 +80,6 @@ #include "ash/wm/workspace/workspace_layout_manager.h" #include "ash/wm/workspace_controller.h" #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/metrics/histogram_macros.h" #include "base/ranges/algorithm.h" @@ -413,8 +412,8 @@ } gfx::Point FitPointToBounds(const gfx::Point p, const gfx::Rect& bounds) { - return gfx::Point(base::clamp(p.x(), bounds.x(), bounds.right() - 1), - base::clamp(p.y(), bounds.y(), bounds.bottom() - 1)); + return gfx::Point(std::clamp(p.x(), bounds.x(), bounds.right() - 1), + std::clamp(p.y(), bounds.y(), bounds.bottom() - 1)); } ui::EventType last_mouse_event_type_ = ui::ET_UNKNOWN;
diff --git a/ash/shelf/drag_window_from_shelf_controller.cc b/ash/shelf/drag_window_from_shelf_controller.cc index 18f66604..e869aea5 100644 --- a/ash/shelf/drag_window_from_shelf_controller.cc +++ b/ash/shelf/drag_window_from_shelf_controller.cc
@@ -4,6 +4,8 @@ #include "ash/shelf/drag_window_from_shelf_controller.h" +#include <algorithm> + #include "ash/app_list/app_list_controller_impl.h" #include "ash/constants/ash_features.h" #include "ash/display/screen_orientation_controller.h" @@ -34,7 +36,6 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_transient_descendant_iterator.h" #include "ash/wm/window_util.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_macros.h" @@ -598,8 +599,8 @@ float y_diff = location_in_screen.y() - min_y; float scale = (1.0f - kMinimumWindowScaleDuringDragging) * y_diff / y_full + kMinimumWindowScaleDuringDragging; - scale = base::clamp(scale, /*min=*/kMinimumWindowScaleDuringDragging, - /*max=*/1.f); + scale = std::clamp(scale, /*min=*/kMinimumWindowScaleDuringDragging, + /*max=*/1.f); // Calculate the desired translation so that the dragged window stays under // the finger during the dragging. @@ -638,14 +639,14 @@ float copy_scale = (bounds.bottom() - location_in_screen.y()) / (display_bounds.height() / kOtherWindowFullFadeHeightRatio); - copy_scale = 1.f - base::clamp(copy_scale, 0.f, 1.f); + copy_scale = 1.f - std::clamp(copy_scale, 0.f, 1.f); other_window_copy_->root()->SetOpacity(copy_scale); CHECK(other_window_); if (!WindowState::Get(other_window_)->IsFloated()) { const float copy_transform_scale = - base::clamp(copy_scale, kOtherWindowMaxScale, 1.f); + std::clamp(copy_scale, kOtherWindowMaxScale, 1.f); const gfx::Transform copy_transform = gfx::GetScaleTransform( other_window_copy_->root()->bounds().CenterPoint(), copy_transform_scale);
diff --git a/ash/shelf/home_button.cc b/ash/shelf/home_button.cc index 2550f823..c140605 100644 --- a/ash/shelf/home_button.cc +++ b/ash/shelf/home_button.cc
@@ -11,11 +11,13 @@ #include "ash/app_list/app_list_model_provider.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/quick_app_access_model.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/ash_typography.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_types.h" #include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_control_button.h" #include "ash/shelf/shelf_focus_cycler.h" #include "ash/shelf/shelf_navigation_widget.h" #include "ash/shelf/shelf_view.h" @@ -130,6 +132,8 @@ if (features::IsHomeButtonQuickAppAccessEnabled()) { shell_observation_.Observe(Shell::Get()); app_list_model_observation_.Observe(AppListModelProvider::Get()); + quick_app_model_observation_.Observe( + AppListModelProvider::Get()->quick_app_access_model()); } } @@ -207,16 +211,11 @@ GetDisplayId(), AppListShowSource::kShelfButton, event.time_stamp()); // If the home button is pressed, fade out the nudge label if it is showing. - if (expandable_container_) { + if (expandable_container_ && !quick_app_button_) { // The label shouldn't be removed if the text-in-shelf feature is enabled. if (features::IsHomeButtonWithTextEnabled()) return; - if (quick_app_button_) { - // TODO(b/266734005): Implement fade out animation for quick app button. - return; - } - if (!expandable_container_->GetVisible()) { // If the nudge label is not visible and will not be animating, directly // remove them as the nudge won't be showing anymore. @@ -494,29 +493,24 @@ const int control_size = ShelfControlButton::CalculatePreferredSize().width(); - SkBitmap square_icon_bitmap; - square_icon_bitmap.allocN32Pixels(control_size, control_size); + const gfx::Size preferred_size = gfx::Size(control_size, control_size); - SkCanvas canvas(square_icon_bitmap); - SkPaint paint_outline; - paint_outline.setColor(SK_ColorRED); - canvas.drawCircle(control_size / 2, control_size / 2, control_size / 2, - paint_outline); - - gfx::ImageSkia test_icon_image = - gfx::ImageSkia::CreateFrom1xBitmap(square_icon_bitmap); - - // TODO(b/266734005): Animate in quick app once icon is loaded. quick_app_button_->SetPaintToLayer(); - quick_app_button_->SetImage(views::Button::STATE_NORMAL, test_icon_image); - quick_app_button_->SetSize(gfx::Size(control_size, control_size)); + quick_app_button_->layer()->SetFillsBoundsOpaquely(false); + quick_app_button_->SetImage( + views::Button::STATE_NORMAL, + AppListModelProvider::Get()->quick_app_access_model()->GetAppIcon( + preferred_size)); + quick_app_button_->SetSize(preferred_size); + + shelf_->shelf_layout_manager()->LayoutShelf(false); } void HomeButton::QuickAppButtonPressed() { - // TODO(b/266734005): Reset and hide the quick app once pressed. ash::Shell::Get()->app_list_controller()->ActivateItem( - quick_app_id_, /*event_flags=*/0, - ash::AppListLaunchedFrom::kLaunchedFromQuickAppAccess); + AppListModelProvider::Get()->quick_app_access_model()->quick_app_id(), + /*event_flags=*/0, ash::AppListLaunchedFrom::kLaunchedFromQuickAppAccess); + AppListModelProvider::Get()->quick_app_access_model()->SetQuickAppActivated(); } void HomeButton::AnimateNudgeRipple(views::AnimationBuilder& builder) { @@ -760,6 +754,12 @@ nudge_label_ = nullptr; } +void HomeButton::RemoveQuickAppButton() { + RemoveChildViewT(expandable_container_); + expandable_container_ = nullptr; + quick_app_button_ = nullptr; +} + bool HomeButton::DoesIntersectRect(const views::View* target, const gfx::Rect& rect) const { DCHECK_EQ(target, this); @@ -794,25 +794,36 @@ void HomeButton::OnActiveAppListModelsChanged(AppListModel* model, SearchModel* search_model) { + QuickAppAccessModel* quick_model = + AppListModelProvider::Get()->quick_app_access_model(); quick_app_model_observation_.Reset(); - quick_app_model_observation_.Observe( - AppListModelProvider::Get()->quick_app_access_model()); + quick_app_model_observation_.Observe(quick_model); - OnQuickAppChanged(); + OnQuickAppShouldShowChanged(quick_model->quick_app_should_show_state()); } -void HomeButton::OnQuickAppChanged() { - quick_app_id_ = - AppListModelProvider::Get()->quick_app_access_model()->quick_app_id(); - if (quick_app_id_.empty()) { - // TODO(b/266734005): Hide the quick app button if already shown. +void HomeButton::OnQuickAppShouldShowChanged(bool show_quick_app) { + if (!show_quick_app && quick_app_button_) { + // TODO(b/266734005): Animate the hiding of the quick app button. + RemoveQuickAppButton(); + } else if (show_quick_app && !quick_app_button_) { + if (nudge_label_) { + RemoveNudgeLabel(); + } + CreateQuickAppButton(); + } +} + +void HomeButton::OnQuickAppIconChanged() { + if (!quick_app_button_) { return; } - // Only create the quick app button if no nudge label exists already. - if (!quick_app_button_ && !nudge_label_) { - CreateQuickAppButton(); - } + const int control_size = ShelfControlButton::CalculatePreferredSize().width(); + quick_app_button_->SetImage( + views::Button::STATE_NORMAL, + AppListModelProvider::Get()->quick_app_access_model()->GetAppIcon( + gfx::Size(control_size, control_size))); } } // namespace ash
diff --git a/ash/shelf/home_button.h b/ash/shelf/home_button.h index 1ce809f1..2427885 100644 --- a/ash/shelf/home_button.h +++ b/ash/shelf/home_button.h
@@ -181,6 +181,9 @@ // Removes the nudge label from the view hierarchy. void RemoveNudgeLabel(); + // Removes the quick app button from the view hierarchy. + void RemoveQuickAppButton(); + // views::ViewTargeterDelegate: bool DoesIntersectRect(const views::View* target, const gfx::Rect& rect) const override; @@ -193,7 +196,8 @@ SearchModel* search_model) override; // QuickAppAccessModel::Observer: - void OnQuickAppChanged() override; + void OnQuickAppShouldShowChanged(bool quick_app_shown) override; + void OnQuickAppIconChanged() override; base::ScopedObservation<QuickAppAccessModel, QuickAppAccessModel::Observer> quick_app_model_observation_{this}; @@ -233,9 +237,6 @@ // set by SetQuickApp(). views::ImageButton* quick_app_button_ = nullptr; - // The app_id of the quick app button. - std::string quick_app_id_; - base::ObserverList<NudgeAnimationObserver> observers_; base::WeakPtrFactory<HomeButton> weak_ptr_factory_{this};
diff --git a/ash/shelf/home_button_unittest.cc b/ash/shelf/home_button_unittest.cc index 64bb5ea..e028813 100644 --- a/ash/shelf/home_button_unittest.cc +++ b/ash/shelf/home_button_unittest.cc
@@ -29,6 +29,7 @@ #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_util.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/command_line.h" #include "base/run_loop.h" @@ -37,6 +38,8 @@ #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/test/event_generator.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_unittest_util.h" #include "ui/views/animation/bounds_animator.h" #include "ui/views/controls/button/image_button.h" #include "ui/wm/core/coordinate_conversion.h" @@ -185,11 +188,15 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// Test that setting an existing app item as the quick app shows a working +// clickable quick app button. TEST_F(HomeButtonWithQuickAppAccess, Basic) { EXPECT_FALSE(IsQuickAppVisible()); const std::string quick_app_id = "Quick App Item"; - Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id); + GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id); + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); EXPECT_TRUE(IsQuickAppVisible()); @@ -204,6 +211,173 @@ GetEventGenerator()->ClickLeftButton(); EXPECT_EQ(1, GetTestAppListClient()->activate_item_count()); EXPECT_EQ(quick_app_id, GetTestAppListClient()->activate_item_last_id()); + + // Quick app button should be hidden after clicking it. + EXPECT_FALSE(IsQuickAppVisible()); +} + +// Test that setting a quick app which is not in the app list model does not +// show the quick app button. +TEST_F(HomeButtonWithQuickAppAccess, NonExistentApp) { + EXPECT_FALSE(IsQuickAppVisible()); + EXPECT_FALSE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp( + "Quick App Item")); + EXPECT_FALSE(IsQuickAppVisible()); +} + +// Test that when setting a quick app with no icon, the quick app button doesn't +// show until an icon is loaded. +TEST_F(HomeButtonWithQuickAppAccess, AppWithNoIconThenLoaded) { + EXPECT_FALSE(IsQuickAppVisible()); + + const std::string quick_app_id = "Quick App Item"; + AppListItem* item = new AppListItem(quick_app_id); + GetAppListTestHelper()->model()->AddItem(item); + + EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp( + "Quick App Item")); + + // Check that the quick app item with no icon is not visible, and that icon + // load was requested. + EXPECT_FALSE(IsQuickAppVisible()); + EXPECT_EQ(std::vector<std::string>{quick_app_id}, + GetTestAppListClient()->load_icon_app_ids()); + + // Set the default icon and check that the quick app button is visible after. + item->SetDefaultIconAndColor( + CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorRED), IconColor()); + EXPECT_TRUE(IsQuickAppVisible()); +} + +// Test that the quick app button image changes when setting a new quick app +// with a quick app button already shown. +TEST_F(HomeButtonWithQuickAppAccess, IconUpdatesOnNewQuickAppSet) { + EXPECT_FALSE(IsQuickAppVisible()); + + const std::string quick_app_id = "Quick App Item"; + AppListItem* item = new AppListItem(quick_app_id); + GetAppListTestHelper()->model()->AddItem(item); + item->SetDefaultIconAndColor( + CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorRED), IconColor()); + + const std::string quick_app_id_two = "Quick App Item Two"; + AppListItem* item_two = new AppListItem(quick_app_id_two); + GetAppListTestHelper()->model()->AddItem(item_two); + item_two->SetDefaultIconAndColor( + CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorBLUE), IconColor()); + + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); + EXPECT_TRUE(IsQuickAppVisible()); + + gfx::ImageSkia image_one = + home_button()->quick_app_button_for_test()->GetImage( + views::Button::STATE_NORMAL); + + EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp( + quick_app_id_two)); + EXPECT_TRUE(IsQuickAppVisible()); + + gfx::ImageSkia image_two = + home_button()->quick_app_button_for_test()->GetImage( + views::Button::STATE_NORMAL); + + // Check that the quick app button image is changed after setting a new quick + // app. + EXPECT_FALSE( + gfx::test::AreImagesEqual(gfx::Image(image_one), gfx::Image(image_two))); +} + +// Test that the quick app button is hidden when the home button is pressed. +TEST_F(HomeButtonWithQuickAppAccess, HomeButtonPressed) { + EXPECT_FALSE(IsQuickAppVisible()); + + const std::string quick_app_id = "Quick App Item"; + GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id); + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); + + EXPECT_TRUE(IsQuickAppVisible()); + + gfx::Point center = home_button()->GetBoundsInScreen().CenterPoint(); + GetEventGenerator()->MoveMouseTo(center); + GetEventGenerator()->ClickLeftButton(); + + EXPECT_FALSE(IsQuickAppVisible()); +} + +// Test that the quick app button is hidden when the app list is opened. +TEST_F(HomeButtonWithQuickAppAccess, AppListOpened) { + EXPECT_FALSE(IsQuickAppVisible()); + + const std::string quick_app_id = "Quick App Item"; + GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id); + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); + + EXPECT_TRUE(IsQuickAppVisible()); + + GetAppListTestHelper()->ShowAppList(); + + EXPECT_FALSE(IsQuickAppVisible()); +} + +// Test that the quick app button on both displays get shown and hidden +// together. +TEST_F(HomeButtonWithQuickAppAccess, TwoDisplays) { + UpdateDisplay("10+10-500x400,600+10-1000x600/r"); + + HomeButton* second_home_button = + Shelf::ForWindow(Shell::GetAllRootWindows()[1]) + ->shelf_widget() + ->navigation_widget() + ->GetHomeButton(); + + EXPECT_NE(home_button(), second_home_button); + EXPECT_FALSE(second_home_button->quick_app_button_for_test()); + EXPECT_FALSE(home_button()->quick_app_button_for_test()); + + // Set the quick app and ensure the quick app button is shown on both + // displays. + const std::string quick_app_id = "Quick App Item"; + GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id); + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); + + EXPECT_TRUE(second_home_button->quick_app_button_for_test()); + EXPECT_TRUE(home_button()->quick_app_button_for_test()); + + // Click the home button on the first display. + gfx::Point center = home_button()->GetBoundsInScreen().CenterPoint(); + GetEventGenerator()->MoveMouseTo(center); + GetEventGenerator()->ClickLeftButton(); + + // Both quick app buttons should be hidden. + EXPECT_FALSE(second_home_button->quick_app_button_for_test()); + EXPECT_FALSE(home_button()->quick_app_button_for_test()); +} + +// Test that setting an empty string as the quick app id hides the existing +// quick app button. +TEST_F(HomeButtonWithQuickAppAccess, EmptyAppId) { + EXPECT_FALSE(IsQuickAppVisible()); + + const std::string quick_app_id = "Quick App Item"; + GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id); + + // Setting the quick app to emtpy app id initially does not show the quick app + // button. + EXPECT_FALSE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp("")); + EXPECT_FALSE(IsQuickAppVisible()); + + // Set quick app id shows the quick app button. + EXPECT_TRUE( + Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id)); + EXPECT_TRUE(IsQuickAppVisible()); + + // Setting to an empty app id hides the quick app button. + EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp("")); + EXPECT_FALSE(IsQuickAppVisible()); } enum class TestAccessibilityFeature {
diff --git a/ash/shelf/scrollable_shelf_view.cc b/ash/shelf/scrollable_shelf_view.cc index f80dcc7..2a65c55 100644 --- a/ash/shelf/scrollable_shelf_view.cc +++ b/ash/shelf/scrollable_shelf_view.cc
@@ -19,7 +19,6 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/system/status_area_widget.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/i18n/rtl.h" #include "base/metrics/histogram_functions.h" @@ -621,7 +620,7 @@ int available_space_for_icons) const { const float scroll_upper_bound = CalculateScrollUpperBound(available_space_for_icons); - scroll = base::clamp(scroll, 0.0f, scroll_upper_bound); + scroll = std::clamp(scroll, 0.0f, scroll_upper_bound); return scroll; } @@ -1829,11 +1828,11 @@ // TODO(b/268401797): Rewrite CalculateTappableIconIndices() as a more // thorough fix for out of bound indices. first_visible_view_index = - base::clamp(first_visible_view_index, static_cast<size_t>(0), - visible_views_indices.size() - 1); + std::clamp(first_visible_view_index, static_cast<size_t>(0), + visible_views_indices.size() - 1); last_visible_view_index = - base::clamp(last_visible_view_index, first_visible_view_index, - visible_views_indices.size() - 1); + std::clamp(last_visible_view_index, first_visible_view_index, + visible_views_indices.size() - 1); return {visible_views_indices[first_visible_view_index], visible_views_indices[last_visible_view_index]};
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 5823e4d..d895991 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -4,6 +4,7 @@ #include "ash/shelf/shelf_view.h" +#include <algorithm> #include <memory> #include <utility> @@ -52,7 +53,6 @@ #include "base/check_op.h" #include "base/containers/adapters.h" #include "base/containers/contains.h" -#include "base/cxx17_backports.h" #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" @@ -1701,7 +1701,7 @@ size_t target_index = views::ViewModelUtils::DetermineMoveIndex( *view_model_, drag_view_, shelf_->IsHorizontalAlignment(), drag_view_->x(), drag_view_->y()); - target_index = base::clamp(target_index, indices.first, indices.second); + target_index = std::clamp(target_index, indices.first, indices.second); // Check the relative position of |drag_view_| and its ideal bounds if it can // be dragged across the separator to pin.
diff --git a/ash/shelf/swipe_home_to_overview_controller.cc b/ash/shelf/swipe_home_to_overview_controller.cc index d756c1df..60514455 100644 --- a/ash/shelf/swipe_home_to_overview_controller.cc +++ b/ash/shelf/swipe_home_to_overview_controller.cc
@@ -4,6 +4,8 @@ #include "ash/shelf/swipe_home_to_overview_controller.h" +#include <algorithm> + #include "ash/app_list/app_list_controller_impl.h" #include "ash/constants/ash_features.h" #include "ash/controls/contextual_tooltip.h" @@ -15,7 +17,6 @@ #include "ash/shell.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_session.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_macros.h" @@ -128,7 +129,7 @@ const float progress = gfx::Tween::CalculateValue( gfx::Tween::FAST_OUT_SLOW_IN, - base::clamp(1.f - distance / target_distance, 0.0f, 1.0f)); + std::clamp(1.f - distance / target_distance, 0.0f, 1.0f)); float scale = gfx::Tween::FloatValueBetween(progress, 1.0f, kTargetHomeScale); Shell::Get()->app_list_controller()->UpdateScaleAndOpacityForHomeLauncher(
diff --git a/ash/style/color_util.cc b/ash/style/color_util.cc index e79e2d6..9bbd3a3 100644 --- a/ash/style/color_util.cc +++ b/ash/style/color_util.cc
@@ -4,11 +4,12 @@ #include "ash/style/color_util.h" +#include <algorithm> + #include "ash/public/cpp/wallpaper/wallpaper_types.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/wallpaper/wallpaper_controller_impl.h" -#include "base/cxx17_backports.h" #include "chromeos/constants/chromeos_features.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/color_utils.h" @@ -66,9 +67,9 @@ color_utils::SkColorToHSL(color, &hsl); if (use_dark_color) { - hsl.l = base::clamp(hsl.l, kMinLightnessDarkMode, 1.0); + hsl.l = std::clamp(hsl.l, kMinLightnessDarkMode, 1.0); } else { - hsl.l = base::clamp(hsl.l, 0.0, kMaxLightnessLightMode); + hsl.l = std::clamp(hsl.l, 0.0, kMaxLightnessLightMode); } return color_utils::HSLToSkColor(hsl, SkColorGetA(color)); }
diff --git a/ash/system/camera/autozoom_toast_controller.cc b/ash/system/camera/autozoom_toast_controller.cc index 070e734..cb621c3 100644 --- a/ash/system/camera/autozoom_toast_controller.cc +++ b/ash/system/camera/autozoom_toast_controller.cc
@@ -4,6 +4,8 @@ #include "ash/system/camera/autozoom_toast_controller.h" +#include <algorithm> + #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" @@ -11,7 +13,6 @@ #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_utils.h" #include "ash/system/unified/unified_system_tray.h" -#include "base/cxx17_backports.h" namespace ash { @@ -149,8 +150,8 @@ void AutozoomToastController::UpdateToastView() { if (toast_view_) { toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->IsAutozoomEnabled()); - int width = base::clamp(toast_view_->GetPreferredSize().width(), - kAutozoomToastMinWidth, kAutozoomToastMaxWidth); + int width = std::clamp(toast_view_->GetPreferredSize().width(), + kAutozoomToastMinWidth, kAutozoomToastMaxWidth); bubble_view_->SetPreferredWidth(width); } }
diff --git a/ash/system/message_center/message_center_scroll_bar.cc b/ash/system/message_center/message_center_scroll_bar.cc index d7b616e..f410b90 100644 --- a/ash/system/message_center/message_center_scroll_bar.cc +++ b/ash/system/message_center/message_center_scroll_bar.cc
@@ -10,6 +10,7 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" #include "ui/compositor/presentation_time_recorder.h" +#include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h" #include "ui/views/widget/widget.h" namespace { @@ -44,90 +45,7 @@ BEGIN_METADATA(RoundedMessageCenterScrollBar, RoundedScrollBar) END_METADATA -MessageCenterScrollBar::MessageCenterScrollBar( - MessageCenterScrollBar::Observer* observer) - : views::OverlayScrollBar(false), observer_(observer) { - GetThumb()->layer()->SetVisible(features::IsNotificationScrollBarEnabled()); - GetThumb()->layer()->CompleteAllAnimations(); -} - -MessageCenterScrollBar::~MessageCenterScrollBar() = default; - -bool MessageCenterScrollBar::OnKeyPressed(const ui::KeyEvent& event) { - if (!stats_recorded_ && - (event.key_code() == ui::VKEY_UP || event.key_code() == ui::VKEY_DOWN)) { - CollectScrollActionReason(ScrollActionReason::kByArrowKey); - stats_recorded_ = true; - } - return views::OverlayScrollBar::OnKeyPressed(event); -} - -bool MessageCenterScrollBar::OnMouseWheel(const ui::MouseWheelEvent& event) { - if (!stats_recorded_) { - CollectScrollActionReason(ScrollActionReason::kByMouseWheel); - stats_recorded_ = true; - } - - bool result = views::OverlayScrollBar::OnMouseWheel(event); - - if (observer_) - observer_->OnMessageCenterScrolled(); - - return result; -} - -const char* MessageCenterScrollBar::GetClassName() const { - return "MessageCenterScrollBar"; -} - -void MessageCenterScrollBar::OnGestureEvent(ui::GestureEvent* event) { - if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { - if (!presentation_time_recorder_ && GetWidget()) { - presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder( - GetWidget()->GetCompositor(), kMessageCenterScrollHistogram, - kMessageCenterScrollMaxLatencyHistogram); - } - if (!stats_recorded_) { - CollectScrollActionReason(ScrollActionReason::kByTouch); - stats_recorded_ = true; - } - } - - if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE) { - if (presentation_time_recorder_) - presentation_time_recorder_->RequestNext(); - } - - if (event->type() == ui::ET_GESTURE_END) - presentation_time_recorder_.reset(); - - views::OverlayScrollBar::OnGestureEvent(event); - - if (observer_) - observer_->OnMessageCenterScrolled(); -} - -bool MessageCenterScrollBar::OnScroll(float dx, float dy) { - bool result = views::OverlayScrollBar::OnScroll(dx, dy); - if (observer_) - observer_->OnMessageCenterScrolled(); - - // Widget might be null in tests. - if (GetWidget() && !presentation_time_recorder_) { - // Create a recorder if needed. We stop and record metrics when the - // object goes out of scope (when message center is closed). - presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder( - GetWidget()->GetCompositor(), kMessageCenterScrollHistogram, - kMessageCenterScrollMaxLatencyHistogram); - } - if (presentation_time_recorder_) - presentation_time_recorder_->RequestNext(); - - return result; -} - -RoundedMessageCenterScrollBar::RoundedMessageCenterScrollBar( - MessageCenterScrollBar::Observer* observer) +RoundedMessageCenterScrollBar::RoundedMessageCenterScrollBar(Observer* observer) : RoundedScrollBar(false), observer_(observer) { GetThumb()->layer()->SetVisible(features::IsNotificationScrollBarEnabled()); GetThumb()->layer()->CompleteAllAnimations();
diff --git a/ash/system/message_center/message_center_scroll_bar.h b/ash/system/message_center/message_center_scroll_bar.h index 9ae7432..920b08de 100644 --- a/ash/system/message_center/message_center_scroll_bar.h +++ b/ash/system/message_center/message_center_scroll_bar.h
@@ -5,10 +5,10 @@ #ifndef ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_SCROLL_BAR_H_ #define ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_SCROLL_BAR_H_ +#include <memory> + #include "ash/controls/rounded_scroll_bar.h" -#include "ui/compositor/presentation_time_recorder.h" #include "ui/events/event.h" -#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" namespace ui { class PresentationTimeRecorder; @@ -16,11 +16,14 @@ namespace ash { -// The scroll bar for message center. This is basically views::OverlayScrollBar +// The scroll bar for message center. This is basically just a RoundedScrollBar // but also records the metrics for the type of scrolling (only the first event // after the message center opens is recorded) and scrolling performance. -class MessageCenterScrollBar : public views::OverlayScrollBar { +// TODO(b/257291597): Rename this file to match the class name. +class RoundedMessageCenterScrollBar : public RoundedScrollBar { public: + METADATA_HEADER(RoundedMessageCenterScrollBar); + class Observer { public: // Called when scroll event is triggered. @@ -29,43 +32,7 @@ }; // |observer| can be null. - explicit MessageCenterScrollBar(Observer* observer); - - MessageCenterScrollBar(const MessageCenterScrollBar&) = delete; - MessageCenterScrollBar& operator=(const MessageCenterScrollBar&) = delete; - - ~MessageCenterScrollBar() override; - - private: - // View overrides: - bool OnKeyPressed(const ui::KeyEvent& event) override; - bool OnMouseWheel(const ui::MouseWheelEvent& event) override; - const char* GetClassName() const override; - - // ui::EventHandler overrides: - void OnGestureEvent(ui::GestureEvent* event) override; - - // views::ScrollDelegate overrides: - bool OnScroll(float dx, float dy) override; - - // False if no event is recorded yet. True if the first event is recorded. - bool stats_recorded_ = false; - - Observer* const observer_; - - // Presentation time recorder for scrolling through notification list. - std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_; -}; - -// The new scroll bar for message center. This class will replace -// MessageCenterScrollBar in NotificationsRefresh feature. -class RoundedMessageCenterScrollBar : public RoundedScrollBar { - public: - METADATA_HEADER(RoundedMessageCenterScrollBar); - - // |observer| can be null. - explicit RoundedMessageCenterScrollBar( - MessageCenterScrollBar::Observer* observer); + explicit RoundedMessageCenterScrollBar(Observer* observer); RoundedMessageCenterScrollBar(const RoundedMessageCenterScrollBar&) = delete; RoundedMessageCenterScrollBar& operator=( @@ -88,7 +55,7 @@ bool stats_recorded_ = false; // Unowned. - MessageCenterScrollBar::Observer* const observer_; + Observer* const observer_; // Presentation time recorder for scrolling through notification list. std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc index 742bcc4..f0d3a821 100644 --- a/ash/system/network/network_icon.cc +++ b/ash/system/network/network_icon.cc
@@ -4,6 +4,7 @@ #include "ash/system/network/network_icon.h" +#include <algorithm> #include <tuple> #include <utility> @@ -18,7 +19,6 @@ #include "ash/system/network/network_icon_animation_observer.h" #include "ash/system/tray/tray_constants.h" #include "base/containers/flat_map.h" -#include "base/cxx17_backports.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h" @@ -200,7 +200,7 @@ int index = animation * nextafter(static_cast<float>(kNumConnectingImages), 0); - index = base::clamp(index, 0, kNumConnectingImages - 1); + index = std::clamp(index, 0, kNumConnectingImages - 1); auto map_key = std::make_tuple( is_bars_image, DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(),
diff --git a/ash/system/night_light/night_light_controller_impl.cc b/ash/system/night_light/night_light_controller_impl.cc index 8f4b9a6..c6960943 100644 --- a/ash/system/night_light/night_light_controller_impl.cc +++ b/ash/system/night_light/night_light_controller_impl.cc
@@ -4,6 +4,7 @@ #include "ash/system/night_light/night_light_controller_impl.h" +#include <algorithm> #include <cmath> #include <memory> @@ -19,7 +20,6 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/model/system_tray_model.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/i18n/time_formatting.h" #include "base/logging.h" @@ -168,7 +168,7 @@ // 3 => Range [60 : 80). // 4 => Range [80 : 100] (most warm). int GetTemperatureRange(float temperature) { - return base::clamp(std::floor(5 * temperature), 0.0f, 4.0f); + return std::clamp(std::floor(5 * temperature), 0.0f, 4.0f); } // Returns the color matrix that corresponds to the given |temperature|. @@ -356,7 +356,7 @@ } start_temperature_ = current_temperature_; - target_temperature_ = base::clamp(new_target_temperature, 0.0f, 1.0f); + target_temperature_ = std::clamp(new_target_temperature, 0.0f, 1.0f); if (ui::ScopedAnimationDurationScaleMode::duration_multiplier() == ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) { @@ -375,7 +375,7 @@ private: // gfx::Animation: void AnimateToState(double state) override { - state = base::clamp(state, 0.0, 1.0); + state = std::clamp(state, 0.0, 1.0); current_temperature_ = start_temperature_ + (target_temperature_ - start_temperature_) * state; } @@ -483,8 +483,8 @@ // kTable[i+1].input_temperature exclude the upper bound, we clamp it to the // last input_temperature element of the table minus 1. const float temperature = - base::clamp<float>(temperature_in_kelvin, kTable[0].input_temperature, - kTable[kTableSize - 1].input_temperature - 1); + std::clamp<float>(temperature_in_kelvin, kTable[0].input_temperature, + kTable[kTableSize - 1].input_temperature - 1); for (size_t i = 0; i < kTableSize - 1; i++) { if (temperature >= kTable[i].input_temperature && temperature < kTable[i + 1].input_temperature) {
diff --git a/ash/system/notification_center/notification_center_view.cc b/ash/system/notification_center/notification_center_view.cc index 10a7a73..363dec6 100644 --- a/ash/system/notification_center/notification_center_view.cc +++ b/ash/system/notification_center/notification_center_view.cc
@@ -89,23 +89,15 @@ scroller_(new views::ScrollView()), notification_list_view_(new NotificationListView(this, model)), last_scroll_position_from_bottom_(0), - is_notifications_refresh_enabled_( - features::IsNotificationsRefreshEnabled()), animation_(std::make_unique<gfx::LinearAnimation>(this)), focus_search_(std::make_unique<views::FocusSearch>(this, false, false)) { - if (is_notifications_refresh_enabled_) { - auto* scroll_bar = new RoundedMessageCenterScrollBar(this); - scroll_bar->SetInsets(kScrollBarInsets); - scroll_bar_ = scroll_bar; - } else { - scroll_bar_ = new MessageCenterScrollBar(this); - } + auto* scroll_bar = new RoundedMessageCenterScrollBar(this); + scroll_bar->SetInsets(kScrollBarInsets); + scroll_bar_ = scroll_bar; - if (is_notifications_refresh_enabled_) { - layout_manager_ = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, - gfx::Insets(kMessageCenterPadding))); - } + layout_manager_ = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + gfx::Insets(kMessageCenterPadding))); } NotificationCenterView::~NotificationCenterView() { @@ -124,10 +116,6 @@ void NotificationCenterView::Init() { notification_list_view_->Init(); - if (!is_notifications_refresh_enabled_) { - AddChildView(notification_bar_); - } - // Need to set the transparent background explicitly, since ScrollView has // set the default opaque background color. // TODO(crbug.com/1247455): Be able to do @@ -137,11 +125,9 @@ scroller_->SetBackgroundColor(absl::nullopt); scroller_->SetVerticalScrollBar(base::WrapUnique(scroll_bar_)); scroller_->SetDrawOverflowIndicator(false); - if (is_notifications_refresh_enabled_) { - scroller_->SetPaintToLayer(); - scroller_->layer()->SetRoundedCornerRadius( - gfx::RoundedCornersF{kMessageCenterScrollViewCornerRadius}); - } + scroller_->SetPaintToLayer(); + scroller_->layer()->SetRoundedCornerRadius( + gfx::RoundedCornersF{kMessageCenterScrollViewCornerRadius}); AddChildView(scroller_); @@ -160,9 +146,7 @@ base::Unretained(this))); } - if (is_notifications_refresh_enabled_) { - AddChildView(notification_bar_); - } + AddChildView(notification_bar_); } bool NotificationCenterView::UpdateNotificationBar() { @@ -181,11 +165,8 @@ int max_scroller_height = max_height; if (notification_bar_->GetVisible()) { - max_scroller_height -= - is_notifications_refresh_enabled_ - ? notification_bar_->GetPreferredSize().height() + - 2 * kMessageCenterPadding - : kStackedNotificationBarHeight; + max_scroller_height -= notification_bar_->GetPreferredSize().height() + + 2 * kMessageCenterPadding; } scroller_->ClipHeightTo(0, max_scroller_height); } @@ -303,73 +284,6 @@ focus_manager_ = nullptr; } -void NotificationCenterView::Layout() { - if (is_notifications_refresh_enabled_) { - return views::View::Layout(); - } - - if (notification_bar_->GetVisible()) { - gfx::Rect counter_bounds(GetContentsBounds()); - - int notification_bar_expanded_height = kStackedNotificationBarHeight; - - int notification_bar_height = collapsed_ - ? kStackedNotificationBarCollapsedHeight - : notification_bar_expanded_height; - int notification_bar_offset = 0; - if (animation_state_ == - NotificationCenterAnimationState::HIDE_STACKING_BAR) { - notification_bar_offset = GetAnimationValue() * notification_bar_height; - } - - counter_bounds.set_height(notification_bar_height); - counter_bounds.set_y(counter_bounds.y() - notification_bar_offset); - notification_bar_->SetBoundsRect(counter_bounds); - - gfx::Rect scroller_bounds(GetContentsBounds()); - - scroller_bounds.Inset(gfx::Insets::TLBR( - notification_bar_height - notification_bar_offset, 0, 0, 0)); - scroller_->SetBoundsRect(scroller_bounds); - } else { - scroller_->SetBoundsRect(GetContentsBounds()); - } - - ScrollToTarget(); -} - -gfx::Size NotificationCenterView::CalculatePreferredSize() const { - if (is_notifications_refresh_enabled_) { - return views::View::CalculatePreferredSize(); - } - - gfx::Size preferred_size = scroller_->GetPreferredSize(); - - if (notification_bar_->GetVisible()) { - int bar_height = kStackedNotificationBarHeight; - - if (animation_state_ == - NotificationCenterAnimationState::HIDE_STACKING_BAR) { - bar_height -= GetAnimationValue() * bar_height; - } - preferred_size.set_height(preferred_size.height() + bar_height); - } - - if (animation_state_ == NotificationCenterAnimationState::COLLAPSE) { - int height = preferred_size.height() * (1.0 - GetAnimationValue()); - - if (collapsed_) { - height = std::max(kStackedNotificationBarCollapsedHeight, height); - } - - preferred_size.set_height(height); - } else if (collapsed_) { - preferred_size.set_height(kStackedNotificationBarCollapsedHeight); - } - - return preferred_size; -} - void NotificationCenterView::OnViewBoundsChanged(views::View* observed_view) { UpdateNotificationBar(); } @@ -599,16 +513,8 @@ return notification_list_view_->GetAllNotifications(); } - if (is_notifications_refresh_enabled_) { - const int y_offset = scroller_->GetVisibleRect().bottom() - scroller_->y(); - return notification_list_view_->GetNotificationsBelowY(y_offset); - } - - const int notification_bar_height = - IsNotificationBarVisible() ? kStackedNotificationBarHeight : 0; - const int y_offset = scroller_->GetVisibleRect().y() - scroller_->y() + - notification_bar_height; - return notification_list_view_->GetNotificationsAboveY(y_offset); + const int y_offset = scroller_->GetVisibleRect().bottom() - scroller_->y(); + return notification_list_view_->GetNotificationsBelowY(y_offset); } std::vector<std::string>
diff --git a/ash/system/notification_center/notification_center_view.h b/ash/system/notification_center/notification_center_view.h index efb5116..c9a0235 100644 --- a/ash/system/notification_center/notification_center_view.h +++ b/ash/system/notification_center/notification_center_view.h
@@ -61,7 +61,7 @@ // Manages scrolling of notification list. class ASH_EXPORT NotificationCenterView : public views::View, - public MessageCenterScrollBar::Observer, + public RoundedMessageCenterScrollBar::Observer, public views::FocusChangeListener, public gfx::AnimationDelegate, public views::ViewObserver { @@ -148,8 +148,6 @@ // views::View: void AddedToWidget() override; void RemovedFromWidget() override; - void Layout() override; - gfx::Size CalculatePreferredSize() const override; // views::ViewObserver: void OnViewBoundsChanged(views::View* observed_view) override; @@ -215,8 +213,6 @@ // Position from the bottom of scroll contents in dip. int last_scroll_position_from_bottom_; - const bool is_notifications_refresh_enabled_; - // The height available to the message center view. This is the remaining // height of the system tray excluding the system menu (which can be expanded // or collapsed).
diff --git a/ash/system/phonehub/app_stream_launcher_view_unittest.cc b/ash/system/phonehub/app_stream_launcher_view_unittest.cc index 238b3a6a..2d1eb296 100644 --- a/ash/system/phonehub/app_stream_launcher_view_unittest.cc +++ b/ash/system/phonehub/app_stream_launcher_view_unittest.cc
@@ -81,7 +81,7 @@ index)); } - const gfx::Image /*cololr_icon=*/CreateTestImage() { + const gfx::Image CreateTestImage() { SkBitmap bitmap; bitmap.allocN32Pixels(60, 60); gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); @@ -133,7 +133,8 @@ .size()); auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -163,7 +164,8 @@ const char16_t app_visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -188,7 +190,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -227,7 +230,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); @@ -261,7 +264,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); @@ -308,7 +311,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); @@ -348,7 +351,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED); @@ -388,7 +391,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + app_visible_name, package_name, /*color_icon=*/CreateTestImage(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED);
diff --git a/ash/system/phonehub/phone_hub_recent_apps_view.cc b/ash/system/phonehub/phone_hub_recent_apps_view.cc index 5f319dbc..c0bd89b 100644 --- a/ash/system/phonehub/phone_hub_recent_apps_view.cc +++ b/ash/system/phonehub/phone_hub_recent_apps_view.cc
@@ -4,6 +4,7 @@ #include "ash/system/phonehub/phone_hub_recent_apps_view.h" +#include <algorithm> #include <memory> #include <numeric> #include <vector> @@ -23,7 +24,6 @@ #include "ash/system/tray/tray_constants.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "ash/webui/eche_app_ui/system_info_provider.h" -#include "base/cxx17_backports.h" #include "base/metrics/histogram_functions.h" #include "base/ranges/algorithm.h" #include "chromeos/ash/components/phonehub/notification.h" @@ -105,8 +105,8 @@ spacing = (child_area.width() - visible_child_width - kRecentAppButtonsViewHorizontalPadding * 2) / (static_cast<int>(visible_children.size()) - 1); - spacing = base::clamp(spacing, kRecentAppButtonMinSpacing, - kRecentAppButtonDefaultSpacing); + spacing = std::clamp(spacing, kRecentAppButtonMinSpacing, + kRecentAppButtonDefaultSpacing); } int child_x = child_area.x() + kRecentAppButtonsViewHorizontalPadding;
diff --git a/ash/system/power/battery_image_source.cc b/ash/system/power/battery_image_source.cc index 29ce06e2..d2377ca 100644 --- a/ash/system/power/battery_image_source.cc +++ b/ash/system/power/battery_image_source.cc
@@ -4,10 +4,11 @@ #include "ash/system/power/battery_image_source.h" +#include <algorithm> + #include "ash/constants/ash_features.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/style/ash_color_provider.h" -#include "base/cxx17_backports.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" @@ -84,7 +85,7 @@ std::floor(info_.charge_percent / 100.0 * icon_bounds.height()); const float min_charge_level = dsf * kMinVisualChargeLevel; charge_level = - base::clamp(charge_level, min_charge_level, icon_bounds.height()); + std::clamp(charge_level, min_charge_level, icon_bounds.height()); const float charge_y = icon_bounds.bottom() - charge_level; gfx::RectF clip_rect(0, charge_y, size().width() * dsf,
diff --git a/ash/system/privacy_screen/privacy_screen_toast_controller.cc b/ash/system/privacy_screen/privacy_screen_toast_controller.cc index 0146eb5..def5919 100644 --- a/ash/system/privacy_screen/privacy_screen_toast_controller.cc +++ b/ash/system/privacy_screen/privacy_screen_toast_controller.cc
@@ -4,6 +4,8 @@ #include "ash/system/privacy_screen/privacy_screen_toast_controller.h" +#include <algorithm> + #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/bubble/bubble_constants.h" #include "ash/shelf/shelf.h" @@ -14,7 +16,6 @@ #include "ash/system/unified/unified_system_tray.h" #include "ash/system/unified/unified_system_tray_bubble.h" #include "ash/system/unified/unified_system_tray_view.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" namespace ash { @@ -143,8 +144,8 @@ /*enabled=*/privacy_screen_controller->GetEnabled(), /*managed=*/privacy_screen_controller->IsManaged()); int width = - base::clamp(toast_view_->GetPreferredSize().width(), - kPrivacyScreenToastMinWidth, kPrivacyScreenToastMaxWidth); + std::clamp(toast_view_->GetPreferredSize().width(), + kPrivacyScreenToastMinWidth, kPrivacyScreenToastMaxWidth); bubble_view_->SetPreferredWidth(width); } }
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index d83e0ec..a50711c3 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -136,7 +136,6 @@ constexpr int kMessageCenterCollapseThreshold = 175; constexpr int kStackedNotificationBarHeight = 32; -constexpr int kStackedNotificationBarCollapsedHeight = 40; constexpr int kNotificationIconStackThreshold = 28; constexpr int kUnifiedSliderViewSpacing = 12; constexpr int kUnifiedMessageCenterBubbleSpacing = 8;
diff --git a/ash/system/unified/top_shortcuts_view.cc b/ash/system/unified/top_shortcuts_view.cc index 3087a669..a3e560ea 100644 --- a/ash/system/unified/top_shortcuts_view.cc +++ b/ash/system/unified/top_shortcuts_view.cc
@@ -4,6 +4,7 @@ #include "ash/system/unified/top_shortcuts_view.h" +#include <algorithm> #include <cstddef> #include <memory> #include <numeric> @@ -28,7 +29,6 @@ #include "ash/system/unified/user_chooser_detailed_view_controller.h" #include "ash/system/unified/user_chooser_view.h" #include "ash/system/user/login_status.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/ranges/algorithm.h" #include "components/prefs/pref_registry_simple.h" @@ -71,8 +71,8 @@ if (visible_children.size() > 1) { spacing = (child_area.width() - visible_child_width) / (static_cast<int>(visible_children.size()) - 1); - spacing = base::clamp(spacing, kUnifiedTopShortcutButtonMinSpacing, - kUnifiedTopShortcutButtonDefaultSpacing); + spacing = std::clamp(spacing, kUnifiedTopShortcutButtonMinSpacing, + kUnifiedTopShortcutButtonDefaultSpacing); } int x = child_area.x(); @@ -90,7 +90,7 @@ child_area.width() - (static_cast<int>(visible_children.size()) - 1) * spacing - (visible_child_width - width); - width = base::clamp(width, 0, std::max(0, remainder)); + width = std::clamp(width, 0, std::max(0, remainder)); } child->SetBounds(x, child_y, width, child->GetHeightForWidth(width));
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index b6ed33c..3d095d46 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "ash/system/unified/unified_system_tray_controller.h" + +#include <algorithm> #include <memory> #include "ash/capture_mode/capture_mode_feature_pod_controller.h" @@ -67,7 +69,6 @@ #include "ash/system/unified/user_chooser_detailed_view_controller.h" #include "ash/wm/lock_state_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_macros.h" @@ -896,9 +897,9 @@ // If already expanded, only consider swiping down. Otherwise, only consider // swiping up. if (was_expanded_) { - return base::clamp(1.0 - std::max(0.0, y_diff) / drag_threshold_, 0.0, 1.0); + return std::clamp(1.0 - std::max(0.0, y_diff) / drag_threshold_, 0.0, 1.0); } else { - return base::clamp(std::max(0.0, -y_diff) / drag_threshold_, 0.0, 1.0); + return std::clamp(std::max(0.0, -y_diff) / drag_threshold_, 0.0, 1.0); } }
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html index 0d026f3..dba3811 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html
@@ -10,7 +10,7 @@ '. mainpage-desc . thumbnail .' '. . . . .'; grid-template-columns: 20px auto 192px auto 20px; - grid-template-rows: auto auto 20px 192px auto 20px; + grid-template-rows: auto auto 20px 192px 1fr 20px; height: 100%; } @@ -23,7 +23,7 @@ '. mainpage-desc .' '. . .'; grid-template-columns: 20px minmax(0,1fr) 20px; - grid-template-rows: auto auto 20px 130px auto 18px; + grid-template-rows: auto auto 20px 130px 1fr 18px; } #container.jelly-disabled { @@ -59,7 +59,7 @@ } #ambientSubpageLink { - --cr-icon-button-size: 48px; + --cr-icon-button-size: 44px; /* Make the arrow align with the thumbnail image */ margin-inline-end: -18px; } @@ -67,7 +67,7 @@ #ambientLabel>h2 { color: var(--cros-text-color-primary); font: var(--personalization-app-label-font); - margin: 14px 0; + margin: 12px 0; } #ambientLabel.enterprise { @@ -126,7 +126,7 @@ :host-context(body.jelly-enabled) #imageContainer, :host-context(body.jelly-enabled) #imagePlaceholder { - aspect-ratio: 460/274; + aspect-ratio: 340/220; max-width: 460px; min-width: 278px; } @@ -172,7 +172,7 @@ #albumTitle { color: var(--cros-text-color-primary); font: var(--cros-display-7-font); - margin-top: 16px; + margin-top: 10px; } #albumTitle.jelly-disabled {
diff --git a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html index 0f2ff380..7090445 100644 --- a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html +++ b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html
@@ -39,10 +39,10 @@ display: grid; gap: 12px; grid-template-columns: repeat(4, minmax(0,1fr)); - margin: 16px 0; + margin: 16px 0 12px; } - cr-button { + #container cr-button { background-color: var(--cros-sys-app_base_shaded); border: none; border-radius: 16px;
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html index 1442c925d..8082f82 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html
@@ -27,7 +27,7 @@ color: var(--cros-text-color-primary); display: inline-block; font: var(--personalization-app-label-font); - margin: 14px 0; + margin: 12px 0; } iron-icon[icon='personalization:managed'] { @@ -35,7 +35,7 @@ } #wallpaperButton { - --cr-icon-button-size: 48px; + --cr-icon-button-size: 44px; /* Make the arrow align with the thumbnail image */ margin-inline-end: -18px; } @@ -75,12 +75,12 @@ } :host-context(body.jelly-enabled) #container { - grid-template-rows: auto auto 20px 1fr 24px; + grid-template-rows: auto auto 16px auto 20px; } :host-context(body.jelly-enabled) #imageContainer, :host-context(body.jelly-enabled) #imagePlaceholder { - aspect-ratio: 460/274; + aspect-ratio: 340/220; max-width: 460px; min-width: 278px; }
diff --git a/ash/wm/desks/cros_next_default_desk_button.cc b/ash/wm/desks/cros_next_default_desk_button.cc index 7e73f46..a04686d 100644 --- a/ash/wm/desks/cros_next_default_desk_button.cc +++ b/ash/wm/desks/cros_next_default_desk_button.cc
@@ -4,6 +4,8 @@ #include "ash/wm/desks/cros_next_default_desk_button.h" +#include <algorithm> + #include "ash/strings/grit/ash_strings.h" #include "ash/wm/desks/desk.h" #include "ash/wm/desks/desk_mini_view.h" @@ -67,7 +69,7 @@ // tests with extreme abnormal size of display. const int min_width = std::min(preview_width, kDefaultDeskButtonMinWidth); const int max_width = std::max(preview_width, kDefaultDeskButtonMinWidth); - const int width = base::clamp( + const int width = std::clamp( label_width + 2 * kDefaultButtonHorizontalPadding, min_width, max_width); return gfx::Size(width, kDefaultDeskButtonHeight); }
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc index 81da3a67..20fb5f0 100644 --- a/ash/wm/desks/desk_mini_view.cc +++ b/ash/wm/desks/desk_mini_view.cc
@@ -25,7 +25,6 @@ #include "ash/wm/overview/overview_constants.h" #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_utils.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/i18n/rtl.h" #include "base/strings/string_util.h" @@ -583,7 +582,7 @@ const int max_width = std::max(preview_bounds.width() - focus_ring_length, kMinDeskNameViewWidth); const int text_width = - base::clamp(desk_name_view_size.width(), min_width, max_width); + std::clamp(desk_name_view_size.width(), min_width, max_width); const int desk_name_view_x = preview_bounds.x() + (preview_bounds.width() - text_width) / 2; gfx::Rect desk_name_view_bounds{desk_name_view_x,
diff --git a/ash/wm/desks/desk_preview_view.cc b/ash/wm/desks/desk_preview_view.cc index 39aa819..6346890 100644 --- a/ash/wm/desks/desk_preview_view.cc +++ b/ash/wm/desks/desk_preview_view.cc
@@ -4,6 +4,7 @@ #include "ash/wm/desks/desk_preview_view.h" +#include <algorithm> #include <functional> #include <memory> #include <utility> @@ -31,7 +32,6 @@ #include "base/containers/contains.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" -#include "base/cxx17_backports.h" #include "base/ranges/algorithm.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/wm/features.h" @@ -395,8 +395,8 @@ root->bounds().width() <= kUseSmallerHeightDividerWidthThreshold ? kRootHeightDividerForSmallScreen : kRootHeightDivider; - return base::clamp(root->bounds().height() / height_divider, - kDeskPreviewMinHeight, kDeskPreviewMaxHeight); + return std::clamp(root->bounds().height() / height_divider, + kDeskPreviewMinHeight, kDeskPreviewMaxHeight); } void DeskPreviewView::SetHighlightOverlayVisibility(bool visible) {
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index 016a097..077047f7 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -4,6 +4,7 @@ #include "ash/wm/desks/desks_controller.h" +#include <algorithm> #include <memory> #include <utility> @@ -54,7 +55,6 @@ #include "base/check_op.h" #include "base/containers/contains.h" #include "base/containers/unique_ptr_adapters.h" -#include "base/cxx17_backports.h" #include "base/debug/crash_logging.h" #include "base/debug/dump_without_crashing.h" #include "base/functional/bind.h" @@ -1542,8 +1542,8 @@ int new_user_active_desk_index = /* This is a default initialized index to 0 if the id doesn't exist. */ user_to_active_desk_index_[current_account_id_]; - new_user_active_desk_index = base::clamp(new_user_active_desk_index, 0, - static_cast<int>(desks_.size()) - 1); + new_user_active_desk_index = std::clamp(new_user_active_desk_index, 0, + static_cast<int>(desks_.size()) - 1); ActivateDesk(desks_[new_user_active_desk_index].get(), DesksSwitchSource::kUserSwitch);
diff --git a/ash/wm/desks/root_window_desk_switch_animator.cc b/ash/wm/desks/root_window_desk_switch_animator.cc index 9b486870..14479843 100644 --- a/ash/wm/desks/root_window_desk_switch_animator.cc +++ b/ash/wm/desks/root_window_desk_switch_animator.cc
@@ -4,6 +4,8 @@ #include "ash/wm/desks/root_window_desk_switch_animator.h" +#include <algorithm> + #include "ash/constants/ash_features.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/screen_util.h" @@ -13,7 +15,6 @@ #include "ash/wm/desks/desks_controller.h" #include "ash/wm/desks/desks_util.h" #include "base/auto_reset.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" @@ -246,10 +247,10 @@ float translation_x = animation_layer->transform().To2dTranslation().x() + translation_delta_x; translation_x = - base::clamp(translation_x, - static_cast<float>(-animation_layer->bounds().width() + - visible_bounds_width), - 0.f); + std::clamp(translation_x, + static_cast<float>(-animation_layer->bounds().width() + + visible_bounds_width), + 0.f); gfx::Transform transform; transform.Translate(translation_x, 0.f); base::AutoReset<bool> auto_reset(&setting_new_transform_, true);
diff --git a/ash/wm/desks/zero_state_button.cc b/ash/wm/desks/zero_state_button.cc index 0be7eda4..e42f806a 100644 --- a/ash/wm/desks/zero_state_button.cc +++ b/ash/wm/desks/zero_state_button.cc
@@ -4,6 +4,8 @@ #include "ash/wm/desks/zero_state_button.h" +#include <algorithm> + #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -13,7 +15,6 @@ #include "ash/wm/desks/desk_preview_view.h" #include "ash/wm/desks/desks_bar_view.h" #include "ash/wm/desks/desks_controller.h" -#include "base/cxx17_backports.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/gfx/canvas.h" @@ -82,8 +83,8 @@ const int max_width = std::max(preview_width, kZeroStateDefaultDeskButtonMinWidth); const int width = - base::clamp(label_width + 2 * kZeroStateDefaultButtonHorizontalPadding, - min_width, max_width); + std::clamp(label_width + 2 * kZeroStateDefaultButtonHorizontalPadding, + min_width, max_width); return gfx::Size(width, kZeroStateButtonHeight); }
diff --git a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc index 9b91f780..71b9db9 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc
@@ -4,6 +4,8 @@ #include "ash/wm/gestures/back_gesture/back_gesture_affordance.h" +#include <algorithm> + #include "ash/display/screen_orientation_controller.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/style/scoped_light_mode_as_default.h" @@ -15,7 +17,6 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_divider.h" #include "ash/wm/window_util.h" -#include "base/cxx17_backports.h" #include "base/i18n/rtl.h" #include "chromeos/constants/chromeos_features.h" #include "components/vector_icons/vector_icons.h" @@ -323,7 +324,7 @@ kBackgroundRadius; float y_progress = y_drag_amount / kDistanceForFullYProgress; - y_drag_progress_ = base::clamp(y_progress, -1.0f, 1.0f); + y_drag_progress_ = std::clamp(y_progress, -1.0f, 1.0f); during_reverse_dragging_ = during_reverse_dragging;
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index c8826db..931d395e 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -4,6 +4,7 @@ #include "ash/wm/overview/overview_grid.h" +#include <algorithm> #include <functional> #include <memory> #include <utility> @@ -60,7 +61,6 @@ #include "ash/wm/workspace/workspace_layout_manager.h" #include "ash/wm/workspace_controller.h" #include "base/containers/adapters.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/numerics/safe_conversions.h" #include "base/ranges/algorithm.h" @@ -1378,7 +1378,7 @@ OverviewItem* nudged_item = window_list_[data.index].get(); double nudge_param = value * value / 30.0; - nudge_param = base::clamp(nudge_param, 0.0, 1.0); + nudge_param = std::clamp(nudge_param, 0.0, 1.0); gfx::RectF bounds = gfx::Tween::RectFValueBetween(nudge_param, data.src, data.dst); nudged_item->SetBounds(bounds, OVERVIEW_ANIMATION_NONE); @@ -1570,7 +1570,7 @@ bool OverviewGrid::UpdateScrollOffset(float delta) { float new_scroll_offset = scroll_offset_; new_scroll_offset += delta; - new_scroll_offset = base::clamp(new_scroll_offset, scroll_offset_min_, 0.f); + new_scroll_offset = std::clamp(new_scroll_offset, scroll_offset_min_, 0.f); // For flings, we want to return false if we hit one of the edges, which is // when |new_scroll_offset| is exactly 0.f or |scroll_offset_min_|. @@ -2328,13 +2328,13 @@ // `rightmost_window_right` may have been modified by an earlier scroll. // `scroll_offset_` is added to adjust for that. If `rightmost_window_right` // is less than `total_bounds.right()`, the grid cannot be scrolled. Set - // `scroll_offset_min_` to 0 so that `base::clamp()` is happy. + // `scroll_offset_min_` to 0 so that `std::clamp()` is happy. rightmost_window_right -= scroll_offset_; scroll_offset_min_ = total_bounds.right() - rightmost_window_right; if (scroll_offset_min_ > 0.f) scroll_offset_min_ = 0.f; - scroll_offset_ = base::clamp(scroll_offset_, scroll_offset_min_, 0.f); + scroll_offset_ = std::clamp(scroll_offset_, scroll_offset_min_, 0.f); // Map which contains up to |kTabletLayoutRow| entries with information on the // last items right bound per row. Used so we can place the next item directly
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index 05bd97d..904844d 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -33,7 +33,6 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_util.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_functions.h" @@ -535,7 +534,7 @@ kDragToCloseDistanceThresholdDp; overview_session_->GetGridWithRootWindow(item_->root_window()) ->UpdateNudge(item_, val); - val = base::clamp(val, 0.f, 1.f); + val = std::clamp(val, 0.f, 1.f); float opacity = original_opacity_; if (opacity > kItemMinOpacity) opacity = original_opacity_ - val * (original_opacity_ - kItemMinOpacity); @@ -636,7 +635,7 @@ desks_bar_data.desks_bar_bounds) / desks_bar_data.shrink_region_distance.x(); } - value = base::clamp(value, 0.f, 1.f); + value = std::clamp(value, 0.f, 1.f); const gfx::SizeF size_value = gfx::Tween::SizeFValueBetween(1.f - value, original_scaled_size_, desks_bar_data.on_desks_bar_item_size);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index f6667929..d779739 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -4,6 +4,7 @@ #include "ash/wm/splitview/split_view_controller.h" +#include <algorithm> #include <cmath> #include <memory> @@ -49,7 +50,6 @@ #include "base/containers/contains.h" #include "base/containers/cxx20_erase.h" #include "base/containers/flat_set.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -166,10 +166,10 @@ gfx::Point GetBoundedPosition(const gfx::Point& location_in_screen, const gfx::Rect& bounds_in_screen) { - return gfx::Point(base::clamp(location_in_screen.x(), bounds_in_screen.x(), - bounds_in_screen.right() - 1), - base::clamp(location_in_screen.y(), bounds_in_screen.y(), - bounds_in_screen.bottom() - 1)); + return gfx::Point(std::clamp(location_in_screen.x(), bounds_in_screen.x(), + bounds_in_screen.right() - 1), + std::clamp(location_in_screen.y(), bounds_in_screen.y(), + bounds_in_screen.bottom() - 1)); } ui::InputMethod* GetCurrentInputMethod() {
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index c452c33..7bd8535 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -29,7 +29,6 @@ #include "ash/wm/window_util.h" #include "base/command_line.h" #include "base/containers/contains.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/location.h" @@ -950,7 +949,7 @@ // accuracy. float largest_hinge_acceleration = std::max(std::abs(base_reading.x()), std::abs(lid_reading.x())); - float smoothing_ratio = base::clamp( + float smoothing_ratio = std::clamp( (largest_hinge_acceleration - kHingeVerticalSmoothingStart) / (kHingeVerticalSmoothingMaximum - kHingeVerticalSmoothingStart), 0.0f, 1.0f);
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc index 1f43606..8caabc3 100644 --- a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc +++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
@@ -4,6 +4,7 @@ #include "ash/wm/tablet_mode/tablet_mode_multitask_menu.h" +#include <algorithm> #include <bit> #include "ash/public/cpp/shell_window_ids.h" @@ -16,7 +17,6 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler.h" #include "ash/wm/window_state.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/frame/multitask_menu/multitask_menu_metrics.h" @@ -346,7 +346,7 @@ const float max_translation_y = -menu_view_->GetPreferredSize().height() - kVerticalPosition; const float translated_ratio = - base::clamp(current_translation_y / max_translation_y, 0.f, 1.f); + std::clamp(current_translation_y / max_translation_y, 0.f, 1.f); Animate(/*show=*/translated_ratio <= 0.5f); }
diff --git a/ash/wm/window_cycle/window_cycle_item_view.cc b/ash/wm/window_cycle/window_cycle_item_view.cc index c0b4b40..2952f3b4 100644 --- a/ash/wm/window_cycle/window_cycle_item_view.cc +++ b/ash/wm/window_cycle/window_cycle_item_view.cc
@@ -4,10 +4,11 @@ #include "ash/wm/window_cycle/window_cycle_item_view.h" +#include <algorithm> + #include "ash/shell.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_preview_view.h" -#include "base/cxx17_backports.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/window.h" @@ -107,8 +108,8 @@ // Previews should never be narrower than half or wider than double their // fixed height. - preview_size.set_width(base::clamp(preview_size.width(), kMinPreviewWidthDp, - kMaxPreviewWidthDp)); + preview_size.set_width( + std::clamp(preview_size.width(), kMinPreviewWidthDp, kMaxPreviewWidthDp)); const int margin = GetInsets().width(); preview_size.Enlarge(margin, margin + WindowMiniView::kHeaderHeightDp);
diff --git a/ash/wm/window_cycle/window_cycle_view.cc b/ash/wm/window_cycle/window_cycle_view.cc index 10e158e18..69c58c5 100644 --- a/ash/wm/window_cycle/window_cycle_view.cc +++ b/ash/wm/window_cycle/window_cycle_view.cc
@@ -4,19 +4,20 @@ #include "ash/wm/window_cycle/window_cycle_view.h" +#include <algorithm> + #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/public/cpp/metrics_util.h" #include "ash/public/cpp/style/color_provider.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" -#include "ash/style/ash_color_provider.h" +#include "ash/style/ash_color_id.h" #include "ash/style/system_shadow.h" #include "ash/style/tab_slider.h" #include "ash/style/tab_slider_button.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_item_view.h" #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" @@ -122,11 +123,14 @@ layer()->SetName("WindowCycleView"); layer()->SetMasksToBounds(true); + const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); SetBackground(views::CreateThemedRoundedRectBackground( - cros_tokens::kCrosSysScrim2, kBackgroundCornerRadius)); + is_jellyroll_enabled ? cros_tokens::kCrosSysScrim2 + : static_cast<ui::ColorId>(kColorAshShieldAndBase80), + kBackgroundCornerRadius)); SetBorder(std::make_unique<views::HighlightBorder>( kBackgroundCornerRadius, - chromeos::features::IsJellyrollEnabled() + is_jellyroll_enabled ? views::HighlightBorder::Type::kHighlightBorderOnShadow : views::HighlightBorder::Type::kHighlightBorder1, /*use_light_colors=*/false)); @@ -146,9 +150,8 @@ WindowCycleView::kInsideBorderHorizontalPaddingDp, kInsideBorderVerticalPaddingDp, WindowCycleView::kInsideBorderHorizontalPaddingDp), - chromeos::features::IsJellyrollEnabled() - ? kBetweenChildPaddingDpCrOSNext - : kBetweenChildPaddingDp)); + is_jellyroll_enabled ? kBetweenChildPaddingDpCrOSNext + : kBetweenChildPaddingDp)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); @@ -175,7 +178,9 @@ // Configure the focus ring for the tab slider selector view. views::FocusRing::Install(tab_slider_selector_view); auto* focus_ring = views::FocusRing::Get(tab_slider_selector_view); - focus_ring->SetColorId(cros_tokens::kCrosSysFocusRing); + focus_ring->SetColorId(is_jellyroll_enabled ? cros_tokens::kCrosSysFocusRing + : static_cast<ui::ColorId>( + ui::kColorAshFocusRing)); const float halo_inset = focus_ring->GetHaloThickness() / 2.f + 2; focus_ring->SetHaloInset(-halo_inset); // Set a pill shaped (fully rounded rect) highlight path to focus ring. @@ -194,9 +199,7 @@ no_recent_items_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); no_recent_items_label_->SetVerticalAlignment(gfx::ALIGN_MIDDLE); - no_recent_items_label_->SetEnabledColor( - AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kIconColorSecondary)); + no_recent_items_label_->SetEnabledColorId(kColorAshIconColorSecondary); no_recent_items_label_->SetFontList( no_recent_items_label_->font_list() .DeriveWithSizeDelta( @@ -567,12 +570,12 @@ // However, the container must span the screen, i.e. the maximum x is 0 // and the minimum for its right boundary is the width of the screen. int minimum_x = width() - content_container_bounds.width(); - x_offset = base::clamp(x_offset, minimum_x, 0); + x_offset = std::clamp(x_offset, minimum_x, 0); // If the user has dragged, offset the container based on how much they // have dragged. Cap |horizontal_distance_dragged_| based on the available // distance from the container to the left and right boundaries. - float clamped_horizontal_distance_dragged = base::clamp( + float clamped_horizontal_distance_dragged = std::clamp( horizontal_distance_dragged_, static_cast<float>(minimum_x - x_offset), static_cast<float>(-x_offset)); if (horizontal_distance_dragged_ != clamped_horizontal_distance_dragged)
diff --git a/ash/wm/window_mini_view.cc b/ash/wm/window_mini_view.cc index af92f70..85adef0 100644 --- a/ash/wm/window_mini_view.cc +++ b/ash/wm/window_mini_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/style/ash_color_id.h" #include "ash/style/ash_color_provider.h" #include "ash/wm/overview/overview_constants.h" #include "ash/wm/window_preview_view.h" @@ -70,8 +71,11 @@ // Always put the backdrop view under other children. backdrop_view_ = AddChildViewAt(std::make_unique<views::View>(), 0); backdrop_view_->SetPaintToLayer(); - backdrop_view_->SetBackground( - views::CreateThemedSolidBackground(cros_tokens::kCrosSysScrim)); + backdrop_view_->SetBackground(views::CreateThemedSolidBackground( + chromeos::features::IsJellyrollEnabled() + ? cros_tokens::kCrosSysScrim + : static_cast<ui::ColorId>( + kColorAshControlBackgroundColorInactive))); ui::Layer* layer = backdrop_view_->layer(); layer->SetFillsBoundsOpaquely(false); @@ -185,7 +189,10 @@ gfx::Insets header_insets(0); if (chromeos::features::IsJellyrollEnabled()) { header_view_->SetBackground(views::CreateThemedRoundedRectBackground( - cros_tokens::kCrosSysHeader, /*top_radius=*/kWindowMiniViewCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? cros_tokens::kCrosSysHeader + : static_cast<ui::ColorId>(kColorAshShieldAndBase80), + /*top_radius=*/kWindowMiniViewCornerRadius, /*bottom_radius=*/0, /*for_border_thickness=*/0)); header_insets = kHeaderInsets; }
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc index 3163236..54835d6 100644 --- a/ash/wm/window_positioning_utils.cc +++ b/ash/wm/window_positioning_utils.cc
@@ -18,7 +18,6 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" -#include "base/cxx17_backports.h" #include "base/notreached.h" #include "base/numerics/ranges.h" #include "chromeos/ui/wm/features.h" @@ -46,8 +45,8 @@ min_axis_length = std::min(min_axis_length, work_area_axis_length); // The primary snap size is proportional to |snap_ratio|. if (is_primary_snap) { - return base::clamp(static_cast<int>(snap_ratio * work_area_axis_length), - min_axis_length, work_area_axis_length); + return std::clamp(static_cast<int>(snap_ratio * work_area_axis_length), + min_axis_length, work_area_axis_length); } // The secondary snap size is proportional to the |snap_ratio|, but @@ -58,8 +57,8 @@ // `WindowPositioningUtilsTest.SnapBoundsWithOddNumberedScreenWidth`. const int empty_space_axis_length = static_cast<int>((1 - snap_ratio) * work_area_axis_length); - return base::clamp(work_area_axis_length - empty_space_axis_length, - min_axis_length, work_area_axis_length); + return std::clamp(work_area_axis_length - empty_space_axis_length, + min_axis_length, work_area_axis_length); } // Return true if the window or one of its ancestor returns true from
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index f37e3cf..8b95d5a 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -172,9 +172,6 @@ class OutputDevice; } namespace blink { -class CategorizedWorkerPoolImpl; -class CategorizedWorkerPoolJob; -class CategorizedWorkerPool; class DiskDataAllocator; class IdentifiabilityActiveSampler; class RTCVideoDecoderAdapter; @@ -190,6 +187,9 @@ } } // namespace blink namespace cc { +class CategorizedWorkerPoolImpl; +class CategorizedWorkerPoolJob; +class CategorizedWorkerPool; class CompletionEvent; class TileTaskManagerImpl; } // namespace cc @@ -742,13 +742,13 @@ friend class android_webview::JsSandboxIsolate; friend class base::SimpleThread; friend class base::internal::GetAppOutputScopedAllowBaseSyncPrimitives; - friend class blink::CategorizedWorkerPoolImpl; - friend class blink::CategorizedWorkerPoolJob; friend class blink::IdentifiabilityActiveSampler; friend class blink::SourceStream; friend class blink::VideoTrackRecorderImplContextProvider; friend class blink::WorkerThread; friend class blink::scheduler::NonMainThreadImpl; + friend class cc::CategorizedWorkerPoolImpl; + friend class cc::CategorizedWorkerPoolJob; friend class chrome_cleaner::ResetShortcutsComponent; friend class chrome_cleaner::SystemReportComponent; friend class content::BrowserMainLoop; @@ -829,13 +829,13 @@ friend class base::StackSamplingProfiler; friend class base::internal::JobTaskSource; friend class base::sequence_manager::internal::TaskQueueImpl; - friend class blink::CategorizedWorkerPoolImpl; - friend class blink::CategorizedWorkerPoolJob; - friend class blink::CategorizedWorkerPool; friend class blink::LegacyWebRtcVideoFrameAdapter; friend class blink::RTCVideoDecoderAdapter; friend class blink::RTCVideoEncoder; friend class blink::WebRtcVideoFrameAdapter; + friend class cc::CategorizedWorkerPoolImpl; + friend class cc::CategorizedWorkerPoolJob; + friend class cc::CategorizedWorkerPool; friend class cc::TileTaskManagerImpl; friend class content::DesktopCaptureDevice; friend class content::EmergencyTraceFinalisationCoordinator;
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc index 407d8b82..77bb741d 100644 --- a/base/win/registry_unittest.cc +++ b/base/win/registry_unittest.cc
@@ -6,6 +6,7 @@ #include <windows.h> +#include <shlobj.h> #include <stdint.h> #include <cstring> @@ -469,14 +470,28 @@ const std::wstring foo_software_key_; }; +class RegistryTestHKLMAdmin : public RegistryTestHKLM { + protected: + void SetUp() override { + if (!IsRedirectorPresent()) { + GTEST_SKIP(); + } + if (!::IsUserAnAdmin()) { + GTEST_SKIP(); + } + // Clean up any stale registry keys. + for (const REGSAM mask : {kNativeViewMask, kRedirectedViewMask}) { + RegKey key; + key.Open(HKEY_LOCAL_MACHINE, L"Software", KEY_SET_VALUE | mask); + key.DeleteKey(kRootKey); + } + } +}; + // This test requires running as an Administrator as it tests redirected // registry writes to HKLM\Software // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384253.aspx -// TODO(wfh): flaky test on Vista. See http://crbug.com/377917 -TEST_F(RegistryTestHKLM, DISABLED_Wow64RedirectedFromNative) { - if (!IsRedirectorPresent()) - return; - +TEST_F(RegistryTestHKLMAdmin, Wow64RedirectedFromNative) { RegKey key; // Test redirected key access from non-redirected. @@ -516,10 +531,7 @@ ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(L"Windows", KEY_READ | KEY_WOW64_64KEY)); } -// TODO(wfh): flaky test on Vista. See http://crbug.com/377917 -TEST_F(RegistryTestHKLM, DISABLED_Wow64NativeFromRedirected) { - if (!IsRedirectorPresent()) - return; +TEST_F(RegistryTestHKLMAdmin, Wow64NativeFromRedirected) { RegKey key; // Test non-redirected key access from redirected.
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni index a7f315c3..d3c4e3c 100644 --- a/build/config/mac/mac_sdk.gni +++ b/build/config/mac/mac_sdk.gni
@@ -38,7 +38,7 @@ # The SDK version used when making official builds. This is a single exact # version, not a minimum. If this version isn't available official builds # will fail. - mac_sdk_official_version = "13.0" + mac_sdk_official_version = "13.3" # The SDK build version used when making official builds. This is a single # exact version found at "System/Library/CoreServices/SystemVersion.plist"
diff --git a/build/config/rust.gni b/build/config/rust.gni index 6f05841..9435aa1 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -190,7 +190,7 @@ # (see '*_toolchain_supports_platform above') to enable experimentation with # other toolchains. rust_abi_target = "" -if (is_linux) { +if (is_linux || is_chromeos) { cpu = current_cpu if (cpu == "arm64") { cpu = "aarch64"
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py index 68c96e259..cd253cd7 100755 --- a/build/mac_toolchain.py +++ b/build/mac_toolchain.py
@@ -34,12 +34,16 @@ return plistlib.load(f) -# This contains binaries from Xcode 14.0 14B47b along with the macOS 13 SDK -# (13.0 22A372). To build these packages, see comments in +# This contains binaries from Xcode 14.3 14E222b along with the macOS 13.3 SDK +# (13.3 22E245). To build these packages, see comments in # build/xcode_binaries.yaml +# To update the version numbers, open Xcode's "About Xcode" for the first number +# and run `xcrun --show-sdk-build-version` for the second. +# To update the _TAG, use the output of the `cipd create` command mentioned in +# xcode_binaries.yaml. MAC_BINARIES_LABEL = 'infra_internal/ios/xcode/xcode_binaries/mac-amd64' -MAC_BINARIES_TAG = '14b47b' +MAC_BINARIES_TAG = 'ajH0-Cuzzqtyj98qUlsgO1-lepRhXoVVNAjVXDIYHxcC' # The toolchain will not be downloaded if the minimum OS version is not met. 19 # is the major version number for macOS 10.15. Xcode 14.0 14B47b only runs on
diff --git a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py index 0b45446..98c8290 100755 --- a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py +++ b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
@@ -17,6 +17,7 @@ import sys THIS_DIR = os.path.abspath(os.path.dirname(__file__)) +CHROMIUM_SRC = os.path.abspath(os.path.join(THIS_DIR,'..','..')) REPROXY_CFG_HEADER = """# AUTOGENERATED FILE - DO NOT EDIT # Generated by fetch_reclient_cfgs.py @@ -26,14 +27,14 @@ """ def ClangRevision(): - sys.path.insert(0, os.path.join(THIS_DIR, '..', '..', + sys.path.insert(0, os.path.join(CHROMIUM_SRC, 'tools', 'clang', 'scripts')) import update sys.path.pop(0) return update.PACKAGE_VERSION def NaclRevision(): - nacl_dir = os.path.join(THIS_DIR, '..', '..', 'native_client') + nacl_dir = os.path.join(CHROMIUM_SRC, 'native_client') if not os.path.exists(nacl_dir): return None return subprocess.check_output( @@ -77,9 +78,14 @@ return False with open(tmpl_path) as f: reproxy_cfg_tmpl = string.Template(REPROXY_CFG_HEADER+f.read()) + scandeps_bin_name = 'scandeps_server' + if sys.platform.startswith('win'): + scandeps_bin_name += ".exe" reproxy_cfg = reproxy_cfg_tmpl.substitute({ 'rbe_instance': rbe_instance, 'reproxy_cfg_template': reproxy_cfg_template, + 'scandeps_bin_path': + os.path.join(CHROMIUM_SRC, 'buildtools', 'reclient', scandeps_bin_name), }) reproxy_cfg_path = os.path.join(THIS_DIR, 'reproxy.cfg') with open(reproxy_cfg_path, 'w') as f:
diff --git a/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template b/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template index 00d4ea0..b2a15910 100644 --- a/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template +++ b/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template
@@ -8,3 +8,5 @@ # TODO(b/276727504) Re-enable once noop build shutdown time bug is fixed # enable_deps_cache=true use_unified_uploads=true +fast_log_collection=true +depsscanner_address=exec://${scandeps_bin_path}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index e5f60ae1..05e11fe 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -216,6 +216,8 @@ "metrics/web_vital_metrics.h", "raster/bitmap_raster_buffer_provider.cc", "raster/bitmap_raster_buffer_provider.h", + "raster/categorized_worker_pool.cc", + "raster/categorized_worker_pool.h", "raster/gpu_raster_buffer_provider.cc", "raster/gpu_raster_buffer_provider.h", "raster/lcd_text_disallowed_reason.cc", @@ -773,6 +775,7 @@ "paint/skia_paint_canvas_unittest.cc", "paint/solid_color_analyzer_unittest.cc", "paint/transfer_cache_unittest.cc", + "raster/categorized_worker_pool_unittest.cc", "raster/playback_image_provider_unittest.cc", "raster/raster_buffer_provider_unittest.cc", "raster/raster_source_unittest.cc",
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index ea6c4e80..e071967 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc
@@ -52,6 +52,9 @@ const char kDisableLayerTreeHostMemoryPressure[] = "disable-layer-tree-host-memory-pressure"; +// Controls the number of threads to use for raster tasks. +const char kNumRasterThreads[] = "num-raster-threads"; + // Renders a border around compositor layers to help debug and study // layer compositing. const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
diff --git a/cc/base/switches.h b/cc/base/switches.h index c31d7345..a92bed0 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h
@@ -34,6 +34,9 @@ // Switches for LayerTreeHost. CC_BASE_EXPORT extern const char kDisableLayerTreeHostMemoryPressure[]; +// Switches for raster. +CC_BASE_EXPORT extern const char kNumRasterThreads[]; + // Debug visualizations. CC_BASE_EXPORT extern const char kShowCompositedLayerBorders[]; CC_BASE_EXPORT extern const char kUIShowCompositedLayerBorders[];
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc b/cc/raster/categorized_worker_pool.cc similarity index 77% rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc rename to cc/raster/categorized_worker_pool.cc index 2d2bd97..4a4af53 100644 --- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc +++ b/cc/raster/categorized_worker_pool.cc
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h" +#include "cc/raster/categorized_worker_pool.h" +#include <algorithm> +#include <memory> #include <string> #include <utility> @@ -12,6 +14,7 @@ #include "base/containers/cxx20_erase.h" #include "base/feature_list.h" #include "base/functional/bind.h" +#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/task/sequence_manager/task_time_observer.h" @@ -23,14 +26,10 @@ #include "base/trace_event/typed_macros.h" #include "build/build_config.h" #include "cc/base/math_util.h" +#include "cc/base/switches.h" #include "cc/raster/task_category.h" -#include "third_party/blink/public/common/switches.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/platform/scheduler/public/main_thread.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" -namespace blink { +namespace cc { namespace { BASE_FEATURE(kUseCompositorJob, @@ -38,24 +37,24 @@ base::FEATURE_ENABLED_BY_DEFAULT); // Task categories running at normal thread priority. -constexpr cc::TaskCategory kNormalThreadPriorityCategories[] = { - cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND, cc::TASK_CATEGORY_FOREGROUND, - cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY}; +constexpr TaskCategory kNormalThreadPriorityCategories[] = { + TASK_CATEGORY_NONCONCURRENT_FOREGROUND, TASK_CATEGORY_FOREGROUND, + TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY}; // Task categories running at background thread priority. -constexpr cc::TaskCategory kBackgroundThreadPriorityCategories[] = { - cc::TASK_CATEGORY_BACKGROUND}; +constexpr TaskCategory kBackgroundThreadPriorityCategories[] = { + TASK_CATEGORY_BACKGROUND}; // Foreground task categories. -constexpr cc::TaskCategory kForegroundCategories[] = { - cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND, cc::TASK_CATEGORY_FOREGROUND}; +constexpr TaskCategory kForegroundCategories[] = { + TASK_CATEGORY_NONCONCURRENT_FOREGROUND, TASK_CATEGORY_FOREGROUND}; // Background task categories. Tasks in these categories cannot start running // when a task with a category in |kForegroundCategories| is running or ready to // run. -constexpr cc::TaskCategory kBackgroundCategories[] = { - cc::TASK_CATEGORY_BACKGROUND, - cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY}; +constexpr TaskCategory kBackgroundCategories[] = { + TASK_CATEGORY_BACKGROUND, + TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY}; // A thread which forwards to CategorizedWorkerPool::Run with the runnable // categories. @@ -65,45 +64,30 @@ const std::string& name_prefix, const Options& options, CategorizedWorkerPoolImpl* pool, - std::vector<cc::TaskCategory> categories, + std::vector<TaskCategory> categories, base::ConditionVariable* has_ready_to_run_tasks_cv) : SimpleThread(name_prefix, options), pool_(pool), categories_(categories), has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} - void SetBackgroundingCallback( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - base::OnceCallback<void(base::PlatformThreadId)> callback) { - DCHECK(!HasStartBeenAttempted()); - background_task_runner_ = std::move(task_runner); - backgrounding_callback_ = std::move(callback); - } - // base::SimpleThread: - void BeforeRun() override { - if (backgrounding_callback_) { - DCHECK(background_task_runner_); - background_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(backgrounding_callback_), tid())); - background_task_runner_.reset(); - } - } + void BeforeRun() override { pool_->ThreadWillRun(tid()); } void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } private: - CategorizedWorkerPoolImpl* const pool_; - const Vector<cc::TaskCategory> categories_; - base::ConditionVariable* const has_ready_to_run_tasks_cv_; + const raw_ptr<CategorizedWorkerPoolImpl> pool_; + const std::vector<TaskCategory> categories_; + const raw_ptr<base::ConditionVariable> has_ready_to_run_tasks_cv_; base::OnceCallback<void(base::PlatformThreadId)> backgrounding_callback_; scoped_refptr<base::SingleThreadTaskRunner> background_task_runner_; }; scoped_refptr<CategorizedWorkerPool>& GetWorkerPool() { - DEFINE_STATIC_LOCAL(scoped_refptr<CategorizedWorkerPool>, worker_pool, ()); - return worker_pool; + static base::NoDestructor<scoped_refptr<CategorizedWorkerPool>> worker_pool; + return *worker_pool; } } // namespace @@ -113,7 +97,7 @@ : public base::SequencedTaskRunner { public: explicit CategorizedWorkerPoolSequencedTaskRunner( - cc::TaskGraphRunner* task_graph_runner) + TaskGraphRunner* task_graph_runner) : task_graph_runner_(task_graph_runner), namespace_token_(task_graph_runner->GenerateNamespaceToken()) {} @@ -144,17 +128,18 @@ graph_.Reset(); for (const auto& graph_task : tasks_) { int dependencies = 0; - if (!graph_.nodes.empty()) + if (!graph_.nodes.empty()) { dependencies = 1; + } // Treat any tasks that are enqueued through the SequencedTaskRunner as // FOREGROUND priority. We don't have enough information to know the // actual priority of such tasks, so we run them as soon as possible. - cc::TaskGraph::Node node(graph_task, cc::TASK_CATEGORY_FOREGROUND, - 0u /* priority */, dependencies); + TaskGraph::Node node(graph_task, TASK_CATEGORY_FOREGROUND, + 0u /* priority */, dependencies); if (dependencies) { - graph_.edges.push_back(cc::TaskGraph::Edge( - graph_.nodes.back().task.get(), node.task.get())); + graph_.edges.push_back( + TaskGraph::Edge(graph_.nodes.back().task.get(), node.task.get())); } graph_.nodes.push_back(std::move(node)); } @@ -179,20 +164,21 @@ // implement the SequencedTaskRunner interfaces. base::Lock lock_; - cc::TaskGraphRunner* task_graph_runner_; + raw_ptr<TaskGraphRunner> task_graph_runner_; // Namespace used to schedule tasks in the task graph runner. - cc::NamespaceToken namespace_token_; + NamespaceToken namespace_token_; // List of tasks currently queued up for execution. - cc::Task::Vector tasks_; + Task::Vector tasks_; // Graph object used for scheduling tasks. - cc::TaskGraph graph_; + TaskGraph graph_; // Cached vector to avoid allocation when getting the list of complete // tasks. - cc::Task::Vector completed_tasks_; + Task::Vector completed_tasks_; }; -CategorizedWorkerPoolImpl::CategorizedWorkerPoolImpl() - : has_task_for_normal_priority_thread_cv_(&lock_), +CategorizedWorkerPoolImpl::CategorizedWorkerPoolImpl(Delegate* delegate) + : delegate_(delegate), + has_task_for_normal_priority_thread_cv_(&lock_), has_task_for_background_priority_thread_cv_(&lock_), shutdown_(false) { // Declare the two ConditionVariables which are used by worker threads to @@ -208,13 +194,13 @@ // |max_concurrency_foreground| normal threads and 1 background threads are // created. - const wtf_size_t num_threads = max_concurrency_foreground + 1; + const size_t num_threads = max_concurrency_foreground + 1; threads_.reserve(num_threads); // Start |max_concurrency_foreground| normal priority threads, which run // foreground work and background work that cannot run at background thread // priority. - std::vector<cc::TaskCategory> normal_thread_prio_categories( + std::vector<TaskCategory> normal_thread_prio_categories( std::begin(kNormalThreadPriorityCategories), std::end(kNormalThreadPriorityCategories)); @@ -228,7 +214,7 @@ } // Start a single thread running at background thread priority. - std::vector<cc::TaskCategory> background_thread_prio_categories{ + std::vector<TaskCategory> background_thread_prio_categories{ std::begin(kBackgroundThreadPriorityCategories), std::end(kBackgroundThreadPriorityCategories)}; @@ -242,15 +228,6 @@ "CompositorTileWorkerBackground", thread_options, this, background_thread_prio_categories, &has_task_for_background_priority_thread_cv_); -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - thread->SetBackgroundingCallback( - Thread::MainThread()->GetTaskRunner(MainThreadTaskRunnerRestricted()), - base::BindOnce([](base::PlatformThreadId thread_id) { - Platform::Current()->SetThreadType(thread_id, - base::ThreadType::kBackground); - })); -#endif - thread->StartAsync(); threads_.push_back(std::move(thread)); @@ -284,6 +261,12 @@ } } +void CategorizedWorkerPoolImpl::ThreadWillRun(base::PlatformThreadId tid) { + if (delegate_) { + delegate_->NotifyThreadWillRun(tid); + } +} + // Overridden from base::TaskRunner: bool CategorizedWorkerPoolImpl::PostDelayedTask(const base::Location& from_here, base::OnceClosure task, @@ -294,7 +277,7 @@ DCHECK(completed_tasks_.empty()); CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_); - base::EraseIf(tasks_, [this](const scoped_refptr<cc::Task>& e) + base::EraseIf(tasks_, [this](const scoped_refptr<Task>& e) EXCLUSIVE_LOCKS_REQUIRED(lock_) { return base::Contains(this->completed_tasks_, e); }); @@ -305,8 +288,8 @@ // Delayed tasks are assigned FOREGROUND category, ensuring that they run as // soon as possible once their delay has expired. graph_.nodes.push_back( - cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, - 0u /* priority */, 0u /* dependencies */)); + TaskGraph::Node(graph_task.get(), TASK_CATEGORY_FOREGROUND, + 0u /* priority */, 0u /* dependencies */)); } ScheduleTasksWithLockAcquired(namespace_token_, &graph_); @@ -315,7 +298,7 @@ } void CategorizedWorkerPoolImpl::Run( - const Vector<cc::TaskCategory>& categories, + const std::vector<TaskCategory>& categories, base::ConditionVariable* has_ready_to_run_tasks_cv) { base::AutoLock lock(lock_); @@ -331,8 +314,9 @@ PERFETTO_INTERNAL_ADD_EMPTY_EVENT(); // Exit when shutdown is set and no more tasks are pending. - if (shutdown_) + if (shutdown_) { break; + } // Wait for more tasks. has_ready_to_run_tasks_cv->Wait(); @@ -349,8 +333,8 @@ } } -void CategorizedWorkerPoolImpl::ScheduleTasks(cc::NamespaceToken token, - cc::TaskGraph* graph) { +void CategorizedWorkerPoolImpl::ScheduleTasks(NamespaceToken token, + TaskGraph* graph) { TRACE_EVENT2("disabled-by-default-cc.debug", "CategorizedWorkerPool::ScheduleTasks", "num_nodes", graph->nodes.size(), "num_edges", graph->edges.size()); @@ -361,10 +345,10 @@ } void CategorizedWorkerPoolImpl::ScheduleTasksWithLockAcquired( - cc::NamespaceToken token, - cc::TaskGraph* graph) { + NamespaceToken token, + TaskGraph* graph) { DCHECK(token.IsValid()); - DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); + DCHECK(!TaskGraphWorkQueue::DependencyMismatch(graph)); DCHECK(!shutdown_); work_queue_.ScheduleTasks(token, graph); @@ -374,7 +358,7 @@ } bool CategorizedWorkerPoolImpl::RunTaskWithLockAcquired( - const Vector<cc::TaskCategory>& categories) { + const std::vector<TaskCategory>& categories) { for (const auto& category : categories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { RunTaskInCategoryWithLockAcquired(category); @@ -385,7 +369,7 @@ } void CategorizedWorkerPoolImpl::RunTaskInCategoryWithLockAcquired( - cc::TaskCategory category) { + TaskCategory category) { lock_.AssertAcquired(); auto prioritized_task = work_queue_.GetNextTaskToRun(category); @@ -408,14 +392,15 @@ work_queue_.CompleteTask(std::move(prioritized_task)); // If namespace has finished running all tasks, wake up origin threads. - if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) + if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) { has_namespaces_with_finished_running_tasks_cv_.Signal(); + } } void CategorizedWorkerPoolImpl::SignalHasReadyToRunTasksWithLockAcquired() { lock_.AssertAcquired(); - for (cc::TaskCategory category : kNormalThreadPriorityCategories) { + for (TaskCategory category : kNormalThreadPriorityCategories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { has_task_for_normal_priority_thread_cv_.Signal(); return; @@ -424,7 +409,7 @@ // Due to the early return in the previous loop, this only runs when there are // no tasks to run on normal priority threads. - for (cc::TaskCategory category : kBackgroundThreadPriorityCategories) { + for (TaskCategory category : kBackgroundThreadPriorityCategories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { has_task_for_background_priority_thread_cv_.Signal(); return; @@ -441,10 +426,9 @@ FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::ThreadPolicy::PREFER_BACKGROUND, base::MayBlock()}, - base::BindRepeating(&CategorizedWorkerPoolJob::Run, - base::Unretained(this), - base::span<const cc::TaskCategory>( - kBackgroundThreadPriorityCategories)), + base::BindRepeating( + &CategorizedWorkerPoolJob::Run, base::Unretained(this), + base::span<const TaskCategory>(kBackgroundThreadPriorityCategories)), base::BindRepeating( [](CategorizedWorkerPoolJob* self, size_t) { return std::min<size_t>(1U, @@ -456,7 +440,7 @@ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, base::BindRepeating( &CategorizedWorkerPoolJob::Run, base::Unretained(this), - base::span<const cc::TaskCategory>(kNormalThreadPriorityCategories)), + base::span<const TaskCategory>(kNormalThreadPriorityCategories)), base::BindRepeating( [](CategorizedWorkerPoolJob* self, size_t) { return std::min( @@ -480,10 +464,12 @@ DCHECK(!work_queue_.HasReadyToRunTasks()); DCHECK(!work_queue_.HasAnyNamespaces()); } - if (foreground_job_handle_) + if (foreground_job_handle_) { foreground_job_handle_.Cancel(); - if (background_job_handle_) + } + if (background_job_handle_) { background_job_handle_.Cancel(); + } } // Overridden from base::TaskRunner: @@ -499,7 +485,7 @@ CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_); base::EraseIf(tasks_, - [this](const scoped_refptr<cc::Task>& e) + [this](const scoped_refptr<Task>& e) EXCLUSIVE_LOCKS_REQUIRED(lock_) { return base::Contains(this->completed_tasks_, e); }); @@ -510,23 +496,23 @@ // Delayed tasks are assigned FOREGROUND category, ensuring that they run // as soon as possible once their delay has expired. graph_.nodes.push_back( - cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, - 0u /* priority */, 0u /* dependencies */)); + TaskGraph::Node(graph_task.get(), TASK_CATEGORY_FOREGROUND, + 0u /* priority */, 0u /* dependencies */)); } job_handle_to_notify = ScheduleTasksWithLockAcquired(namespace_token_, &graph_); completed_tasks_.clear(); } - if (job_handle_to_notify) + if (job_handle_to_notify) { job_handle_to_notify->NotifyConcurrencyIncrease(); + } return true; } -void CategorizedWorkerPoolJob::Run( - base::span<const cc::TaskCategory> categories, - base::JobDelegate* job_delegate) { - absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask> prioritized_task; +void CategorizedWorkerPoolJob::Run(base::span<const TaskCategory> categories, + base::JobDelegate* job_delegate) { + absl::optional<TaskGraphWorkQueue::PrioritizedTask> prioritized_task; while (!job_delegate->ShouldYield()) { base::JobHandle* job_handle_to_notify = nullptr; @@ -541,12 +527,14 @@ ScheduleTasksWithLockAcquired(namespace_token_, &graph_); } } - if (job_handle_to_notify) + if (job_handle_to_notify) { job_handle_to_notify->NotifyConcurrencyIncrease(); + } // There's no pending task to run, quit the worker until notified again. - if (!prioritized_task) + if (!prioritized_task) { return; + } TRACE_EVENT( "toplevel", "TaskGraphRunner::RunTask", [&](perfetto::EventContext ctx) { @@ -565,15 +553,16 @@ work_queue_.CompleteTask(std::move(*prioritized_task)); // If namespace has finished running all tasks, wake up origin threads. - if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) + if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) { has_namespaces_with_finished_running_tasks_cv_.Signal(); + } } } } -absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask> +absl::optional<TaskGraphWorkQueue::PrioritizedTask> CategorizedWorkerPoolJob::GetNextTaskToRunWithLockAcquired( - base::span<const cc::TaskCategory> categories) { + base::span<const TaskCategory> categories) { lock_.AssertAcquired(); for (const auto& category : categories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { @@ -588,8 +577,8 @@ background_job_handle_.Join(); } -void CategorizedWorkerPoolJob::ScheduleTasks(cc::NamespaceToken token, - cc::TaskGraph* graph) { +void CategorizedWorkerPoolJob::ScheduleTasks(NamespaceToken token, + TaskGraph* graph) { TRACE_EVENT2("disabled-by-default-cc.debug", "CategorizedWorkerPool::ScheduleTasks", "num_nodes", graph->nodes.size(), "num_edges", graph->edges.size()); @@ -598,15 +587,16 @@ base::AutoLock lock(lock_); job_handle_to_notify = ScheduleTasksWithLockAcquired(token, graph); } - if (job_handle_to_notify) + if (job_handle_to_notify) { job_handle_to_notify->NotifyConcurrencyIncrease(); + } } base::JobHandle* CategorizedWorkerPoolJob::ScheduleTasksWithLockAcquired( - cc::NamespaceToken token, - cc::TaskGraph* graph) { + NamespaceToken token, + TaskGraph* graph) { DCHECK(token.IsValid()); - DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); + DCHECK(!TaskGraphWorkQueue::DependencyMismatch(graph)); work_queue_.ScheduleTasks(token, graph); return GetJobHandleToNotifyWithLockAcquired(); @@ -616,7 +606,7 @@ CategorizedWorkerPoolJob::GetJobHandleToNotifyWithLockAcquired() { lock_.AssertAcquired(); - for (cc::TaskCategory category : kNormalThreadPriorityCategories) { + for (TaskCategory category : kNormalThreadPriorityCategories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { return &foreground_job_handle_; } @@ -624,7 +614,7 @@ // Due to the early return in the previous loop, this only runs when there are // no tasks to run on normal priority threads. - for (cc::TaskCategory category : kBackgroundThreadPriorityCategories) { + for (TaskCategory category : kBackgroundThreadPriorityCategories) { if (ShouldRunTaskForCategoryWithLockAcquired(category)) { return &background_job_handle_; } @@ -633,11 +623,11 @@ } size_t CategorizedWorkerPoolJob::GetMaxJobConcurrency( - base::span<const cc::TaskCategory> categories) const { + base::span<const TaskCategory> categories) const { base::AutoLock lock(lock_); bool has_foreground_tasks = false; - for (cc::TaskCategory foreground_category : kForegroundCategories) { + for (TaskCategory foreground_category : kForegroundCategories) { if (work_queue_.NumRunningTasksForCategory(foreground_category) > 0 || work_queue_.HasReadyToRunTasksForCategory(foreground_category)) { has_foreground_tasks = true; @@ -646,28 +636,30 @@ } bool has_running_background_tasks = false; - for (cc::TaskCategory background_category : kBackgroundCategories) { + for (TaskCategory background_category : kBackgroundCategories) { has_running_background_tasks |= work_queue_.NumRunningTasksForCategory(background_category); } size_t num_foreground_tasks = 0; size_t num_background_tasks = 0; - for (cc::TaskCategory category : categories) { + for (TaskCategory category : categories) { if (base::Contains(kBackgroundCategories, category)) { - if (work_queue_.NumRunningTasksForCategory(category) > 0) + if (work_queue_.NumRunningTasksForCategory(category) > 0) { num_background_tasks = 1; + } // Enforce that only one background task is allowed to run at a time, and // only if there are no foreground tasks running or ready to run. if (!has_running_background_tasks && !has_foreground_tasks && work_queue_.HasReadyToRunTasksForCategory(category)) { num_background_tasks = 1; } - } else if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) { + } else if (category == TASK_CATEGORY_NONCONCURRENT_FOREGROUND) { // Enforce that only one nonconcurrent task is allowed to run at a time. if (work_queue_.NumRunningTasksForCategory(category) > 0 || - work_queue_.HasReadyToRunTasksForCategory(category)) + work_queue_.HasReadyToRunTasksForCategory(category)) { ++num_foreground_tasks; + } } else { num_foreground_tasks += work_queue_.NumRunningTasksForCategory(category) + work_queue_.NumReadyTasksForCategory(category); @@ -676,9 +668,10 @@ return num_foreground_tasks + num_background_tasks; } -CategorizedWorkerPool* CategorizedWorkerPool::GetOrCreate() { - if (GetWorkerPool()) +CategorizedWorkerPool* CategorizedWorkerPool::GetOrCreate(Delegate* delegate) { + if (GetWorkerPool()) { return GetWorkerPool().get(); + } const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); @@ -696,7 +689,7 @@ base::FeatureList::IsEnabled(kUseCompositorJob) ? scoped_refptr<CategorizedWorkerPool>(new CategorizedWorkerPoolJob()) : scoped_refptr<CategorizedWorkerPool>( - new CategorizedWorkerPoolImpl()); + new CategorizedWorkerPoolImpl(delegate)); categorized_worker_pool->Start(num_raster_threads); GetWorkerPool() = std::move(categorized_worker_pool); return GetWorkerPool().get(); @@ -713,13 +706,12 @@ CategorizedWorkerPool::~CategorizedWorkerPool() = default; -cc::NamespaceToken CategorizedWorkerPool::GenerateNamespaceToken() { +NamespaceToken CategorizedWorkerPool::GenerateNamespaceToken() { base::AutoLock lock(lock_); return work_queue_.GenerateNamespaceToken(); } -void CategorizedWorkerPool::WaitForTasksToFinishRunning( - cc::NamespaceToken token) { +void CategorizedWorkerPool::WaitForTasksToFinishRunning(NamespaceToken token) { TRACE_EVENT0("disabled-by-default-cc.debug", "CategorizedWorkerPool::WaitForTasksToFinishRunning"); @@ -730,11 +722,13 @@ auto* task_namespace = work_queue_.GetNamespaceForToken(token); - if (!task_namespace) + if (!task_namespace) { return; + } - while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) + while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) { has_namespaces_with_finished_running_tasks_cv_.Wait(); + } // There may be other namespaces that have finished running tasks, so wake // up another origin thread. @@ -743,8 +737,8 @@ } void CategorizedWorkerPool::CollectCompletedTasks( - cc::NamespaceToken token, - cc::Task::Vector* completed_tasks) { + NamespaceToken token, + Task::Vector* completed_tasks) { TRACE_EVENT0("disabled-by-default-cc.debug", "CategorizedWorkerPool::CollectCompletedTasks"); @@ -755,23 +749,24 @@ } void CategorizedWorkerPool::CollectCompletedTasksWithLockAcquired( - cc::NamespaceToken token, - cc::Task::Vector* completed_tasks) { + NamespaceToken token, + Task::Vector* completed_tasks) { DCHECK(token.IsValid()); work_queue_.CollectCompletedTasks(token, completed_tasks); } bool CategorizedWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( - cc::TaskCategory category) { + TaskCategory category) { lock_.AssertAcquired(); - if (!work_queue_.HasReadyToRunTasksForCategory(category)) + if (!work_queue_.HasReadyToRunTasksForCategory(category)) { return false; + } if (base::Contains(kBackgroundCategories, category)) { // Only run background tasks if there are no foreground tasks running or // ready to run. - for (cc::TaskCategory foreground_category : kForegroundCategories) { + for (TaskCategory foreground_category : kForegroundCategories) { if (work_queue_.NumRunningTasksForCategory(foreground_category) > 0 || work_queue_.HasReadyToRunTasksForCategory(foreground_category)) { return false; @@ -779,16 +774,17 @@ } // Enforce that only one background task runs at a time. - for (cc::TaskCategory background_category : kBackgroundCategories) { - if (work_queue_.NumRunningTasksForCategory(background_category) > 0) + for (TaskCategory background_category : kBackgroundCategories) { + if (work_queue_.NumRunningTasksForCategory(background_category) > 0) { return false; + } } } // Enforce that only one nonconcurrent task runs at a time. - if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND && + if (category == TASK_CATEGORY_NONCONCURRENT_FOREGROUND && work_queue_.NumRunningTasksForCategory( - cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) { + TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) { return false; } @@ -798,11 +794,11 @@ CategorizedWorkerPool::ClosureTask::ClosureTask(base::OnceClosure closure) : closure_(std::move(closure)) {} -// Overridden from cc::Task: +// Overridden from Task: void CategorizedWorkerPool::ClosureTask::RunOnWorkerThread() { std::move(closure_).Run(); } CategorizedWorkerPool::ClosureTask::~ClosureTask() {} -} // namespace blink +} // namespace cc
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h b/cc/raster/categorized_worker_pool.h similarity index 65% rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h rename to cc/raster/categorized_worker_pool.h index 3a1bc24..3334497e 100644 --- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h +++ b/cc/raster/categorized_worker_pool.h
@@ -2,25 +2,29 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_ +#ifndef CC_RASTER_CATEGORIZED_WORKER_POOL_H_ +#define CC_RASTER_CATEGORIZED_WORKER_POOL_H_ + +#include <memory> +#include <vector> #include "base/containers/span.h" #include "base/functional/callback.h" +#include "base/memory/raw_ptr.h" #include "base/synchronization/condition_variable.h" #include "base/task/post_job.h" #include "base/task/sequenced_task_runner.h" #include "base/task/task_runner.h" #include "base/thread_annotations.h" +#include "base/threading/platform_thread.h" #include "base/threading/simple_thread.h" +#include "cc/cc_export.h" #include "cc/raster/task_category.h" #include "cc/raster/task_graph_runner.h" #include "cc/raster/task_graph_work_queue.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" -namespace blink { +namespace cc { // A pool of threads used to run categorized work. The work can be scheduled on // the threads using different interfaces. @@ -30,20 +34,29 @@ // schedule a graph of tasks with their dependencies. // 3. CreateSequencedTaskRunner() creates a sequenced task runner that might run // in parallel with other instances of sequenced task runners. -class PLATFORM_EXPORT CategorizedWorkerPool : public base::TaskRunner, - public cc::TaskGraphRunner { +class CC_EXPORT CategorizedWorkerPool : public base::TaskRunner, + public TaskGraphRunner { public: + class CC_EXPORT Delegate { + public: + virtual ~Delegate() = default; + + // Called on the delegate with a worker pool thread ID as soon as the + // thread is created. + virtual void NotifyThreadWillRun(base::PlatformThreadId tid) = 0; + }; + CategorizedWorkerPool(); - ~CategorizedWorkerPool() override; - // Get or create the singleton worker pool. - static CategorizedWorkerPool* GetOrCreate(); + // Get or create the singleton worker pool. This object lives forever. If + // `delegate` is non-null, it must also live forever. + static CategorizedWorkerPool* GetOrCreate(Delegate* delegate = nullptr); - // Overridden from cc::TaskGraphRunner: - cc::NamespaceToken GenerateNamespaceToken() override; - void WaitForTasksToFinishRunning(cc::NamespaceToken token) override; - void CollectCompletedTasks(cc::NamespaceToken token, - cc::Task::Vector* completed_tasks) override; + // Overridden from TaskGraphRunner: + NamespaceToken GenerateNamespaceToken() override; + void WaitForTasksToFinishRunning(NamespaceToken token) override; + void CollectCompletedTasks(NamespaceToken token, + Task::Vector* completed_tasks) override; virtual void FlushForTesting() = 0; @@ -55,7 +68,7 @@ // terminated. virtual void Shutdown() = 0; - cc::TaskGraphRunner* GetTaskGraphRunner() { return this; } + TaskGraphRunner* GetTaskGraphRunner() { return this; } // Create a new sequenced task graph runner. scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunner(); @@ -64,17 +77,19 @@ class CategorizedWorkerPoolSequencedTaskRunner; friend class CategorizedWorkerPoolSequencedTaskRunner; + ~CategorizedWorkerPool() override; + // Simple Task for the TaskGraphRunner that wraps a closure. // This class is used to schedule TaskRunner tasks on the // |task_graph_runner_|. - class ClosureTask : public cc::Task { + class ClosureTask : public Task { public: explicit ClosureTask(base::OnceClosure closure); ClosureTask(const ClosureTask&) = delete; ClosureTask& operator=(const ClosureTask&) = delete; - // Overridden from cc::Task: + // Overridden from Task: void RunOnWorkerThread() override; protected: @@ -84,51 +99,52 @@ base::OnceClosure closure_; }; - void CollectCompletedTasksWithLockAcquired(cc::NamespaceToken token, - cc::Task::Vector* completed_tasks) + void CollectCompletedTasksWithLockAcquired(NamespaceToken token, + Task::Vector* completed_tasks) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Determines if we should run a new task for the given category. This factors // in whether a task is available and whether the count of running tasks is // low enough to start a new one. - bool ShouldRunTaskForCategoryWithLockAcquired(cc::TaskCategory category) + bool ShouldRunTaskForCategoryWithLockAcquired(TaskCategory category) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Lock to exclusively access all the following members that are used to // implement the TaskRunner and TaskGraphRunner interfaces. mutable base::Lock lock_; // Stores the tasks to be run, sorted by priority. - cc::TaskGraphWorkQueue work_queue_ GUARDED_BY(lock_); + TaskGraphWorkQueue work_queue_ GUARDED_BY(lock_); // Namespace used to schedule tasks in the task graph runner. - const cc::NamespaceToken namespace_token_; + const NamespaceToken namespace_token_; // List of tasks currently queued up for execution. - cc::Task::Vector tasks_ GUARDED_BY(lock_); + Task::Vector tasks_ GUARDED_BY(lock_); // Graph object used for scheduling tasks. - cc::TaskGraph graph_ GUARDED_BY(lock_); + TaskGraph graph_ GUARDED_BY(lock_); // Cached vector to avoid allocation when getting the list of complete // tasks. - cc::Task::Vector completed_tasks_ GUARDED_BY(lock_); + Task::Vector completed_tasks_ GUARDED_BY(lock_); // Condition variable that is waited on by origin threads until a namespace // has finished running all associated tasks. base::ConditionVariable has_namespaces_with_finished_running_tasks_cv_; }; -class PLATFORM_EXPORT CategorizedWorkerPoolImpl : public CategorizedWorkerPool { +class CC_EXPORT CategorizedWorkerPoolImpl : public CategorizedWorkerPool { public: - CategorizedWorkerPoolImpl(); - ~CategorizedWorkerPoolImpl() override; + explicit CategorizedWorkerPoolImpl(Delegate* delegate = nullptr); + + void ThreadWillRun(base::PlatformThreadId tid); // Overridden from base::TaskRunner: bool PostDelayedTask(const base::Location& from_here, base::OnceClosure task, base::TimeDelta delay) override; - // Overridden from cc::TaskGraphRunner: - void ScheduleTasks(cc::NamespaceToken token, cc::TaskGraph* graph) override; + // Overridden from TaskGraphRunner: + void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override; // Runs a task from one of the provided categories. Categories listed first // have higher priority. - void Run(const Vector<cc::TaskCategory>& categories, + void Run(const std::vector<TaskCategory>& categories, base::ConditionVariable* has_ready_to_run_tasks_cv); // Overridden from CategorizedWorkerPool: @@ -137,25 +153,28 @@ void Shutdown() override; private: - void ScheduleTasksWithLockAcquired(cc::NamespaceToken token, - cc::TaskGraph* graph) + ~CategorizedWorkerPoolImpl() override; + + void ScheduleTasksWithLockAcquired(NamespaceToken token, TaskGraph* graph) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Runs a task from one of the provided categories. Categories listed first // have higher priority. Returns false if there were no tasks to run. - bool RunTaskWithLockAcquired(const Vector<cc::TaskCategory>& categories) + bool RunTaskWithLockAcquired(const std::vector<TaskCategory>& categories) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Run next task for the given category. Caller must acquire |lock_| prior to // calling this function and make sure at least one task is ready to run. - void RunTaskInCategoryWithLockAcquired(cc::TaskCategory category) + void RunTaskInCategoryWithLockAcquired(TaskCategory category) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Helper function which signals worker threads if tasks are ready to run. void SignalHasReadyToRunTasksWithLockAcquired() EXCLUSIVE_LOCKS_REQUIRED(lock_); + const raw_ptr<Delegate> delegate_; + // The actual threads where work is done. - Vector<std::unique_ptr<base::SimpleThread>> threads_; + std::vector<std::unique_ptr<base::SimpleThread>> threads_; // Condition variables for foreground and background threads. base::ConditionVariable has_task_for_normal_priority_thread_cv_; @@ -165,22 +184,21 @@ bool shutdown_ GUARDED_BY(lock_); }; -class PLATFORM_EXPORT CategorizedWorkerPoolJob : public CategorizedWorkerPool { +class CC_EXPORT CategorizedWorkerPoolJob : public CategorizedWorkerPool { public: CategorizedWorkerPoolJob(); - ~CategorizedWorkerPoolJob() override; // Overridden from base::TaskRunner: bool PostDelayedTask(const base::Location& from_here, base::OnceClosure task, base::TimeDelta delay) override; - // Overridden from cc::TaskGraphRunner: - void ScheduleTasks(cc::NamespaceToken token, cc::TaskGraph* graph) override; + // Overridden from TaskGraphRunner: + void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override; // Runs a task from one of the provided categories. Categories listed first // have higher priority. - void Run(base::span<const cc::TaskCategory> categories, + void Run(base::span<const TaskCategory> categories, base::JobDelegate* job_delegate); // Overridden from CategorizedWorkerPool: @@ -189,20 +207,20 @@ void Shutdown() override; private: - absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask> - GetNextTaskToRunWithLockAcquired( - base::span<const cc::TaskCategory> categories); + ~CategorizedWorkerPoolJob() override; - base::JobHandle* ScheduleTasksWithLockAcquired(cc::NamespaceToken token, - cc::TaskGraph* graph) + absl::optional<TaskGraphWorkQueue::PrioritizedTask> + GetNextTaskToRunWithLockAcquired(base::span<const TaskCategory> categories); + + base::JobHandle* ScheduleTasksWithLockAcquired(NamespaceToken token, + TaskGraph* graph) EXCLUSIVE_LOCKS_REQUIRED(lock_); // Helper function which signals worker threads if tasks are ready to run. base::JobHandle* GetJobHandleToNotifyWithLockAcquired() EXCLUSIVE_LOCKS_REQUIRED(lock_); - size_t GetMaxJobConcurrency( - base::span<const cc::TaskCategory> categories) const; + size_t GetMaxJobConcurrency(base::span<const TaskCategory> categories) const; size_t max_concurrency_foreground_ = 0; @@ -210,6 +228,6 @@ base::JobHandle foreground_job_handle_; }; -} // namespace blink +} // namespace cc -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_ +#endif // CC_RASTER_CATEGORIZED_WORKER_POOL_H_
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc b/cc/raster/categorized_worker_pool_unittest.cc similarity index 68% rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc rename to cc/raster/categorized_worker_pool_unittest.cc index fa6d1f0..b54bc123 100644 --- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc +++ b/cc/raster/categorized_worker_pool_unittest.cc
@@ -2,18 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h" +#include "cc/raster/categorized_worker_pool.h" + +#include <utility> + +#include "base/functional/callback.h" #include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" #include "base/test/sequenced_task_runner_test_template.h" -#include "base/test/task_environment.h" #include "base/test/task_runner_test_template.h" #include "base/threading/platform_thread.h" #include "base/threading/simple_thread.h" #include "cc/test/task_graph_runner_test_template.h" -#include "third_party/blink/public/platform/platform.h" -namespace blink { +namespace cc { namespace { // Number of threads spawned in tests. @@ -35,7 +37,6 @@ ~CategorizedWorkerPoolTestDelegate() { categorized_worker_pool_->Shutdown(); } private: - base::test::TaskEnvironment task_environment_; scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ = base::MakeRefCounted<T>(); }; @@ -58,7 +59,6 @@ } private: - base::test::TaskEnvironment task_environment_; scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ = base::MakeRefCounted<T>(); }; @@ -70,7 +70,7 @@ void StartTaskGraphRunner() { categorized_worker_pool_->Start(kNumThreads); } - cc::TaskGraphRunner* GetTaskGraphRunner() { + TaskGraphRunner* GetTaskGraphRunner() { return categorized_worker_pool_->GetTaskGraphRunner(); } @@ -81,7 +81,6 @@ } private: - base::test::TaskEnvironment task_environment_; scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ = base::MakeRefCounted<T>(); }; @@ -102,18 +101,17 @@ } void TearDown() override { - cc::Task::Vector completed_tasks; + Task::Vector completed_tasks; categorized_worker_pool_->CollectCompletedTasks(namespace_token_, &completed_tasks); categorized_worker_pool_->Shutdown(); } - base::test::TaskEnvironment task_environment_; scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_; - cc::NamespaceToken namespace_token_; + NamespaceToken namespace_token_; }; -class ClosureTask : public cc::Task { +class ClosureTask : public Task { public: explicit ClosureTask(base::OnceClosure closure) : closure_(std::move(closure)) {} @@ -121,7 +119,7 @@ ClosureTask(const ClosureTask&) = delete; ClosureTask& operator=(const ClosureTask&) = delete; - // Overridden from cc::Task: + // Overridden from Task: void RunOnWorkerThread() override { std::move(closure_).Run(); } protected: @@ -137,8 +135,8 @@ // TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY don't run // concurrently. TEST_P(CategorizedWorkerPoolTest, BackgroundTasksDontRunConcurrently) { - cc::Task::Vector tasks; - cc::TaskGraph graph; + Task::Vector tasks; + TaskGraph graph; bool is_running_task = false; for (size_t i = 0; i < 100; ++i) { @@ -152,10 +150,10 @@ is_running_task = false; }))); - graph.nodes.push_back(cc::TaskGraph::Node( + graph.nodes.push_back(TaskGraph::Node( tasks.back(), - i % 2 == 0 ? cc::TASK_CATEGORY_BACKGROUND - : cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY, + i % 2 == 0 ? TASK_CATEGORY_BACKGROUND + : TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY, /* priority=*/0u, /* dependencies=*/0u)); } @@ -168,15 +166,15 @@ // doesn't run at background thread priority. TEST_P(CategorizedWorkerPoolTest, AcquiresForegroundResourcesNotBackgroundThreadPriority) { - cc::Task::Vector tasks; - cc::TaskGraph graph; + Task::Vector tasks; + TaskGraph graph; tasks.push_back(base::MakeRefCounted<ClosureTask>(base::BindOnce([]() { EXPECT_NE(base::ThreadType::kBackground, base::PlatformThread::GetCurrentThreadType()); }))); - graph.nodes.push_back(cc::TaskGraph::Node( - tasks.back(), cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY, + graph.nodes.push_back(TaskGraph::Node( + tasks.back(), TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY, /* priority=*/0u, /* dependencies=*/0u)); categorized_worker_pool_->ScheduleTasks(namespace_token_, &graph); @@ -188,7 +186,7 @@ CategorizedWorkerPoolTest, testing::Values(false, true)); -} // namespace blink +} // namespace cc // Test suite instantiation needs to be in the same namespace as test suite // definition. @@ -198,22 +196,20 @@ INSTANTIATE_TYPED_TEST_SUITE_P( CategorizedWorkerPoolImpl, TaskRunnerTest, - blink::CategorizedWorkerPoolTestDelegate<blink::CategorizedWorkerPoolImpl>); + cc::CategorizedWorkerPoolTestDelegate<cc::CategorizedWorkerPoolImpl>); INSTANTIATE_TYPED_TEST_SUITE_P( CategorizedWorkerPoolJob, TaskRunnerTest, - blink::CategorizedWorkerPoolTestDelegate<blink::CategorizedWorkerPoolJob>); + cc::CategorizedWorkerPoolTestDelegate<cc::CategorizedWorkerPoolJob>); -INSTANTIATE_TYPED_TEST_SUITE_P( - CategorizedWorkerPoolImpl, - SequencedTaskRunnerTest, - blink::CategorizedWorkerPoolSequencedTestDelegate< - blink::CategorizedWorkerPoolImpl>); -INSTANTIATE_TYPED_TEST_SUITE_P( - CategorizedWorkerPoolJob, - SequencedTaskRunnerTest, - blink::CategorizedWorkerPoolSequencedTestDelegate< - blink::CategorizedWorkerPoolJob>); +INSTANTIATE_TYPED_TEST_SUITE_P(CategorizedWorkerPoolImpl, + SequencedTaskRunnerTest, + cc::CategorizedWorkerPoolSequencedTestDelegate< + cc::CategorizedWorkerPoolImpl>); +INSTANTIATE_TYPED_TEST_SUITE_P(CategorizedWorkerPoolJob, + SequencedTaskRunnerTest, + cc::CategorizedWorkerPoolSequencedTestDelegate< + cc::CategorizedWorkerPoolJob>); } // namespace base @@ -221,20 +217,20 @@ // Multithreaded tests. using CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate_1_5 = - ::testing::Types<blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, + ::testing::Types<CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolImpl, 1>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolImpl, 2>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolImpl, 3>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolImpl, 4>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolImpl, 5>>; INSTANTIATE_TYPED_TEST_SUITE_P( @@ -242,20 +238,20 @@ TaskGraphRunnerTest, CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate_1_5); using CategorizedWorkerPoolJobTaskGraphRunnerTestDelegate_1_5 = - ::testing::Types<blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, + ::testing::Types<CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolJob, 1>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolJob, 2>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolJob, 3>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolJob, 4>, - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, + CategorizedWorkerPoolTaskGraphRunnerTestDelegate< + CategorizedWorkerPoolJob, 5>>; INSTANTIATE_TYPED_TEST_SUITE_P( CategorizedWorkerPoolJob_1_5_Threads, @@ -264,17 +260,15 @@ // Single threaded tests. using CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate = - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolImpl, - 1>; + CategorizedWorkerPoolTaskGraphRunnerTestDelegate<CategorizedWorkerPoolImpl, + 1>; INSTANTIATE_TYPED_TEST_SUITE_P( CategorizedWorkerPoolImpl, SingleThreadTaskGraphRunnerTest, CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate); using CategorizedWorkerPoolJobTaskGraphRunnerTestDelegate = - blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate< - blink::CategorizedWorkerPoolJob, - 1>; + CategorizedWorkerPoolTaskGraphRunnerTestDelegate<CategorizedWorkerPoolJob, + 1>; INSTANTIATE_TYPED_TEST_SUITE_P( CategorizedWorkerPoolJob, SingleThreadTaskGraphRunnerTest,
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index b0110cee..d7b49d2 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2352,6 +2352,50 @@ ] } + # Defines a target that derives from the chrome public application. This + # can be either an APK or an app bundle module. This supports + # chrome_public_xxx targets (for Android L-M). For Android N+, see instead + # monochrome_public_apk_or_module_tmpl() below. + # + # Variables: + # target_type: Determines the final target type. Should be one of + # 'android_apk', or 'android_app_bundle_module'. + # apk_name: For 'android_apk' target types, name of the final APK without + # an .apk suffix (e.g. 'ChromePublic'). + # is_base_module: For 'android_app_bundle_module' target types only, + # set to true to indicate that this is a base application module + # (instead of a feature module). + template("chrome_public_apk_or_module_tmpl") { + _is_bundle_module = invoker.target_type == "android_app_bundle_module" + chrome_public_common_apk_or_module_tmpl(target_name) { + forward_variables_from(invoker, + [ + "add_view_trace_events", + "apk_name", + "bundle_target", + "is_base_module", + "target_type", + "enable_lint", + "enable_multidex", + "lint_baseline_file", + "lint_suppressions_dep", + "lint_suppressions_file", + "manual_jni_registration", + ]) + deps = chrome_public_shared_deps + + if (_is_bundle_module) { + deps += [ ":chrome_bundle_module_pak_assets" ] + } else { + deps += [ ":chrome_apk_pak_assets" ] + } + + shared_libraries = [ ":libchrome" ] + + version_name = chrome_version_name + } + } + chrome_public_apk_or_module_tmpl("chrome_public_apk") { target_type = "android_apk" apk_name = "ChromePublic" @@ -2504,6 +2548,83 @@ annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } + # Defines a target that derives from the monochrome public application. This + # can be either an APK or an app bundle module. Note that these only work + # on Android N+ devices, see chrome_public_apk_or_module_tmpl() for a template + # that supports generating targets for older Android releases. + # + # Variables: + # target_type: Either 'android_apk' or 'android_app_bundle_module'. + # apk_name: For APK target types, the final APK name without an .apk + # suffix (e.g. "MonochromePublic"). + # is_base_module: For module target types, a boolean indicating whether + # this is a base bundle module (instead of a feature one). + # is_64_bit_browser: When compiling in a 64-bit configuration, a boolean + # indicating whether the browser is 64-bit or 32-bit. + # include_32_bit_webview: When compiling a 64-bit browser configuration, if + # true, a 32-bit WebView library will also be built and included. + template("monochrome_public_apk_or_module_tmpl") { + _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome + _is_bundle = invoker.target_type == "android_app_bundle_module" + + monochrome_public_common_apk_or_module_tmpl(target_name) { + forward_variables_from(invoker, + [ + "add_view_trace_events", + "apk_name", + "bundle_target", + "expected_android_manifest", + "include_32_bit_webview", + "include_64_bit_webview", + "is_64_bit_browser", + "is_base_module", + "is_trichrome", + "resource_ids_provider_dep", + "static_library_provider", + "target_type", + "use_chromium_linker", + ]) + + if (!_is_trichrome) { + # Resource allowlist used when generating R.java files and causes + # only the webview subset of resources to be marked as non-final. + # Strings in this target will also be kept in the base apk rather than placed in the language splits. + shared_resources_allowlist_target = + "//android_webview:system_webview_no_weblayer_apk" + + # Ensure the localized resources for all locales are used, even when + # a smaller set is specified through aapt_locale_allowlist. + shared_resources_allowlist_locales = platform_pak_locales + } + + deps = [] + if (_is_bundle) { + deps += [ + "//chrome/android:chrome_base_module_resources", + + # deps in delegate_public_impl_java are put into the Chrome module, but the language deps + # are needed by the base module. + "//components/language/android:ulp_delegate_public_java", + ] + } else { + deps += [ ":delegate_public_impl_java" ] + } + if (!_is_trichrome) { + deps += [ + "//android_webview:platform_service_bridge_upstream_implementation_java", + "//android_webview/nonembedded:icon_resources", + "//android_webview/nonembedded:monochrome_devui_launcher_icon_resources", + ] + if (!_is_bundle) { + deps += [ ":monochrome_java" ] + } + if (webview_includes_weblayer) { + deps += [ "//weblayer/browser/java:upstream_java" ] + } + } + } + } + if (android_64bit_target_cpu && skip_secondary_abi_for_cq) { group("trichrome_library_apk") { deps = [ ":trichrome_library_64_apk" ] @@ -2512,8 +2633,7 @@ deps = [ ":monochrome_64_public_apk" ] } } else { - chrome_public_apk_or_module_tmpl("monochrome_public_apk") { - is_monochrome = true + monochrome_public_apk_or_module_tmpl("monochrome_public_apk") { apk_name = "MonochromePublic" target_type = "android_apk" if (android_64bit_target_cpu) { @@ -2552,8 +2672,7 @@ } if (android_64bit_target_cpu) { - chrome_public_apk_or_module_tmpl("monochrome_64_public_apk") { - is_monochrome = true + monochrome_public_apk_or_module_tmpl("monochrome_64_public_apk") { apk_name = "MonochromePublic64" target_type = "android_apk" is_64_bit_browser = true @@ -2731,7 +2850,48 @@ include_32_bit_webview = !skip_secondary_abi_for_cq } - deps = [ ":chrome_test_ar_java" ] + # This is where we would add the shared_libraries entry for + # :libchromefortest in the non-Monochrome version. However, doing so in the + # Monochrome version causes Chrome to crash on startup due to being unable + # to load the library, and looking at the libraries included in the APK + # shows both libchromefortest and libmonochrome, when only one should be + # present. The tests currently work fine with just libmonochrome, so keep + # it this way until we actually need the test-only library. This may be + # related to monochrome_public_common_apk_or_module_tmpl adding its own + # shared libraries, but chrome_public_common_apk_or_module_tmpl not. See + # https://crbug.com/974017. + deps = [ + ":chrome_test_ar_java", + "//third_party/android_sdk:android_test_mock_java", + ] + + # Include ArCore files directly instead of using bundles. This does + # require us to explicitly re-declare our dependency on ARCore, which + # otherwise should have already been included, since the native libraries + # need to know that it is available. Though we'd always need to forcibly + # include the manifest DEP here as well + deps += [ + "//third_party/arcore-android-sdk-client:com_google_ar_core_java", + "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest", + ] + + _libarcore_dir = get_label_info( + "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)", + "target_out_dir") + "/com_google_ar_core_java/jni" + + # We store this as a separate .so in the APK and only load as needed. + if (android_64bit_target_cpu) { + if (skip_secondary_abi_for_cq) { + loadable_modules = [ "$_libarcore_dir/arm64-v8a/libarcore_sdk_c.so" ] + } else { + secondary_abi_loadable_modules = + [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] + } + } else { + loadable_modules = [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] + } + + additional_apks = [ "//net/android:net_test_support_apk" ] } } @@ -2954,19 +3114,22 @@ ] } - template("chrome_bundle_tmpl") { - _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome - _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome - assert(_is_monochrome || _is_trichrome, "TODO: https://crbug.com/1426950") - + template("monochrome_or_trichrome_public_bundle_tmpl") { _base_module_target_name = "${invoker.target_name}__base_bundle_module" - chrome_public_apk_or_module_tmpl(_base_module_target_name) { + _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome + + if (_is_trichrome) { + _bundle_name = "TrichromeChrome${invoker.bundle_suffix}" + } else { + _bundle_name = "MonochromePublic${invoker.bundle_suffix}" + } + + monochrome_public_apk_or_module_tmpl(_base_module_target_name) { forward_variables_from(invoker, [ "add_view_trace_events", "expected_android_manifest", "is_64_bit_browser", - "is_monochrome", "is_trichrome", "include_32_bit_webview", "include_64_bit_webview", @@ -2974,6 +3137,7 @@ "resource_ids_provider_dep", ]) target_type = "android_app_bundle_module" + is_base_module = true bundle_target = ":${invoker.target_name}" if (defined(invoker.expected_android_manifest_template)) { @@ -2992,7 +3156,6 @@ "include_32_bit_webview", "include_64_bit_webview", "is_64_bit_browser", - "is_monochrome", "is_trichrome", "lint_baseline_file", "lint_min_sdk_version", @@ -3002,19 +3165,20 @@ "expected_libs_and_assets", "expected_proguard_config", ]) + is_monochrome = !_is_trichrome base_module_target = ":$_base_module_target_name" + bundle_name = _bundle_name manifest_package = chrome_public_manifest_package - if (_is_trichrome) { - bundle_name = "TrichromeChrome${invoker.bundle_suffix}" - module_descs = chrome_module_descs - } else if (_is_monochrome) { - bundle_name = "MonochromePublic${invoker.bundle_suffix}" + if (is_monochrome) { module_descs = monochrome_module_descs + } else { + module_descs = chrome_module_descs } chrome_deps = [ ":delegate_public_impl_java" ] if (!_is_trichrome) { chrome_deps += [ "//chrome/android:monochrome_java" ] } + if (!is_java_debug) { proguard_android_sdk_dep = webview_framework_dep } @@ -3043,9 +3207,7 @@ } else { # Public webview targets don't work with non-public sdks. # https://crbug.com/1000763 - chrome_bundle_tmpl("monochrome_public_bundle") { - is_monochrome = true - + monochrome_or_trichrome_public_bundle_tmpl("monochrome_public_bundle") { # Monochrome bundle is used as our unified lint target, so it needs to set the # lowest shipping minSdkVersion to catch all potential NewApi errors. lint_min_sdk_version = default_min_sdk_version @@ -3085,7 +3247,7 @@ } } - chrome_bundle_tmpl("trichrome_chrome_bundle") { + monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_bundle") { bundle_suffix = "" is_trichrome = true static_library_provider = ":trichrome_library_apk" @@ -3198,14 +3360,13 @@ } if (android_64bit_target_cpu) { - chrome_bundle_tmpl("monochrome_64_public_bundle") { - is_monochrome = true + monochrome_or_trichrome_public_bundle_tmpl("monochrome_64_public_bundle") { bundle_suffix = "64" is_64_bit_browser = true include_32_bit_webview = false } - chrome_bundle_tmpl("trichrome_chrome_64_bundle") { + monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_64_bundle") { is_trichrome = true bundle_suffix = "64" is_64_bit_browser = true @@ -3218,21 +3379,22 @@ } if (!skip_secondary_abi_for_cq) { - chrome_bundle_tmpl("monochrome_32_public_bundle") { - is_monochrome = true + monochrome_or_trichrome_public_bundle_tmpl( + "monochrome_32_public_bundle") { bundle_suffix = "32" is_64_bit_browser = false include_64_bit_webview = false } - chrome_bundle_tmpl("monochrome_64_32_public_bundle") { - is_monochrome = true + monochrome_or_trichrome_public_bundle_tmpl( + "monochrome_64_32_public_bundle") { bundle_suffix = "6432" is_64_bit_browser = true include_32_bit_webview = true } - chrome_bundle_tmpl("trichrome_chrome_64_32_bundle") { + monochrome_or_trichrome_public_bundle_tmpl( + "trichrome_chrome_64_32_bundle") { is_trichrome = true bundle_suffix = "6432" is_64_bit_browser = true @@ -3243,7 +3405,7 @@ "expectations/$target_name.$target_cpu.libs_and_assets.expected" } } - chrome_bundle_tmpl("trichrome_chrome_32_bundle") { + monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_32_bundle") { is_trichrome = true bundle_suffix = "32" is_64_bit_browser = false
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index a697eda..5e6f796 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -455,6 +455,7 @@ "java/res/layout/account_divider_preference.xml", "java/res/layout/account_management_account_row.xml", "java/res/layout/auto_sign_in_first_run_dialog.xml", + "java/res/layout/autofill_address_profile_prompt_source_notice.xml", "java/res/layout/autofill_billing_address_dropdown.xml", "java/res/layout/autofill_card_unmask_prompt.xml", "java/res/layout/autofill_card_unmask_prompt_card_details.xml", @@ -462,10 +463,10 @@ "java/res/layout/autofill_cc_details.xml", "java/res/layout/autofill_expiration_date_fix_flow.xml", "java/res/layout/autofill_local_profile_icon.xml", + "java/res/layout/autofill_migrate_address_profile_prompt.xml", "java/res/layout/autofill_name_fixflow.xml", "java/res/layout/autofill_save_address_profile_prompt.xml", "java/res/layout/autofill_save_card_base_layout.xml", - "java/res/layout/autofill_save_update_address_profile_prompt_footer.xml", "java/res/layout/autofill_server_card_editor.xml", "java/res/layout/autofill_server_data_edit_link.xml", "java/res/layout/autofill_server_data_label.xml",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index ef17c6e..28fe242 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -109,6 +109,8 @@ # Variables: # target_type: Either 'android_apk' or 'android_app_bundle_module'. # apk_name: For APK target types, the final APK name without a suffix. +# is_base_module: For bundle module target types, true iff this is a base +# application module, instead of a feature module. # shared_libraries: List of native shared libraries targets to include in # the final target (e.g. [ ":libchrome" ]). # is_monochrome: Indicates that this target contains chrome and webview @@ -122,44 +124,29 @@ # Plus all other variables accepted by android_apk() or # android_app_bundle_module(), depending on the target type. # -template("chrome_common_apk_or_module_tmpl") { - _target_type = invoker.target_type - assert(_target_type == "android_apk" || - _target_type == "android_app_bundle_module" || - _target_type == "instrumentation_test_apk") +template("chrome_public_common_apk_or_module_tmpl") { + assert( + invoker.target_type == "android_apk" || + invoker.target_type == "android_app_bundle_module" || + invoker.target_type == "instrumentation_test_apk", + "Invalid target_type definition, should be 'android_apk' or 'android_app_bundle_module'") _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome - _is_bundle = _target_type == "android_app_bundle_module" + _is_bundle = invoker.target_type == "android_app_bundle_module" - _is_64_bit_browser = - android_64bit_target_cpu && - (!defined(invoker.is_64_bit_browser) || invoker.is_64_bit_browser) if (_is_trichrome || _is_monochrome) { _include_64_bit_webview = android_64bit_target_cpu && (!defined(invoker.include_64_bit_webview) || invoker.include_64_bit_webview) _include_32_bit_webview = !defined(invoker.include_32_bit_webview) || invoker.include_32_bit_webview - _include_primary_abi = !android_64bit_target_cpu || _is_64_bit_browser || - _include_64_bit_webview - _include_secondary_abi = android_64bit_target_cpu && - (!_is_64_bit_browser || _include_32_bit_webview) - if (_include_secondary_abi) { - _secondary_out_dir = - get_label_info("X($android_secondary_abi_toolchain)", "root_out_dir") - not_needed([ "_secondary_out_dir" ]) - } - } else { - _include_primary_abi = true - _include_secondary_abi = false - - # TODO(agrieve): not_needed needed only when not using crashpad trampoline. - not_needed([ - "_include_primary_abi", - "_include_secondary_abi", - ]) } + _is_64_bit_browser = + android_64bit_target_cpu && + (!defined(invoker.is_64_bit_browser) || invoker.is_64_bit_browser) + _is_secondary_abi_primary = !_is_64_bit_browser && android_64bit_target_cpu + not_needed([ "_is_secondary_abi_primary" ]) assert(!(_is_monochrome && _is_trichrome), "Cannot be both trichrome and monochrome!") @@ -167,6 +154,12 @@ "If trichrome library is used, static_library_provider must be set " + "so that a dep can be added on the library APK.") + if (!defined(invoker.target_type)) { + _target_type = "android_apk" + } else { + _target_type = invoker.target_type + } + if (_is_trichrome) { _version_code = TRICHROME_VERSION_MAP["${android_64bit_target_cpu}_${_is_64_bit_browser}_${_include_64_bit_webview}_${_include_32_bit_webview}"] } else if (_is_monochrome) { @@ -176,150 +169,104 @@ _version_code = chrome_modern_version_code } - if (defined(invoker.manifest_package)) { - _manifest_package = invoker.manifest_package - } else { - _manifest_package = chrome_public_manifest_package - } - - _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml" - - # TODO(crbug.com/1411557): Move out of manifest/ when downstream is updated. - # _split.xml is used in chrome_bundle template. - _split_android_manifest = - "$target_gen_dir/manifest/$target_name/AndroidManifest_split.xml" - _android_manifest_target_name = "${target_name}__android_manifest" - split_manifest_template(_android_manifest_target_name) { - definitions_in_split = _is_bundle - split_input = "//chrome/android/java/AndroidManifest_split.xml" - split_output = _split_android_manifest - includes = [] - output = _android_manifest - variables = default_chrome_public_jinja_variables + - [ "manifest_package=$_manifest_package" ] - if (_is_trichrome) { - input = "//chrome/android/java/AndroidManifest_trichrome_chrome.xml" - includes = [ "//chrome/android/java/AndroidManifest.xml" ] - variables += - trichrome_jinja_variables + [ "trichrome_version=$_version_code" ] - } else if (_is_monochrome) { - input = "//chrome/android/java/AndroidManifest_monochrome.xml" - includes = [ - "//android_webview/nonembedded/java/AndroidManifest.xml", - "//chrome/android/java/AndroidManifest.xml", - ] - variables += monochrome_android_manifest_jinja_variables - if (_is_64_bit_browser) { - variables += [ "webview_library=libmonochrome_64.so" ] - } else { - variables += [ "webview_library=libmonochrome.so" ] - } + # TODO(crbug.com/1411557): Remove option for custom manifest. + if (!defined(invoker.android_manifest)) { + if (defined(invoker.manifest_package)) { + _manifest_package = invoker.manifest_package } else { - input = "//chrome/android/java/AndroidManifest.xml" + _manifest_package = chrome_public_manifest_package } - if (_is_monochrome || _is_trichrome) { - _force_32_bit = _include_32_bit_webview && _include_64_bit_webview && - !_is_64_bit_browser - variables += [ - "force_32_bit=$_force_32_bit", - "include_arcore_manifest_flag=$enable_arcore", - ] - # TODO(crbug.com/1411557): Remove block. - if (_is_64_bit_browser) { - variables -= [ use_32bit_abi_jinja_variable ] + _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml" + + # TODO(crbug.com/1411557): Move out of manifest/ when downstream is updated. + # _split.xml is used in chrome_bundle template. + _split_android_manifest = + "$target_gen_dir/manifest/$target_name/AndroidManifest_split.xml" + _android_manifest_target_name = "${target_name}__android_manifest" + split_manifest_template(_android_manifest_target_name) { + definitions_in_split = _is_bundle + split_input = "//chrome/android/java/AndroidManifest_split.xml" + split_output = _split_android_manifest + includes = [] + output = _android_manifest + variables = default_chrome_public_jinja_variables + + [ "manifest_package=$_manifest_package" ] + if (_is_trichrome) { + input = "//chrome/android/java/AndroidManifest_trichrome_chrome.xml" + includes = [ "//chrome/android/java/AndroidManifest.xml" ] + variables += + trichrome_jinja_variables + [ "trichrome_version=$_version_code" ] + } else if (_is_monochrome) { + input = "//chrome/android/java/AndroidManifest_monochrome.xml" + includes = [ + "//android_webview/nonembedded/java/AndroidManifest.xml", + "//chrome/android/java/AndroidManifest.xml", + ] + variables += monochrome_android_manifest_jinja_variables + if (_is_64_bit_browser) { + variables += [ "webview_library=libmonochrome_64.so" ] + } else { + variables += [ "webview_library=libmonochrome.so" ] + } + } else { + input = "//chrome/android/java/AndroidManifest.xml" } - } - if (defined(invoker.jinja_input)) { - includes += [ input ] - input = invoker.jinja_input - } - if (defined(invoker.jinja_extra_variables)) { - variables += invoker.jinja_extra_variables - } - if (defined(invoker.jinja_extra_includes)) { - includes += invoker.jinja_extra_includes + if (_is_monochrome || _is_trichrome) { + _force_32_bit = _include_32_bit_webview && _include_64_bit_webview && + !_is_64_bit_browser + variables += [ + "force_32_bit=$_force_32_bit", + "include_arcore_manifest_flag=$enable_arcore", + ] + + # TODO(crbug.com/1411557): Remove block. + if (_is_64_bit_browser) { + variables -= [ use_32bit_abi_jinja_variable ] + } + } + if (defined(invoker.jinja_input)) { + includes += [ input ] + input = invoker.jinja_input + } + if (defined(invoker.jinja_extra_variables)) { + variables += invoker.jinja_extra_variables + } + if (defined(invoker.jinja_extra_includes)) { + includes += invoker.jinja_extra_includes + } } } target(_target_type, target_name) { - android_manifest = _android_manifest - android_manifest_dep = ":$_android_manifest_target_name" - manifest_package = _manifest_package + forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - if (defined(invoker.min_sdk_version)) { - min_sdk_version = invoker.min_sdk_version - } else if (_is_trichrome) { + if (!defined(assert_no_deps)) { + assert_no_deps = [] + } + + # https://crbug.com/1415351 + assert_no_deps += [ + "//third_party/androidx:androidx_window_extensions_core_core_java", + "//third_party/androidx:androidx_window_sidecar_sidecar_java", + "//third_party/androidx:androidx_window_window_java_java", + ] + + # TODO(crbug.com/1411557): Do not allows custom manifest dep. + if (defined(_android_manifest_target_name)) { + android_manifest = _android_manifest + android_manifest_dep = ":$_android_manifest_target_name" + manifest_package = _manifest_package + } + + if (!defined(min_sdk_version) && _is_trichrome) { min_sdk_version = 29 } - if (defined(invoker.version_name)) { - version_name = invoker.version_name - } else { - version_name = chrome_version_name - } - if (defined(invoker.version_code)) { - # Override for the actual versionCode, but not for trichrome_version. - version_code = invoker.version_code - } else { - version_code = _version_code - } - if (defined(invoker.expected_android_manifest)) { + if (defined(expected_android_manifest)) { expected_android_manifest_version_code_offset = chrome_version_code expected_android_manifest_library_version_offset = chrome_version_code } - if (_target_type == "android_apk") { - command_line_flags_file = "chrome-command-line" - } - - if (_is_bundle) { - is_base_module = true - - # Sets ISOLATED_SPLITS_ENABLED in BuildConfig.java. - isolated_splits_enabled = true - } - - if (_is_monochrome) { - alternative_android_sdk_dep = webview_framework_dep - app_as_shared_lib = true - - # Resource allowlist used when generating R.java files and causes - # only the webview subset of resources to be marked as non-final. - # Strings in this target will also be kept in the base apk rather than placed in the language splits. - shared_resources_allowlist_target = - "//android_webview:system_webview_no_weblayer_apk" - - # Ensure the localized resources for all locales are used, even when - # a smaller set is specified through aapt_locale_allowlist. - shared_resources_allowlist_locales = platform_pak_locales - - product_config_java_packages = [ - "org.chromium.chrome.browser", - webview_product_config_java_package, - ] - - if (webview_includes_weblayer) { - product_config_java_packages += [ weblayer_product_config_java_package ] - } - } else { - product_config_java_packages = [ "org.chromium.chrome.browser" ] - } - - if (enable_silent_java_assert_reporting) { - custom_assertion_handler = crash_reporting_assertion_handler - } - - if (allow_jni_multiplexing) { - enable_jni_multiplexing = true - } - - # TODO(agrieve): Make this the default for apks with minSdkVersion > 21. - if (_is_monochrome || _is_trichrome) { - no_xml_namespaces = true - } - - # Include resource strings files only for supported locales. - aapt_locale_allowlist = platform_pak_locales - resource_exclusion_regex = common_resource_exclusion_regex resource_exclusion_exceptions = common_resource_exclusion_exceptions @@ -329,7 +276,7 @@ "*ic_lock.*", # Bottom edge seems misaligned. ] - # Most of these, with the exception of resource_exclusion_exceptions, + # Note most of these, with the exception of resource_exclusion_exceptions, # are currently duplicated in system_webview_apk_tmpl.gni. # Used only by alert dialog on tiny screens. @@ -343,236 +290,256 @@ # Instead of manually filtering, unused resource removal would be better: # https://crbug.com/636448 resource_exclusion_regex += "|${_material_package}/xml.*badge_" + _material_package = "*com_google_android_material*" - if (!is_java_debug) { - # Android supports webp transparent resources properly since API level 18, - # so this can only be activated for modern ones (which target API >= 21). - png_to_webp = true + if (!_is_monochrome) { + product_config_java_packages = [ "org.chromium.chrome.browser" ] + } - proguard_enabled = true - proguard_configs = [ "//chrome/android/proguard/main.flags" ] - if (_is_monochrome) { - proguard_configs += - [ "//android_webview/nonembedded/java/proguard.flags" ] - } - if (defined(invoker.proguard_configs)) { - proguard_configs += invoker.proguard_configs - } + # Android supports webp transparent resources properly since API level 18, + # so this can only be activated for modern ones (which target API >= 21). + if (!defined(png_to_webp)) { + png_to_webp = !is_java_debug + } - # We only optimize resources for bundles since APKs are not shipped. - # Resources only live in the base module atm as such we only need to set - # these on the base module - if (_is_bundle) { - # Removes metadata needed for Resources.getIdentifier("resource_name"). - strip_resource_names = true + # We only optimize resources for bundles since APKs are not shipped. + # Resources only live in the base module atm as such we only need to set + # these on the base module + if (_is_bundle) { + # Removes metadata needed for Resources.getIdentifier("resource_name"). + strip_resource_names = !is_java_debug - # Shortens resource file names in apk eg: res/drawable/button.xml -> res/a.xml - short_resource_paths = true + # Shortens resource file names in apk eg: res/drawable/button.xml -> res/a.xml + short_resource_paths = !is_java_debug - # Removes unused resources from the apk. Only enabled on official builds - # since it adds a slow step and serializes the build graph causing fewer - # expensive tasks (eg: proguarding, resource optimization) to be run in - # parallel by adding dependencies between them (adds around 10-20 - # seconds on my machine). - strip_unused_resources = is_official_build + # Removes unused resources from the apk. Only enabled on official builds + # since it adds a slow step and serializes the build graph causing fewer + # expensive tasks (eg: proguarding, resource optimization) to be run in + # parallel by adding dependencies between them (adds around 10-20 + # seconds on my machine). + strip_unused_resources = is_official_build + } - # Resources config for blocklisting resource names from obfuscation - resources_config_paths = [ "//chrome/android/aapt2.config" ] - if (_is_monochrome || _is_trichrome) { - resources_config_paths += [ "//android_webview/aapt2.config" ] - } - if (defined(invoker.resources_config_paths)) { - resources_config_paths += invoker.resources_config_paths + if (!defined(aapt_locale_allowlist)) { + # Include resource strings files only for supported locales. + aapt_locale_allowlist = platform_pak_locales + } + + if (!defined(use_chromium_linker)) { + # The Chromium Linker depends on ASharedMemory_create() introduced in O. + use_chromium_linker = chromium_linker_supported && _is_trichrome + } + + if (_is_trichrome) { + static_library_provider_use_secondary_abi = _is_secondary_abi_primary + + # http://crbug.com/1042107. + if (is_component_build) { + if (android_64bit_target_cpu && _is_64_bit_browser) { + main_component_library = "libmonochrome_64.cr.so" + } else { + main_component_library = "libmonochrome.cr.so" } } } - deps = [ - "//chrome/android:chrome_base_module_resources", - "//chrome/android:chrome_public_non_pak_assets", - ] - - # TODO(agrieve): Make uncondtional when moving to trampoline. - if (_is_monochrome || _is_trichrome) { - deps += [ "//components/crash/android:handler_java" ] - } - if (_is_monochrome) { - deps += [ "//chrome/android:base_monochrome_module_java" ] - } else { - deps += [ "//chrome/android:base_module_java" ] - } - if (defined(invoker.deps)) { - deps += invoker.deps - } - - if (!_is_trichrome) { - # These go in trichrome library. + if (!_is_monochrome && !_is_trichrome) { deps += [ + "//components/crash/core/app:chrome_crashpad_handler_named_as_so", "//gin:v8_snapshot_assets", "//third_party/icu:icu_assets", ] + if (!defined(loadable_modules)) { + loadable_modules = [] + } + loadable_modules += [ "$root_out_dir/libchrome_crashpad_handler.so" ] + if (!defined(library_always_compress)) { + library_always_compress = [] + } + library_always_compress += [ + "libchrome_crashpad_handler.so", + "libchromium_android_linker.so", + ] + } - # TODO(agrieve): This is excluded from trichrome in preparation for - # "synchronized proguarding", which we've since abandoned. Enable for - # trichrome, or just remove the version check altogether. + if (dfmify_dev_ui && !_is_bundle) { + # Dev UI is a feature in a DFM, and APKs don't use DFMs. To make the code + # available for APKs add a dependency on it. + deps += [ "//chrome/android/features/dev_ui:java" ] + } + if (enable_vr && !_is_bundle) { + # VR is a feature in a DFM, and APKs don't use DFMs, but we + # unconditionally include vr code in our native library. To make the code + # available for APKs, add a dependency on it. + deps += [ "//chrome/android/features/vr:java" ] + } + + if (!is_java_debug) { + proguard_enabled = true + if (!defined(proguard_configs)) { + proguard_configs = [] + } + proguard_configs += [ "//chrome/android/proguard/main.flags" ] + } + + if (use_chromium_linker) { + if (_is_secondary_abi_primary) { + _secondary_linker = "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" + deps += [ _secondary_linker ] + _secondary_out_dir = get_label_info(_secondary_linker, "root_out_dir") + secondary_abi_loadable_modules += + [ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ] + } else { + deps += [ "//base/android/linker:chromium_android_linker" ] + loadable_modules += + [ "$root_out_dir/libchromium_android_linker$shlib_extension" ] + } + } + if (build_with_internal_optimization_guide) { + if (_is_secondary_abi_primary) { + _secondary_optimization_guide = "//components/optimization_guide/internal:optimization_guide_internal($android_secondary_abi_toolchain)" + deps += [ _secondary_optimization_guide ] + _secondary_out_dir = + get_label_info(_secondary_optimization_guide, "root_out_dir") + secondary_abi_loadable_modules += + [ "$_secondary_out_dir/liboptimization_guide_internal.so" ] + } else { + deps += [ "//components/optimization_guide/internal:optimization_guide_internal" ] + loadable_modules += + [ "$root_out_dir/liboptimization_guide_internal.so" ] + } + } + if (_target_type == "android_apk") { + command_line_flags_file = "chrome-command-line" + } + if (!_is_trichrome) { build_config_include_product_version_resource = true deps += [ "//chrome/android:product_version_resources" ] } + if (!_is_bundle || !(_is_monochrome || _is_trichrome)) { + deps += [ "//chrome/android:chrome_all_java" ] + } + if (_is_bundle) { # Required to support macro resources. # See https://crbug.com/1278419 deps += [ ":${target_name}__all_dfm_resources" ] - } else { - # For bundles, this exists in the "chrome" split. - deps += [ "//chrome/android:chrome_all_java" ] - - if (dfmify_dev_ui) { - # For bundles, Dev UI is a feature in a DFM. - deps += [ "//chrome/android/features/dev_ui:java" ] - } - if (enable_vr) { - # For bundles, VR is a feature in a DFM. - deps += [ "//chrome/android/features/vr:java" ] - } - } - - if (_is_monochrome) { - deps += [ - "//android_webview/glue:glue_java", - "//android_webview/nonembedded:monochrome_devui_launcher_icon_resources", - "//android_webview/nonembedded:nonembedded_java", - ] - - # For bundles, this lives in chrome split. - if (!_is_bundle) { - deps += [ "//chrome/android:monochrome_java" ] - } - - if (_include_primary_abi) { - deps += [ "//android_webview:monochrome_webview_primary_abi_assets" ] - } - if (_include_secondary_abi) { - deps += [ "//android_webview:monochrome_webview_secondary_abi_assets" ] - } - } - - if (_is_bundle && _is_monochrome) { - deps += [ "//chrome/android:monochrome_bundle_module_pak_assets" ] - } else if (_is_bundle && _is_trichrome) { - deps += [ "//chrome/android:trichrome_chrome_bundle_module_pak_assets" ] - } else if (_is_bundle) { - deps += [ "//chrome/android:chrome_bundle_module_pak_assets" ] - } else if (_is_monochrome) { - deps += [ "//chrome/android:monochrome_apk_pak_assets" ] - } else { - assert(!_is_trichrome) - deps += [ "//chrome/android:chrome_apk_pak_assets" ] - } - - # https://crbug.com/1415351 - assert_no_deps = [ - "//third_party/androidx:androidx_window_extensions_core_core_java", - "//third_party/androidx:androidx_window_sidecar_sidecar_java", - "//third_party/androidx:androidx_window_window_java_java", - ] - if (defined(invoker.assert_no_deps)) { - assert_no_deps += invoker.assert_no_deps } # Unwind tables are included in the stack_unwinder DFM on Android, so they # aren't needed for bundle builds. However, we keep them for non-bundle # builds, such as test and development apks (e.g. chrome_public_apk), to # allow tests and developers to use them directly. - if (!defined(invoker.shared_libraries) && !_is_bundle && - add_unwind_tables_in_chrome_32bit_apk && - (target_cpu == "arm" || - (target_cpu == "arm64" && !_is_64_bit_browser))) { - if (_is_monochrome || _is_trichrome) { - deps += [ "//chrome/android:libmonochrome_unwind_table_assets" ] - } else { - deps += [ "//chrome/android:libchrome_unwind_table_assets" ] - } - } + if (!_is_bundle && add_unwind_tables_in_chrome_32bit_apk) { + _needs_32bit_lib = + target_cpu == "arm" || ((_is_monochrome || _is_trichrome) && + target_cpu == "arm64" && !_is_64_bit_browser) - data_deps = [] - if (defined(invoker.data_deps)) { - data_deps += invoker.data_deps + if (_needs_32bit_lib) { + if (_is_monochrome || _is_trichrome) { + deps += [ "//chrome/android:libmonochrome_unwind_table_assets" ] + } else { + deps += [ "//chrome/android:libchrome_unwind_table_assets" ] + } + } } # Prefer to add this data_dep on the final target instead of java targets # like chrome_all_java so that all other targets can build in parallel with # lint. if (!disable_android_lint) { + if (!defined(data_deps)) { + data_deps = [] + } data_deps += [ "//chrome/android:android_lint" ] } - shared_libraries = [] - loadable_modules = [] - if (android_64bit_target_cpu) { - secondary_abi_shared_libraries = [] - secondary_abi_loadable_modules = [] - } - if (defined(invoker.loadable_modules)) { - loadable_modules = invoker.loadable_modules - } - if (defined(invoker.secondary_abi_loadable_modules)) { - secondary_abi_loadable_modules = invoker.secondary_abi_loadable_modules + if (enable_silent_java_assert_reporting) { + custom_assertion_handler = crash_reporting_assertion_handler } - if (_is_64_bit_browser && build_hwasan_splits) { - _hwasan_toolchain = "//build/toolchain/android:android_clang_arm64_hwasan" + if (allow_jni_multiplexing) { + enable_jni_multiplexing = true } - if (defined(invoker.shared_libraries)) { - shared_libraries += invoker.shared_libraries - } else if (_is_monochrome) { - if (android_64bit_target_cpu) { - # Build //android_webview:monochrome with the opposite bitness that - # Chrome runs in. - if (_is_64_bit_browser) { - shared_libraries += [ "//chrome/android:libmonochrome_64" ] - if (_include_32_bit_webview) { - secondary_abi_shared_libraries += [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ] - } - if (build_hwasan_splits) { - shared_libraries += - [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ] - } - } else { - if (_include_64_bit_webview) { - shared_libraries += [ "//android_webview:monochrome" ] - } - secondary_abi_shared_libraries += [ - "//chrome/android:libmonochrome($android_secondary_abi_toolchain)", - ] - } - } else { - shared_libraries += [ "//chrome/android:libmonochrome" ] + if (!defined(version_name)) { + version_name = chrome_version_name + } + version_code = _version_code + + # Override for the actual versionCode, but not for trichrome_version. + if (defined(invoker.version_code)) { + version_code = invoker.version_code + } + } +} + +# The equivalent of chrome_common_apk_or_module_tmpl for all builds of +# monochrome and trichrome chrome. +template("monochrome_public_common_apk_or_module_tmpl") { + chrome_public_common_apk_or_module_tmpl(target_name) { + _overrides = { + _is_bundle_module = defined(invoker.target_type) && + invoker.target_type == "android_app_bundle_module" + + if (_is_bundle_module) { + assert( + defined(invoker.is_base_module), + "_is_bundle_module is true but the invoker does not define is_base_module!") } - } else if (!_is_trichrome) { - shared_libraries += [ "//chrome/android:libchrome" ] - } - # TODO(agrieve): Enable for chrome_public_apk as well. - if (enable_arcore && (_is_monochrome || _is_trichrome)) { - # The arcore manifest needs to be merged into the base module because - # the Play Store verifies the com.google.ar.core.min_apk_version - # meta-data tag is in the base manifest. - deps += [ - "//third_party/arcore-android-sdk-client:com_google_ar_core_java", - "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest", + is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome + is_monochrome = !is_trichrome + + shared_libraries = [] + if (defined(invoker.shared_libraries)) { + shared_libraries += invoker.shared_libraries + } + secondary_abi_shared_libraries = [] + if (defined(invoker.secondary_abi_shared_libraries)) { + secondary_abi_shared_libraries += invoker.secondary_abi_shared_libraries + } + loadable_modules = [] + if (defined(invoker.loadable_modules)) { + loadable_modules = invoker.loadable_modules + } + secondary_abi_loadable_modules = [] + if (defined(invoker.secondary_abi_loadable_modules)) { + secondary_abi_loadable_modules = invoker.secondary_abi_loadable_modules + } + native_lib_placeholders = [] + if (defined(invoker.native_lib_placeholders)) { + native_lib_placeholders = invoker.native_lib_placeholders + } + secondary_native_lib_placeholders = [] + if (defined(invoker.secondary_native_lib_placeholders)) { + secondary_native_lib_placeholders = + invoker.secondary_native_lib_placeholders + } + + deps = [ + "//chrome/android:chrome_public_non_pak_assets", + "//components/crash/android:handler_java", ] + if (defined(invoker.deps)) { + deps += invoker.deps + } - # For Trichrome, the native library is added to TrichromeLibrary.apk so - # it's not needed here. - if (!_is_trichrome) { - _arcore_target = "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" - _libarcore_dir = get_label_info(_arcore_target, "target_out_dir") + - "/com_google_ar_core_java/jni" + if (_is_bundle_module && invoker.is_base_module && enable_arcore && + is_monochrome) { + # AR DFM is disabled - set the loadable_modules / + # secondary_abi_loadable_modules to what would be brought in by the + # module. The AR Java will be brought in by the chrome_bundle target. + # This needs to happen for monochrome builds of base module if ARCore is + # enabled. For Trichrome, the native library is added to + # TrichromeLibrary.apk so it's not needed here. + _libarcore_dir = get_label_info( + "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)", + "target_out_dir") + "/com_google_ar_core_java/jni" if (android_64bit_target_cpu) { - if (_is_64_bit_browser) { + if (invoker.is_64_bit_browser) { loadable_modules += [ "$_libarcore_dir/arm64-v8a/libarcore_sdk_c.so" ] } else { @@ -584,164 +551,234 @@ [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] } } - } - library_always_compress = [] - if (defined(invoker.library_always_compress)) { - library_always_compress = invoker.library_always_compress - } - # TODO(agrieve): Use Crashpad trampoline in chrome_public_apk. - if (!_is_monochrome && !_is_trichrome) { - deps += - [ "//components/crash/core/app:chrome_crashpad_handler_named_as_so" ] - loadable_modules += [ "$root_out_dir/libchrome_crashpad_handler.so" ] - library_always_compress += [ "libchrome_crashpad_handler.so" ] - } else if (!_is_trichrome) { - # Crashpad trampoline lives in TrichromeLibrary.apk. - # https://chromium.googlesource.com/chromium/src/+/main/docs/android_native_libraries.md#Crashpad-Packaging - if (_include_primary_abi) { - deps += [ - "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline", - ] - loadable_modules += - [ "$root_out_dir/libcrashpad_handler_trampoline.so" ] - } - if (_include_secondary_abi) { - deps += [ "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)" ] - secondary_abi_loadable_modules += - [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ] - } - } - - # The Chromium Linker depends on ASharedMemory_create() introduced in O. - use_chromium_linker = chromium_linker_supported && _is_trichrome - - if (use_chromium_linker) { - if (android_64bit_target_cpu && !_is_64_bit_browser) { - deps += [ "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" ] - secondary_abi_loadable_modules += - [ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ] - } else { - deps += [ "//base/android/linker:chromium_android_linker" ] - loadable_modules += - [ "$root_out_dir/libchromium_android_linker$shlib_extension" ] - } - if (_is_64_bit_browser && build_hwasan_splits) { - deps += [ - "//base/android/linker:chromium_android_linker($_hwasan_toolchain)", - ] - _hwasan_outdir = get_label_info(":($_hwasan_toolchain)", "root_out_dir") - loadable_modules += - [ "$_hwasan_outdir/libchromium_android_linker$shlib_extension" ] - } - } - - if (build_with_internal_optimization_guide) { - if (android_64bit_target_cpu && !_is_64_bit_browser) { - _secondary_optimization_guide = "//components/optimization_guide/internal:optimization_guide_internal($android_secondary_abi_toolchain)" - deps += [ _secondary_optimization_guide ] - secondary_abi_loadable_modules += - [ "$_secondary_out_dir/liboptimization_guide_internal.so" ] - } else { - deps += [ "//components/optimization_guide/internal:optimization_guide_internal" ] - loadable_modules += - [ "$root_out_dir/liboptimization_guide_internal.so" ] - } - } - - if (_is_trichrome) { - if (android_64bit_target_cpu && !_is_64_bit_browser) { - static_library_provider_use_secondary_abi = true + if (_is_bundle_module) { + # Sets ISOLATED_SPLITS_ENABLED in BuildConfig.java. + isolated_splits_enabled = true } - # Include placeholder libraries to make Chrome multiarch in the same way - # as Monochrome, even though Chrome only runs with one of the two - # bitnesses. This allows the "32-bit" and "64-bit" versions of Chrome to - # depend on their respective versions of the shared library APK even - # though they're functionally the same. - if (_include_primary_abi && loadable_modules == []) { - native_lib_placeholders = [ "libdummy.so" ] - } - if (_include_secondary_abi && secondary_abi_loadable_modules == []) { - secondary_native_lib_placeholders = [ "libdummy.so" ] - } + if (_is_bundle_module && invoker.is_base_module) { + # The arcore manifest needs to be merged into the base module because + # the Play Store verifies the com.google.ar.core.min_apk_version + # meta-data tag is in the base manifest. + if (enable_arcore) { + deps += [ + "//third_party/arcore-android-sdk-client:com_google_ar_core_java", + "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest", + ] + } - # http://crbug.com/1042107. - if (is_component_build) { - if (_is_64_bit_browser) { - main_component_library = "libmonochrome_64.cr.so" + if (is_monochrome) { + deps += [ "//chrome/android:base_monochrome_module_java" ] } else { - main_component_library = "libmonochrome.cr.so" + deps += [ "//chrome/android:base_module_java" ] + } + } + + if (android_64bit_target_cpu && (is_monochrome || is_trichrome)) { + _include_64_bit_webview = !defined(invoker.include_64_bit_webview) || + invoker.include_64_bit_webview + _include_32_bit_webview = !defined(invoker.include_32_bit_webview) || + invoker.include_32_bit_webview + } + if (is_monochrome) { + product_config_java_packages = [ + "org.chromium.chrome.browser", + webview_product_config_java_package, + ] + + if (webview_includes_weblayer) { + product_config_java_packages += + [ weblayer_product_config_java_package ] + } + + # Flag whether additional deps and libs should be included for each ABI. + _include_primary_support = false + _include_secondary_support = false + + if (android_64bit_target_cpu) { + # Build //android_webview:monochrome with the opposite bitness that + # Chrome runs in. + if (invoker.is_64_bit_browser) { + _include_primary_support = true + shared_libraries += [ "//chrome/android:libmonochrome_64" ] + if (_include_32_bit_webview) { + secondary_abi_shared_libraries += [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ] + _include_secondary_support = true + } + } else { + secondary_abi_shared_libraries += + [ "//chrome/android:monochrome_secondary_abi_lib" ] + _include_secondary_support = true + if (_include_64_bit_webview) { + shared_libraries += [ "//android_webview:monochrome" ] + _include_primary_support = true + } + } + } else { + shared_libraries += [ "//chrome/android:libmonochrome" ] + _include_primary_support = true + } + + deps += [ + "//android_webview/glue:glue_java", + "//android_webview/nonembedded:nonembedded_java", + ] + if (!_is_bundle_module) { + deps += [ "//chrome/android:monochrome_java" ] + } + + if (_include_primary_support) { + deps += [ + "//android_webview:monochrome_webview_primary_abi_assets", + "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline", + ] + loadable_modules += + [ "$root_out_dir/libcrashpad_handler_trampoline.so" ] + } + if (_include_secondary_support) { + _trampoline = + "//third_party/crashpad/crashpad/handler:" + + "crashpad_handler_trampoline($android_secondary_abi_toolchain)" + + deps += [ + "//android_webview:monochrome_webview_secondary_abi_assets", + _trampoline, + ] + + _secondary_out_dir = get_label_info(_trampoline, "root_out_dir") + secondary_abi_loadable_modules += + [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ] + } + + if (defined(invoker.alternative_android_sdk_dep)) { + alternative_android_sdk_dep = invoker.alternative_android_sdk_dep + } else { + alternative_android_sdk_dep = webview_framework_dep + } + if (defined(invoker.app_as_shared_lib)) { + app_as_shared_lib = invoker.app_as_shared_lib + } else { + app_as_shared_lib = true + } + _pak_prefix = "monochrome" + } + if (is_trichrome) { + # Include placeholder libraries to make Chrome multiarch in the same way + # as Monochrome, even though Chrome only runs with one of the two + # bitnesses. This allows the "32-bit" and "64-bit" versions of Chrome to + # depend on their respective versions of the shared library APK even + # though they're functionally the same. + if (android_64bit_target_cpu) { + if (invoker.is_64_bit_browser) { + native_lib_placeholders += [ "libdummy.so" ] + if (_include_32_bit_webview) { + secondary_native_lib_placeholders += [ "libdummy.so" ] + } + } else { + secondary_native_lib_placeholders += [ "libdummy.so" ] + if (_include_64_bit_webview) { + native_lib_placeholders += [ "libdummy.so" ] + } + } + } else { + native_lib_placeholders += [ "libdummy.so" ] + } + + _pak_prefix = "trichrome_chrome" + } + + # The Chromium Linker depends on ASharedMemory_create() introduced in O. + use_chromium_linker = is_trichrome && chromium_linker_supported + + if (build_hwasan_splits && android_64bit_target_cpu && + invoker.is_64_bit_browser) { + _hwasan_toolchain = + "//build/toolchain/android:android_clang_arm64_hwasan" + shared_libraries += + [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ] + + if (use_chromium_linker) { + shared_libraries += [ + "//base/android/linker:chromium_android_linker($_hwasan_toolchain)", + ] + } + } + + # We only optimize resources in bundles. + if (_is_bundle_module) { + # Resources config for blocklisting resource names from obfuscation + resources_config_paths = [ + "//android_webview/aapt2.config", + "//chrome/android/aapt2.config", + ] + if (defined(invoker.resources_config_paths)) { + resources_config_paths += invoker.resources_config_paths + } + } + + if (defined(invoker.never_incremental)) { + never_incremental = invoker.never_incremental + } else if (!defined(invoker.target_type) || + invoker.target_type == "android_apk") { + # Incremental install doesn't work for monochrome. See crbug.com/663492. + } + + # Strip xml namespaces for monochrome. This should only be done for apks + # targeting API > 21 which for chrome is only Monochrome. This is due to + # how android public and private resource ids are namespaced. + if (defined(invoker.no_xml_namespaces)) { + no_xml_namespaces = invoker.no_xml_namespaces + } else { + no_xml_namespaces = true + } + + if (_is_bundle_module) { + _pak_prefix += "_bundle_module" + } else { + _pak_prefix += "_apk" + } + deps += [ "//chrome/android:${_pak_prefix}_pak_assets" ] + + if (!is_java_debug) { + proguard_configs = [] + if (defined(invoker.proguard_configs)) { + proguard_configs += invoker.proguard_configs + } + if (is_monochrome) { + proguard_configs += + [ "//android_webview/nonembedded/java/proguard.flags" ] } } } - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - forward_variables_from(invoker, - "*", - TESTONLY_AND_VISIBILITY + [ - "deps", - "shared_libraries", - "loadable_modules", - "secondary_abi_shared_libraries", - "secondary_abi_loadable_modules", - "data_deps", - "proguard_configs", - "manifest_package", - "version_code", - "assert_no_deps", - "version_name", - "resources_config_paths", - ]) - } -} - -# For creating chrome targets without internal customizations. -template("chrome_public_apk_or_module_tmpl") { - chrome_common_apk_or_module_tmpl(target_name) { - _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome - _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome - _is_bundle = invoker.target_type == "android_app_bundle_module" - - deps = [] - if (defined(invoker.deps)) { - deps += invoker.deps - } - if (_is_monochrome) { - deps += upstream_only_webview_deps - } else if (!_is_trichrome) { - deps += [ - "//chrome/android:chrome_public_apk_base_module_resources", - "//chrome/android:chrome_public_base_module_java", - "//chrome/android:chrome_public_non_pak_assets", - "//components/browser_ui/styles/android:chrome_public_apk_resources", - ] - } - if (_is_bundle) { - deps += [ - # deps in delegate_public_impl_java are put into the Chrome module, but the language deps - # are needed by the base module. - "//components/language/android:ulp_delegate_public_java", - ] - } else { - deps += [ "//chrome/android:delegate_public_impl_java" ] - } - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY + [ "deps" ]) - } -} - -# TODO(https://crbug.com/1427610): Remove. -template("monochrome_public_common_apk_or_module_tmpl") { - chrome_common_apk_or_module_tmpl(target_name) { - forward_variables_from(invoker, "*") - if (!defined(is_monochrome)) { - is_trichrome = true - } - } -} -template("chrome_public_common_apk_or_module_tmpl") { - chrome_common_apk_or_module_tmpl(target_name) { - forward_variables_from(invoker, "*") + # The _overrides scope is used to ensure that: + # * Values set in invoker cannot accidentally clobber values set in + # _overrides. + # * Values set in _overrides cannot accidentaly clobber values set in + # invoker (since the forward_variables_from will fail). + _override_args = [ + "alternative_android_sdk_dep", + "app_as_shared_lib", + "deps", + "is_monochrome", + "is_trichrome", + "isolated_splits_enabled", + "loadable_modules", + "native_lib_placeholders", + "never_incremental", + "no_xml_namespaces", + "product_config_java_packages", + "proguard_configs", + "resources_config_paths", + "secondary_abi_loadable_modules", + "secondary_abi_shared_libraries", + "secondary_native_lib_placeholders", + "shared_libraries", + "use_chromium_linker", + "webview_product_config_java_package", + ] + forward_variables_from(invoker, "*", _override_args) + forward_variables_from(_overrides, _override_args) } }
diff --git a/chrome/android/chrome_test_apk_tmpl.gni b/chrome/android/chrome_test_apk_tmpl.gni index b9d6791..5ca00db6a 100644 --- a/chrome/android/chrome_test_apk_tmpl.gni +++ b/chrome/android/chrome_test_apk_tmpl.gni
@@ -4,40 +4,50 @@ import("//chrome/android/chrome_public_apk_tmpl.gni") +# Dependencies that are common to any chrome_public derivative targets. +chrome_public_shared_deps = [ + "//chrome/android:chrome_app_java_resources", + "//chrome/android:chrome_public_apk_base_module_resources", + "//chrome/android:chrome_public_base_module_java", + "//chrome/android:chrome_public_non_pak_assets", + "//components/browser_ui/styles/android:chrome_public_apk_resources", + "//gin:v8_snapshot_assets", + "//third_party/icu:icu_assets", +] + chrome_public_test_manifest_package = "org.chromium.chrome.tests" template("chrome_test_apk_tmpl") { - chrome_common_apk_or_module_tmpl(target_name) { + chrome_public_common_apk_or_module_tmpl(target_name) { testonly = true target_type = "instrumentation_test_apk" bundles_supported = true - - if (!defined(invoker.is_monochrome)) { - jinja_input = "//chrome/android/javatests/AndroidManifest.xml" - manifest_package = chrome_public_test_manifest_package - } + jinja_input = "//chrome/android/javatests/AndroidManifest.xml" + manifest_package = chrome_public_test_manifest_package shared_libraries = [ "//chrome/android:libchromefortest" ] - deps = [ - "//chrome/android:chrome_public_base_module_java_for_test", - "//third_party/android_sdk:android_test_base_java", - "//third_party/android_sdk:android_test_mock_java", - "//third_party/android_sdk:android_test_runner_java", - "//third_party/androidx:androidx_test_runner_java", - ] - if (defined(invoker.deps)) { - deps += invoker.deps - } + deps = chrome_public_shared_deps + invoker.deps + [ + "//chrome/android:chrome_apk_pak_assets", + "//chrome/android:chrome_public_base_module_java_for_test", + "//third_party/android_sdk:android_test_base_java", + "//third_party/android_sdk:android_test_mock_java", + "//third_party/android_sdk:android_test_runner_java", + "//third_party/androidx:androidx_test_runner_java", + ] if (add_unwind_tables_in_chrome_32bit_apk && current_cpu == "arm") { deps += [ "//chrome/android:libchromefortest_unwind_table_assets" ] } + if (enable_vr) { + # Contains VrFirstRunActivity, which is referenced by AndroidManifest.xml. + deps += [ "//chrome/android/features/vr:java" ] + } - # For EmbeddedTestServer. additional_apks = [ "//net/android:net_test_support_apk" ] if (defined(invoker.additional_apks)) { additional_apks += invoker.additional_apks } if (!is_java_debug) { + proguard_enabled = true proguard_configs = [ "//chrome/android/proguard/apk_for_test.flags" ] if (defined(invoker.proguard_configs)) { proguard_configs += invoker.proguard_configs @@ -58,18 +68,54 @@ } } -# TODO(agrieve): Delete this and have all tests use chrome_test_apk_tmpl. template("monochrome_test_apk_tmpl") { - chrome_test_apk_tmpl(target_name) { - is_monochrome = true - manifest_package = chrome_public_manifest_package + monochrome_public_common_apk_or_module_tmpl(target_name) { + forward_variables_from(invoker, + [ + "apk_name", + "data_deps", + "is_64_bit_browser", + "include_64_bit_webview", + "include_32_bit_webview", + "loadable_modules", + "proguard_configs", + "secondary_abi_loadable_modules", + "target_sdk_version", + ]) + testonly = true + target_type = "instrumentation_test_apk" + + # TODO(agrieve): Add: manifest_package = chrome_public_test_manifest_package jinja_input = "//chrome/android/javatests/AndroidManifest_monochrome.xml" jinja_extra_includes = [ "//chrome/android/javatests/AndroidManifest.xml" ] jinja_extra_variables = [ "test_manifest_package=$chrome_public_test_manifest_package" ] - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) + deps = chrome_public_shared_deps + invoker.deps + [ + "//android_webview:platform_service_bridge_upstream_implementation_java", + "//chrome/android:chrome_public_base_module_java_for_test", + "//chrome/android:monochrome_apk_pak_assets", + "//third_party/android_sdk:android_test_base_java", + "//third_party/android_sdk:android_test_mock_java", + "//third_party/android_sdk:android_test_runner_java", + "//third_party/androidx:androidx_test_runner_java", + ] + + if (webview_includes_weblayer) { + deps += [ "//weblayer/browser/java:upstream_java" ] + } + + additional_apks = [ "//net/android:net_test_support_apk" ] + if (defined(invoker.additional_apks)) { + additional_apks += invoker.additional_apks + } + if (!is_java_debug) { + if (!defined(proguard_configs)) { + proguard_configs = [] + } + proguard_enabled = true + proguard_configs += [ "//chrome/android/proguard/apk_for_test.flags" ] + } } }
diff --git a/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml b/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml new file mode 100644 index 0000000..ab57ae2 --- /dev/null +++ b/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2023 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/autofill_address_profile_prompt_source_notice" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="@dimen/dialog_padding_sides" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" + tools:text="@string/autofill_save_in_account_prompt_address_source_notice" />
diff --git a/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml new file mode 100644 index 0000000..59923bb --- /dev/null +++ b/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml
@@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2023 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="true"> + + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/address_prompt_end_margin" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + layout="@layout/autofill_address_profile_prompt_source_notice" /> + + <org.chromium.ui.widget.ChromeImageButton + android:id="@+id/edit_button" + android:layout_width="@dimen/address_prompt_edit_button_size" + android:layout_height="@dimen/address_prompt_edit_button_size" + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/address_prompt_end_margin" + android:layout_marginTop="8dp" + android:layout_below="@+id/autofill_address_profile_prompt_source_notice" + android:padding="@dimen/address_prompt_edit_button_padding" + android:background="?attr/selectableItemBackground" + android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip" + android:scaleType="fitCenter" + app:srcCompat="@drawable/edit_icon" + app:tint="@color/default_icon_color_tint_list" /> + + <LinearLayout + android:id="@+id/address_data" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/autofill_address_profile_prompt_source_notice" + android:layout_toStartOf="@id/edit_button" + android:paddingTop="12dp" + android:paddingStart="@dimen/dialog_padding_sides" + android:orientation="vertical"> + + <org.chromium.ui.widget.TextViewWithLeading + android:id="@+id/address" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="12dp" + android:textAppearance="@style/TextAppearance.TextLarge.Secondary" + app:leading="@dimen/text_size_large_leading" + tools:text="John Doe\n1600 Amphitheatre Parkway\nMountain View,, CA, 94043\nUnited States" /> + + <TextView + android:id="@+id/email" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextLarge.Secondary" + tools:text="xyz@example.com" /> + + <TextView + android:id="@+id/phone" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextLarge.Secondary" + tools:text="+1 111 111 0000" /> + + </LinearLayout> + </RelativeLayout> +</ScrollView>
diff --git a/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml index 1f58d5e4..7232249 100644 --- a/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml +++ b/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml
@@ -20,17 +20,16 @@ <org.chromium.ui.widget.ChromeImageButton android:id="@+id/edit_button" - android:layout_width="48dp" - android:layout_height="48dp" + android:layout_width="@dimen/address_prompt_edit_button_size" + android:layout_height="@dimen/address_prompt_edit_button_size" android:layout_alignParentEnd="true" - android:layout_marginEnd="8dp" - android:padding="12dp" + android:layout_marginEnd="@dimen/address_prompt_end_margin" + android:padding="@dimen/address_prompt_edit_button_padding" android:background="?attr/selectableItemBackground" android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip" android:scaleType="fitCenter" app:srcCompat="@drawable/edit_icon" - app:tint="@color/default_icon_color_tint_list" - tools:src="@drawable/edit_icon" /> + app:tint="@color/default_icon_color_tint_list" /> <LinearLayout android:id="@+id/address_data" @@ -39,8 +38,7 @@ android:layout_toStartOf="@id/edit_button" android:paddingTop="@dimen/dialog_padding_top" android:paddingStart="@dimen/dialog_padding_sides" - android:orientation="vertical" - tools:ignore="RtlSymmetry"> + android:orientation="vertical"> <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/address" @@ -49,21 +47,21 @@ android:layout_marginBottom="12dp" android:textAppearance="@style/TextAppearance.TextLarge.Secondary" app:leading="@dimen/text_size_large_leading" - tools:text="Alex Park\n345 High Street\nSan Francisco, CA, 94105\nUnited States" /> + tools:text="John Doe\n1600 Amphitheatre Parkway\nMountain View, CA, 94043\nUnited States" /> <TextView android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextLarge.Secondary" - tools:text="alex.park@gmail.com" /> + tools:text="xyz@example.com" /> <TextView android:id="@+id/phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextLarge.Secondary" - tools:text="+1 858 230 4000" /> + tools:text="+1 111 111 0000" /> </LinearLayout> @@ -94,6 +92,12 @@ android:textAppearance="@style/TextAppearance.TextLarge.Secondary" /> </com.google.android.material.textfield.TextInputLayout> - <include layout="@layout/autofill_save_update_address_profile_prompt_footer"/> + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/address_prompt_end_margin" + android:layout_marginTop="20dp" + android:layout_below="@+id/nickname_input_layout" + layout="@layout/autofill_address_profile_prompt_source_notice" /> </RelativeLayout> </ScrollView>
diff --git a/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml b/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml deleted file mode 100644 index 33a168f..0000000 --- a/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml +++ /dev/null
@@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<merge - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"> - <TextView - android:id="@+id/autofill_save_update_address_profile_prompt_footer" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingStart="@dimen/dialog_padding_sides" - android:paddingTop="12dp" - android:paddingBottom="8dp" - android:textAppearance="@style/TextAppearance.TextMedium.Secondary" - tools:text="@string/autofill_save_in_account_prompt_address_source_notice" /> -</merge>
diff --git a/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml index 01ec7b41..19263a74 100644 --- a/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml +++ b/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml
@@ -20,7 +20,7 @@ android:ellipsize="end" android:maxLines="1" android:textAppearance="@style/TextAppearance.TextMedium.Secondary" - tools:text="For Alex Park — 345 Spear street" /> + tools:text="For John Doe — 1600 Amphitheatre Parkway" /> <org.chromium.components.browser_ui.widget.FadingEdgeScrollView android:layout_width="match_parent" @@ -38,8 +38,7 @@ <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="@dimen/dialog_padding_sides" - tools:ignore="RtlSymmetry"> + android:paddingStart="@dimen/dialog_padding_sides"> <Space android:id="@+id/no_header_space" @@ -67,23 +66,22 @@ android:layout_toStartOf="@id/edit_button" android:textAppearance="@style/TextAppearance.TextLarge.Primary" app:leading="@dimen/text_size_large_leading" - tools:text="Alex Johnson Park\n+1 858 230 4000" /> + tools:text="John Robert Doe\n+1 111 111 0000" /> <org.chromium.ui.widget.ChromeImageButton android:id="@+id/edit_button" - android:layout_width="48dp" - android:layout_height="48dp" + android:layout_width="@dimen/address_prompt_edit_button_size" + android:layout_height="@dimen/address_prompt_edit_button_size" android:layout_alignBaseline="@id/details_new" android:layout_alignParentEnd="true" - android:layout_marginEnd="8dp" + android:layout_marginEnd="@dimen/address_prompt_end_margin" android:baseline="32dp" - android:padding="12dp" + android:padding="@dimen/address_prompt_edit_button_padding" android:background="?attr/selectableItemBackground" android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip" android:scaleType="fitCenter" app:srcCompat="@drawable/edit_icon" - app:tint="@color/default_icon_color_tint_list" - tools:src="@drawable/edit_icon" /> + app:tint="@color/default_icon_color_tint_list" /> </RelativeLayout> <TextView @@ -105,9 +103,14 @@ android:paddingEnd="@dimen/dialog_padding_sides" android:textAppearance="@style/TextAppearance.TextLarge.Primary" app:leading="@dimen/text_size_large_leading" - tools:text="Alex Park" /> + tools:text="John Doe" /> </LinearLayout> </org.chromium.components.browser_ui.widget.FadingEdgeScrollView> - <include layout="@layout/autofill_save_update_address_profile_prompt_footer"/> + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/address_prompt_end_margin" + android:layout_marginTop="12dp" + layout="@layout/autofill_address_profile_prompt_source_notice" /> </LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 9ad0fea1..8723345 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -71,6 +71,11 @@ <!-- Sheet tab toolbar dimensions --> <dimen name="sheet_tab_toolbar_height">70dp</dimen> + <!-- Autofill address prompt dimensions --> + <dimen name="address_prompt_end_margin">8dp</dimen> + <dimen name="address_prompt_edit_button_size">48dp</dimen> + <dimen name="address_prompt_edit_button_padding">12dp</dimen> + <!-- Autofill keyboard accessory dimensions --> <dimen name="keyboard_accessory_height_with_shadow">56dp</dimen> <dimen name="keyboard_accessory_sheet_height">330dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java index d090920..343df72 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
@@ -35,6 +35,7 @@ /** * Prompt that asks users to confirm saving an address profile imported from a form submission. + * TODO(crbug.com/1432549): cover with render tests. */ @JNINamespace("autofill") @JNIAdditionalImport(PersonalDataManager.class) @@ -58,10 +59,15 @@ mModalDialogManager = modalDialogManager; LayoutInflater inflater = LayoutInflater.from(activity); - mDialogView = inflater.inflate(isUpdate ? R.layout.autofill_update_address_profile_prompt - : R.layout.autofill_save_address_profile_prompt, - null); - if (!isUpdate) setupAddressNickname(); + if (isMigrationToAccount) { + mDialogView = inflater.inflate(R.layout.autofill_migrate_address_profile_prompt, null); + } else if (isUpdate) { + mDialogView = inflater.inflate(R.layout.autofill_update_address_profile_prompt, null); + } else { + mDialogView = inflater.inflate(R.layout.autofill_save_address_profile_prompt, null); + } + + if (!isUpdate && !isMigrationToAccount) setupAddressNickname(); PropertyModel.Builder builder = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) @@ -146,7 +152,7 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) void setSourceNotice(String sourceNotice) { showTextIfNotEmpty( - mDialogView.findViewById(R.id.autofill_save_update_address_profile_prompt_footer), + mDialogView.findViewById(R.id.autofill_address_profile_prompt_source_notice), sourceNotice); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java index 8dbdc43..cc71ac16b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
@@ -448,7 +448,10 @@ .replace("$1", email); } - return mContext.getString(R.string.autofill_address_will_be_saved_in_account_source_notice) + return mContext + .getString(mIsMigrationToAccount + ? R.string.autofill_address_will_be_migrated_to_account_source_notice + : R.string.autofill_address_will_be_saved_in_account_source_notice) .replace("$1", email); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java index 33b80b5b..6195f177 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
@@ -23,7 +23,6 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RequiresRestart; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; @@ -31,7 +30,6 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; import org.chromium.chrome.test.util.OmniboxTestUtils; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil; import org.chromium.components.browser_ui.site_settings.PermissionInfo; import org.chromium.components.content_settings.ContentSettingValues; @@ -44,7 +42,6 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION}) @Batch(Batch.PER_CLASS) public class GeolocationHeaderTest { public @ClassRule static ChromeTabbedActivityTestRule sActivityTestRule =
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java index b5085838..dbefba7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java
@@ -91,10 +91,14 @@ } private void createAndShowPrompt(boolean isUpdate) { + createAndShowPrompt(isUpdate, NO_MIGRATION); + } + + private void createAndShowPrompt(boolean isUpdate, boolean isMigrationToAccount) { AutofillProfile dummyProfile = new AutofillProfile(); mModalDialogManager = new FakeModalDialogManager(ModalDialogType.APP); mPrompt = new SaveUpdateAddressProfilePrompt(mPromptController, mModalDialogManager, - mActivity, mProfile, dummyProfile, isUpdate, NO_MIGRATION); + mActivity, mProfile, dummyProfile, isUpdate, isMigrationToAccount); mPrompt.setAddressEditorForTesting(mAddressEditor); mPrompt.show(); } @@ -170,10 +174,29 @@ propertyModel.get(ModalDialogProperties.POSITIVE_BUTTON_TEXT)); Assert.assertEquals("negative button text", propertyModel.get(ModalDialogProperties.NEGATIVE_BUTTON_TEXT)); + } + + @Test + @SmallTest + public void dialogStrings_SourceNotice() { + createAndShowPrompt(false, true); + View dialog = mPrompt.getDialogViewForTesting(); + + mPrompt.setSourceNotice(null); + Assert.assertEquals(View.GONE, + dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice) + .getVisibility()); + + mPrompt.setSourceNotice(""); + Assert.assertEquals(View.GONE, + dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice) + .getVisibility()); mPrompt.setSourceNotice("source notice"); - validateTextView( - dialog.findViewById(R.id.autofill_save_update_address_profile_prompt_footer), + Assert.assertEquals(View.VISIBLE, + dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice) + .getVisibility()); + validateTextView(dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice), "source notice"); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java index 142dd19..678bc80c 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
@@ -470,7 +470,8 @@ .replace("$1", USER_EMAIL); final String sourceNotice = mActivity - .getString(R.string.autofill_address_will_be_saved_in_account_source_notice) + .getString( + R.string.autofill_address_will_be_migrated_to_account_source_notice) .replace("$1", USER_EMAIL); checkUiStringsHaveExpectedValues(
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni index c693f23..32ebe22 100644 --- a/chrome/android/trichrome.gni +++ b/chrome/android/trichrome.gni
@@ -44,14 +44,6 @@ invoker.include_64_bit_webview) && android_64bit_target_cpu _include_32_bit_webview = !defined(invoker.include_32_bit_webview) || invoker.include_32_bit_webview - _include_primary_abi = - !android_64bit_target_cpu || _is_64_bit_browser || _include_64_bit_webview - _include_secondary_abi = android_64bit_target_cpu && - (!_is_64_bit_browser || _include_32_bit_webview) - if (_include_secondary_abi) { - _secondary_out_dir = - get_label_info("X($android_secondary_abi_toolchain)", "root_out_dir") - } _version_code = TRICHROME_VERSION_MAP["${android_64bit_target_cpu}_${_is_64_bit_browser}_${_include_64_bit_webview}_${_include_32_bit_webview}"] # TODO(crbug.com/1411557): Remove option for custom manifest. @@ -95,35 +87,40 @@ expected_android_manifest_library_version_offset = chrome_version_code } - omit_dex = true + # TODO(torne): since there's no real java code in the library right now, + # leave out the build hooks and let them get compiled into each APK. Later + # this should probably be in the library. + no_build_hooks = true include_size_info = is_official_build + alternative_android_sdk_dep = webview_framework_dep r_java_root_package_name = "trichrome_lib" app_as_shared_lib = true - version_name = chrome_version_name - version_code = _version_code - min_sdk_version = 29 # No support for this has been added, also not supported by test runner # since trichrome library is used in "additional_apks" in the trichrome # bundle smoke tests. never_incremental = true + version_name = chrome_version_name + version_code = _version_code + min_sdk_version = 29 + # TODO(torne): using icon_resources just to get a temporary icon deps = [ "//android_webview/nonembedded:icon_resources", "//third_party/icu:icu_assets", ] - if (_include_primary_abi) { - deps += [ "//gin:v8_snapshot_assets" ] - } - if (_include_secondary_abi) { - deps += [ "//gin:v8_snapshot_secondary_abi_assets" ] - } if (defined(invoker.deps)) { deps += invoker.deps } + omit_dex = true + + # Flag whether additional deps and libs should be included for each ABI. + _include_primary_support = false + _include_secondary_support = false + if (android_64bit_target_cpu) { # Include the actual browser-bitness libmonochrome library, dependencies # (crashpad and linker), and an opposite-bitness placeholder library to @@ -131,54 +128,64 @@ # precompiled for both architectures. if (_is_64_bit_browser) { shared_libraries = [ "//chrome/android:libmonochrome_64" ] + _include_primary_support = true if (_include_32_bit_webview) { secondary_native_lib_placeholders = [ "libdummy.so" ] } - if (build_hwasan_splits) { - _hwasan_toolchain = - "//build/toolchain/android:android_clang_arm64_hwasan" - shared_libraries += - [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ] - } } else { secondary_abi_shared_libraries = [ "//chrome/android:monochrome_secondary_abi_lib" ] + _include_secondary_support = true if (invoker.include_64_bit_webview) { native_lib_placeholders = [ "libdummy.so" ] } } } else { shared_libraries = [ "//chrome/android:libmonochrome" ] + _include_primary_support = true } - # https://chromium.googlesource.com/chromium/src/+/main/docs/android_native_libraries.md#Crashpad-Packaging - loadable_modules = [] - secondary_abi_loadable_modules = [] - if (_include_primary_abi) { + if (_include_primary_support) { deps += [ + "//gin:v8_snapshot_assets", "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline", ] - loadable_modules += [ "$root_out_dir/libcrashpad_handler_trampoline.so" ] + loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ] } - if (_include_secondary_abi) { - deps += [ "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)" ] - secondary_abi_loadable_modules += + if (_include_secondary_support) { + _trampoline = + "//third_party/crashpad/crashpad/handler:" + + "crashpad_handler_trampoline($android_secondary_abi_toolchain)" + deps += [ + "//gin:v8_snapshot_secondary_abi_assets", + _trampoline, + ] + _secondary_out_dir = get_label_info(_trampoline, "root_out_dir") + secondary_abi_loadable_modules = [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ] } if (enable_arcore) { - _arcore_target = "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" - _libarcore_dir = get_label_info(_arcore_target, "target_out_dir") + - "/com_google_ar_core_java/jni" - deps += [ "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" ] + _libarcore_dir = get_label_info( + "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)", + "target_out_dir") + "/com_google_ar_core_java/jni" + not_needed([ "_libarcore_dir" ]) - if (_include_primary_abi) { + _arcore_extra_deps = [ "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" ] + not_needed([ "_arcore_extra_deps" ]) + + if (_include_primary_support) { loadable_modules += [ "$_libarcore_dir/$android_app_abi/libarcore_sdk_c.so" ] + deps += _arcore_extra_deps } - if (_include_secondary_abi) { - secondary_abi_loadable_modules += - [ "$_libarcore_dir/$android_app_secondary_abi/libarcore_sdk_c.so" ] + if (_include_secondary_support) { + if (enable_arcore) { + secondary_abi_loadable_modules += [ + "$_libarcore_dir/$android_app_secondary_abi/libarcore_sdk_c.so", + ] + deps += _arcore_extra_deps + } } } forward_variables_from(invoker,
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index ef67dd3..7e1d696 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -809,6 +809,12 @@ </message> </if> + <if expr="is_win or is_macosx or is_linux"> + <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item" translateable="false"> + Not used in Chromium. Placeholder to keep resource maps in sync. + </message> + </if> + <if expr="is_macosx"> <message name="IDS_APP_MENU_PRODUCT_NAME" desc="The application's short name, used for the Mac's application menu, activity monitor, etc. This should be less than 16 characters. Example: Chrome, not Google Chrome."> Chromium @@ -1151,6 +1157,15 @@ </message> </if> + <if expr="is_win or is_macosx or is_linux"> + <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT" desc="Alternate window title for the Update Recommended dialog." translateable="false"> + Not used in Chromium. Placeholder to keep resource maps in sync. + </message> + <message name="IDS_UPDATE_RECOMMENDED_ALT" desc="Alternate main text of the Update Recommended dialog with a count of open Incognito windows." translateable="false"> + Not used in Chromium. Placeholder to keep resource maps in sync. + </message> + </if> + <!-- Update bubble --> <message name="IDS_REINSTALL_APP" desc="Text for the button the user clicks to reinstall the app."> Reinstall Chromium @@ -1663,16 +1678,6 @@ <!-- High Efficiency IPH strings --> <if expr="not is_android"> <if expr="use_titlecase"> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency info mode in-product promo bubble."> - Memory Saver Made Chromium Faster - </message> - </if> - <if expr="not use_titlecase"> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="The title for the high efficiency info mode in-product promo bubble."> - Memory Saver made Chromium faster - </message> - </if> - <if expr="use_titlecase"> <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency mode in-product promo bubble"> Make Chromium Faster </message>
diff --git a/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 deleted file mode 100644 index 57350014..0000000 --- a/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -eaa33f2365a0520981c4befc57752f11bcb7c169 \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index daaefb1..eae13c0b 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -7113,6 +7113,9 @@ <message name="IDS_NTP_MODULES_CART_LOWER_YOUR" desc="Name of the chrome cart module in lowercase shown in various UIs."> your carts </message> + <message name="IDS_NTP_MODULES_QUEST_CART_ANNOTATION" desc="Annotation that shows in the ChromeCart tile in Quest module to let users know that this tile is from pending items in their shopping cart."> + In your cart + </message> <message name="IDS_NTP_MODULES_CART_INFO" desc="Text shown in the body of the info dialog of the cart module."> You’re seeing carts that help you easily get back to items you left in shopping carts across the web. <ph name="BREAK"><br></ph> @@ -8215,12 +8218,6 @@ <message name="IDS_BATTERY_SAVER_MODE_PROMO_ACTION_TEXT" desc="The custom action button text for the battery saver mode in-product promo bubble."> Settings </message> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT" desc="The text shown for the high efficiency info mode in-product promo bubble."> - While this tab was inactive, Memory Saver freed up memory for other tasks. You can change this anytime in settings. - </message> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT" desc="The custom action button text for the high efficiency info mode in-product promo bubble."> - Settings - </message> <if expr="use_titlecase"> <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TEXT" desc="The text shown for the high efficiency mode in-product promo bubble"> Memory Saver frees up memory from inactive tabs so it can be used by active tabs and other apps. @@ -9424,6 +9421,17 @@ <message name="IDS_APP_MENU_BUTTON_UPDATE" desc="Short label next to app-menu button when an update is available."> Update </message> + <if expr="is_win or is_macosx or is_linux"> + <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT1" desc="Alternate short label next to app-menu button when an update is available."> + Finish update + </message> + <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT2" desc="Alternate short label next to app-menu button when an update is available."> + Relaunch to update + </message> + <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT3" desc="Alternate short label next to app-menu button when an update is available."> + New Chrome available + </message> + </if> <message name="IDS_APP_MENU_BUTTON_ERROR" desc="Short label next to app-menu button when the user needs to resolve something."> Error </message>
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1 new file mode 100644 index 0000000..d7cea84b --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1
@@ -0,0 +1 @@ +1fac87ea606325d799531ef8259ba0fe70160b09 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1 new file mode 100644 index 0000000..5a6b1f0 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1
@@ -0,0 +1 @@ +5692a2825f4a8a23c74e6f8748262c5aa4ed4afd \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1 new file mode 100644 index 0000000..584487b --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1
@@ -0,0 +1 @@ +9f7a1df62265c683ec4715ce2aca59fc4ace2382 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1 deleted file mode 100644 index 57350014..0000000 --- a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -eaa33f2365a0520981c4befc57752f11bcb7c169 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1 deleted file mode 100644 index a62c876..0000000 --- a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e67acd8cde024be973d3cc91ee0a51fe09424138 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1 new file mode 100644 index 0000000..56cfdb39 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1
@@ -0,0 +1 @@ +e8fc28f080b143a15e0697e7af6e8619b450e155 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 0b81272..15ee610 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -840,6 +840,19 @@ </if> </if> + <if expr="is_win or is_macosx or is_linux"> + <if expr="use_titlecase"> + <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item"> + Relaunch to Update - Your tabs will reopen + </message> + </if> + <if expr="not use_titlecase"> + <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item"> + Relaunch to update - your tabs will reopen + </message> + </if> + </if> + <if expr="is_macosx"> <message name="IDS_APP_MENU_PRODUCT_NAME" desc="The application's short name, used for the Mac's application menu, activity monitor, etc. This should be less than 16 characters. Example: Chrome, not Google Chrome."> Chrome @@ -1222,6 +1235,18 @@ </message> </if> + <if expr="is_win or is_macosx or is_linux"> + <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT" desc="Alternate window title for the Update Recommended dialog."> + Relaunch to finish Chrome update + </message> + <message name="IDS_UPDATE_RECOMMENDED_ALT" desc="Alternate main text of the Update Recommended dialog with a count of open Incognito windows."> + {COUNT, plural, + =0 {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen.} + =1 {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen. Your Incognito window won't reopen.} + other {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen. Your # Incognito windows won't reopen.}} + </message> + </if> + <!-- Update bubble --> <message name="IDS_REINSTALL_APP" desc="Text for the button the user clicks to reinstall the app."> Reinstall Chrome @@ -1754,16 +1779,6 @@ <!-- High Efficiency IPH strings --> <if expr="not is_android"> <if expr="use_titlecase"> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency info mode in-product promo bubble."> - Memory Saver Made Chrome Faster - </message> - </if> - <if expr="not use_titlecase"> - <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="The title for the high efficiency info mode in-product promo bubble."> - Memory Saver made Chrome faster - </message> - </if> - <if expr="use_titlecase"> <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency mode in-product promo bubble"> Make Chrome Faster </message>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 deleted file mode 100644 index c9923a4..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -0f37ea118551945bad92e6bde0773b369114d6ff \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1 new file mode 100644 index 0000000..9b37dc5 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1
@@ -0,0 +1 @@ +84f4e2d903db457de773ed4f64c91da4b03d8257 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1 new file mode 100644 index 0000000..9c0bbef --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1
@@ -0,0 +1 @@ +43c15cefa091a229407f18c12b0026d4c0abf977 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1 new file mode 100644 index 0000000..c05a802 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1
@@ -0,0 +1 @@ +16e4a1d3a5391eb7f5bfe1abf45675fb29a81797 \ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index c896c4e..0ace4ced 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -82,6 +82,7 @@ "input.icon", "journeys.icon", "key.icon", + "key_chrome_refresh.icon", "keyboard_arrow_down.icon", "keyboard_arrow_right.icon", "keyboard_arrow_up.icon", @@ -187,6 +188,7 @@ "text_increase.icon", "trailing_scroll.icon", "translate.icon", + "translate_chrome_refresh.icon", "trash_can.icon", "trash_can_light.icon", "tv.icon",
diff --git a/chrome/app/vector_icons/key_chrome_refresh.icon b/chrome/app/vector_icons/key_chrome_refresh.icon new file mode 100644 index 0000000..9465ddf --- /dev/null +++ b/chrome/app/vector_icons/key_chrome_refresh.icon
@@ -0,0 +1,49 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 6, 15, +R_CUBIC_TO, -1.39f, 0, -2.57f, -0.49f, -3.54f, -1.46f, +CUBIC_TO, 1.49f, 12.57f, 1, 11.39f, 1, 10, +R_CUBIC_TO, 0, -1.39f, 0.49f, -2.57f, 1.46f, -3.54f, +CUBIC_TO, 3.43f, 5.49f, 4.61f, 5, 6, 5, +R_CUBIC_TO, 1, 0, 1.92f, 0.27f, 2.77f, 0.8f, +R_CUBIC_TO, 0.85f, 0.53f, 1.45f, 1.27f, 1.81f, 2.2f, +H_LINE_TO, 19, +R_V_LINE_TO, 4, +R_H_LINE_TO, -2, +R_V_LINE_TO, 3, +R_H_LINE_TO, -4, +R_V_LINE_TO, -3, +R_H_LINE_TO, -2.42f, +R_ARC_TO, 4.62f, 4.62f, 0, 0, 1, -1.82f, 2.2f, +CUBIC_TO, 7.92f, 14.73f, 7, 15, 6, 15, +CLOSE, +R_MOVE_TO, 0, -1.5f, +R_CUBIC_TO, 0.86f, 0, 1.61f, -0.28f, 2.25f, -0.85f, +R_CUBIC_TO, 0.64f, -0.57f, 1.06f, -1.28f, 1.25f, -2.15f, +R_H_LINE_TO, 5, +R_V_LINE_TO, 3, +R_H_LINE_TO, 1, +R_V_LINE_TO, -3, +R_H_LINE_TO, 2, +R_V_LINE_TO, -1, +R_H_LINE_TO, -8, +R_CUBIC_TO, -0.19f, -0.86f, -0.61f, -1.58f, -1.25f, -2.15f, +CUBIC_TO_SHORTHAND, 6.86f, 6.5f, 6, 6.5f, +R_CUBIC_TO, -0.97f, 0, -1.8f, 0.34f, -2.48f, 1.02f, +CUBIC_TO_SHORTHAND, 2.5f, 9.03f, 2.5f, 10, +R_CUBIC_TO, 0, 0.97f, 0.34f, 1.8f, 1.02f, 2.48f, +CUBIC_TO_SHORTHAND, 5.03f, 13.5f, 6, 13.5f, +CLOSE, +MOVE_TO, 6, 12, +R_CUBIC_TO, 0.55f, 0, 1.02f, -0.2f, 1.41f, -0.59f, +R_CUBIC_TO, 0.39f, -0.39f, 0.59f, -0.86f, 0.59f, -1.41f, +R_CUBIC_TO, 0, -0.55f, -0.2f, -1.02f, -0.59f, -1.41f, +CUBIC_TO, 7.02f, 8.2f, 6.55f, 8, 6, 8, +R_CUBIC_TO, -0.55f, 0, -1.02f, 0.2f, -1.41f, 0.59f, +CUBIC_TO, 4.2f, 8.98f, 4, 9.45f, 4, 10, +R_CUBIC_TO, 0, 0.55f, 0.2f, 1.02f, 0.59f, 1.41f, +R_CUBIC_TO, 0.39f, 0.39f, 0.86f, 0.59f, 1.41f, 0.59f, +CLOSE
diff --git a/chrome/app/vector_icons/translate_chrome_refresh.icon b/chrome/app/vector_icons/translate_chrome_refresh.icon index 574af77..e839a51 100644 --- a/chrome/app/vector_icons/translate_chrome_refresh.icon +++ b/chrome/app/vector_icons/translate_chrome_refresh.icon
@@ -2,73 +2,46 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 13.6f, 3.1f, -LINE_TO, 7.22f, 3.1f, -LINE_TO, 6.6f, 1, -LINE_TO, 2.4f, 1, -CUBIC_TO, 1.63f, 1, 1, 1.63f, 1, 2.4f, -LINE_TO, 1, 11.5f, -CUBIC_TO, 1, 12.27f, 1.63f, 12.9f, 2.4f, 12.9f, -LINE_TO, 7.3f, 12.9f, -LINE_TO, 8, 15, -LINE_TO, 13.6f, 15, -CUBIC_TO, 14.37f, 15, 15, 14.37f, 15, 13.6f, -LINE_TO, 15, 4.5f, -CUBIC_TO, 15, 3.73f, 14.37f, 3.1f, 13.6f, 3.1f, -LINE_TO, 13.6f, 3.1f, +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 10.17f, 18, +R_LINE_TO, 3.56f, -9.5f, +R_H_LINE_TO, 1.71f, +LINE_TO, 19, 18, +R_H_LINE_TO, -1.65f, +R_LINE_TO, -0.85f, -2.44f, +R_H_LINE_TO, -3.83f, +LINE_TO, 11.82f, 18, +R_H_LINE_TO, -1.65f, CLOSE, -MOVE_TO, 4.62f, 9.81f, -CUBIC_TO, 3.04f, 9.81f, 1.76f, 8.53f, 1.76f, 6.95f, -CUBIC_TO, 1.76f, 5.37f, 3.04f, 4.09f, 4.62f, 4.09f, -CUBIC_TO, 5.35f, 4.09f, 6.01f, 4.35f, 6.54f, 4.84f, -LINE_TO, 6.59f, 4.88f, -LINE_TO, 5.73f, 5.7f, -LINE_TO, 5.68f, 5.67f, -CUBIC_TO, 5.48f, 5.48f, 5.14f, 5.26f, 4.62f, 5.26f, -CUBIC_TO, 3.7f, 5.26f, 2.95f, 6.02f, 2.95f, 6.95f, -CUBIC_TO, 2.95f, 7.88f, 3.7f, 8.64f, 4.62f, 8.64f, -CUBIC_TO, 5.58f, 8.64f, 5.99f, 8.04f, 6.1f, 7.62f, -LINE_TO, 4.56f, 7.62f, -LINE_TO, 4.56f, 6.54f, -LINE_TO, 7.32f, 6.54f, -LINE_TO, 7.33f, 6.59f, -CUBIC_TO, 7.36f, 6.73f, 7.36f, 6.87f, 7.36f, 7.01f, -CUBIC_TO, 7.36f, 8.66f, 6.24f, 9.81f, 4.62f, 9.81f, -LINE_TO, 4.62f, 9.81f, +R_MOVE_TO, 3, -3.81f, +H_LINE_TO, 16, +R_LINE_TO, -1.38f, -3.94f, +R_H_LINE_TO, -0.08f, +R_LINE_TO, -1.38f, 3.94f, CLOSE, -MOVE_TO, 8.84f, 8.62f, -CUBIC_TO, 9.07f, 9.04f, 9.36f, 9.44f, 9.67f, 9.81f, -LINE_TO, 9.3f, 10.18f, -LINE_TO, 8.84f, 8.62f, -LINE_TO, 8.84f, 8.62f, -CLOSE, -MOVE_TO, 13.6f, 14.3f, -LINE_TO, 8.7f, 14.3f, -LINE_TO, 10.1f, 12.9f, -LINE_TO, 9.53f, 10.96f, -LINE_TO, 10.18f, 10.32f, -LINE_TO, 12.05f, 12.2f, -LINE_TO, 12.56f, 11.69f, -LINE_TO, 10.67f, 9.81f, -CUBIC_TO, 11.3f, 9.09f, 11.79f, 8.24f, 12.01f, 7.36f, -LINE_TO, 12.9f, 7.36f, -LINE_TO, 12.9f, 6.63f, -LINE_TO, 10.35f, 6.63f, -LINE_TO, 10.35f, 5.9f, -LINE_TO, 9.62f, 5.9f, -LINE_TO, 9.62f, 6.63f, -LINE_TO, 8.25f, 6.63f, -LINE_TO, 7.43f, 3.8f, -LINE_TO, 13.6f, 3.8f, -CUBIC_TO, 13.99f, 3.8f, 14.3f, 4.12f, 14.3f, 4.5f, -LINE_TO, 14.3f, 13.6f, -CUBIC_TO, 14.3f, 13.99f, 13.99f, 14.3f, 13.6f, 14.3f, -CLOSE, -MOVE_TO, 8.69f, 8.08f, -LINE_TO, 8.47f, 7.36f, -LINE_TO, 11.26f, 7.36f, -CUBIC_TO, 11.26f, 7.36f, 11.02f, 8.27f, 10.17f, 9.27f, -CUBIC_TO, 9.81f, 8.84f, 9.55f, 8.41f, 9.38f, 8.08f, -LINE_TO, 8.69f, 8.08f, +MOVE_TO, 3.52f, 15.5f, +R_LINE_TO, -1.04f, -1.06f, +R_LINE_TO, 4, -3.96f, +R_CUBIC_TO, -0.5f, -0.53f, -0.97f, -1.08f, -1.4f, -1.65f, +R_CUBIC_TO, -0.43f, -0.57f, -0.81f, -1.19f, -1.13f, -1.85f, +R_H_LINE_TO, 1.71f, +R_CUBIC_TO, 0.25f, 0.44f, 0.53f, 0.86f, 0.85f, 1.25f, +R_CUBIC_TO, 0.32f, 0.39f, 0.65f, 0.77f, 0.98f, 1.15f, +R_CUBIC_TO, 0.53f, -0.58f, 1.01f, -1.19f, 1.46f, -1.82f, +R_CUBIC_TO, 0.45f, -0.63f, 0.81f, -1.32f, 1.08f, -2.05f, +H_LINE_TO, 1, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 5.75f, +V_LINE_TO, 2, +R_H_LINE_TO, 1.5f, +R_V_LINE_TO, 2, +H_LINE_TO, 14, +R_V_LINE_TO, 1.5f, +R_H_LINE_TO, -2.38f, +R_CUBIC_TO, -0.29f, 0.96f, -0.72f, 1.84f, -1.27f, 2.66f, +R_CUBIC_TO, -0.56f, 0.81f, -1.17f, 1.59f, -1.83f, 2.32f, +R_LINE_TO, 1.9f, 1.88f, +R_LINE_TO, -0.58f, 1.54f, +R_LINE_TO, -2.33f, -2.33f, +R_LINE_TO, -3.98f, 3.94f, CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index f59b9a4..ca38016 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -7443,16 +7443,14 @@ "supervised_user/supervised_user_settings_service_factory.h", ] if (is_chromeos_ash) { - sources += [ - "supervised_user/chromeos/web_content_handler_impl.cc", - "supervised_user/chromeos/web_content_handler_impl.h", - ] deps += [ "//chrome/browser/ash/crosapi" ] } if (is_chromeos) { sources += [ "supervised_user/chromeos/supervised_user_favicon_request_handler.cc", "supervised_user/chromeos/supervised_user_favicon_request_handler.h", + "supervised_user/chromeos/web_content_handler_impl.cc", + "supervised_user/chromeos/web_content_handler_impl.h", ] } deps += [
diff --git a/chrome/browser/ash/crosapi/network_settings_service_ash.cc b/chrome/browser/ash/crosapi/network_settings_service_ash.cc index a1b4e8e..9449e8c 100644 --- a/chrome/browser/ash/crosapi/network_settings_service_ash.cc +++ b/chrome/browser/ash/crosapi/network_settings_service_ash.cc
@@ -121,15 +121,15 @@ // Required to display the extension which is controlling the proxy in the OS // Settings > Network > Proxy window. - base::Value proxy_extension(base::Value::Type::DICT); - proxy_extension.SetStringKey(kPrefExtensionNameKey, - proxy_config->extension->name); - proxy_extension.SetStringKey(kPrefExtensionIdKey, - proxy_config->extension->id); - proxy_extension.SetBoolKey(kPrefExtensionCanDisabledKey, - proxy_config->extension->can_be_disabled); - pref_service->Set(ash::prefs::kLacrosProxyControllingExtension, - std::move(proxy_extension)); + base::Value::Dict proxy_extension = + base::Value::Dict() + .Set(kPrefExtensionNameKey, proxy_config->extension->name) + .Set(kPrefExtensionIdKey, proxy_config->extension->id) + .Set(kPrefExtensionCanDisabledKey, + proxy_config->extension->can_be_disabled); + + pref_service->SetDict(ash::prefs::kLacrosProxyControllingExtension, + std::move(proxy_extension)); pref_service->SetDict(proxy_config::prefs::kProxy, CrosapiProxyToProxyConfig(std::move(proxy_config))
diff --git a/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc b/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc index 59e079e..5a6efbc 100644 --- a/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc +++ b/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ash/crosapi/network_settings_service_ash.h" #include "ash/constants/ash_pref_names.h" -#include "base/functional/callback.h" #include "base/test/repeating_test_future.h" #include "chrome/browser/ash/crosapi/network_settings_translation.h" #include "chrome/browser/browser_process.h" @@ -13,10 +12,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_browser_process.h" -#include "chromeos/ash/components/dbus/dbus_thread_manager.h" #include "chromeos/ash/components/dbus/shill/shill_profile_client.h" #include "chromeos/ash/components/dbus/shill/shill_service_client.h" -#include "chromeos/ash/components/network/network_state.h" #include "chromeos/ash/components/network/network_state_handler.h" #include "chromeos/crosapi/mojom/network_settings_service.mojom.h" #include "components/policy/core/browser/browser_policy_connector.h" @@ -30,9 +27,7 @@ #include "components/proxy_config/proxy_config_pref_names.h" #include "components/proxy_config/proxy_prefs.h" #include "content/public/test/browser_test.h" -#include "net/base/proxy_server.h" #include "third_party/cros_system_api/dbus/shill/dbus-constants.h" -#include "url/url_constants.h" namespace { @@ -208,18 +203,21 @@ ProxyConfigDictionary proxy_config_dict(std::move(proxy_dict)); auto proxy_config = crosapi::ProxyConfigToCrosapiProxy(&proxy_config_dict, - /*wpad_url=*/GURL("")); + /*dhcp_wpad_url=*/GURL("")); proxy_config->extension = crosapi::mojom::ExtensionControllingProxy::New(); proxy_config->extension->name = kExtensionName; proxy_config->extension->id = kExtensionId; proxy_config->extension->can_be_disabled = can_be_disabled; network_service_ash_->SetExtensionProxy(std::move(proxy_config)); - base::Value expected_pref(base::Value::Type::DICT); - expected_pref.SetStringKey(kPrefExtensionNameKey, kExtensionName); - expected_pref.SetStringKey(kPrefExtensionIdKey, kExtensionId); - expected_pref.SetBoolKey(kPrefExtensionCanDisabled, can_be_disabled); - WaitForLacrosProxyControllingExtensionPref(std::move(expected_pref)); + base::Value::Dict expected_pref = + base::Value::Dict() + .Set(kPrefExtensionNameKey, kExtensionName) + .Set(kPrefExtensionIdKey, kExtensionId) + .Set(kPrefExtensionCanDisabled, can_be_disabled); + + WaitForLacrosProxyControllingExtensionPref( + base::Value(std::move(expected_pref))); } void WaitForLacrosProxyControllingExtensionPref( @@ -270,8 +268,7 @@ result = observer_->WaitForProxyConfig(); ASSERT_FALSE(result.is_null()); EXPECT_TRUE(result->extension.is_null()); - EXPECT_EQ(*(extension_proxy_pref->GetValue()), - base::Value(base::Value::Type::DICT)); + EXPECT_EQ(*(extension_proxy_pref->GetValue()), base::Value::Dict()); // proxy_mode=system is the default value (see // PrefProxyConfigTrackerImpl::RegisterProfilePrefs). EXPECT_EQ(*(proxy_pref->GetValue()), ProxyConfigDictionary::CreateSystem()); @@ -330,8 +327,8 @@ ProxyConfigDictionary proxy_config_dict( ProxyConfigDictionary::CreatePacScript(kPacUrl, /*pac_mandatory=*/true)); - auto proxy_config = crosapi::ProxyConfigToCrosapiProxy(&proxy_config_dict, - /*wpad_url=*/GURL("")); + auto proxy_config = crosapi::ProxyConfigToCrosapiProxy( + &proxy_config_dict, /*dhcp_wpad_url=*/GURL("")); proxy_config->extension = crosapi::mojom::ExtensionControllingProxy::New(); proxy_config->extension->name = kExtensionName; proxy_config->extension->id = kExtensionId;
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc index 5f472dd7..bba2b919 100644 --- a/chrome/browser/ash/login/chrome_restart_request.cc +++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -185,7 +185,6 @@ blink::switches::kEnableRasterSideDarkModeForImages, blink::switches::kEnableZeroCopy, blink::switches::kGpuRasterizationMSAASampleCount, - blink::switches::kNumRasterThreads, switches::kAshPowerButtonPosition, switches::kAshSideVolumeButtonPosition, switches::kDefaultWallpaperLarge, @@ -202,6 +201,7 @@ cc::switches::kEnableGpuBenchmarking, cc::switches::kEnableMainFrameBeforeActivation, cc::switches::kHighlightNonLCDTextLayers, + cc::switches::kNumRasterThreads, cc::switches::kShowCompositedLayerBorders, cc::switches::kShowFPSCounter, cc::switches::kShowLayerAnimationBounds,
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn index 773d3bf..2efae0bb 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
@@ -30,8 +30,6 @@ "fast_pair_advertiser.h", "fido_assertion_info.cc", "fido_assertion_info.h", - "incoming_connection.cc", - "incoming_connection.h", "random_session_id.cc", "random_session_id.h", "target_device_connection_broker.cc", @@ -85,7 +83,6 @@ "authenticated_connection_unittest.cc", "connection_unittest.cc", "fast_pair_advertiser_unittest.cc", - "incoming_connection_unittest.cc", "target_device_connection_broker_impl_unittest.cc", ] }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc index d69eb5f6..9960f0f 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc
@@ -69,7 +69,8 @@ int32_t session_id, RequestWifiCredentialsCallback callback) { // Build the Wifi Credential Request payload - std::string shared_secret_str(shared_secret_.begin(), shared_secret_.end()); + std::string shared_secret_str(secondary_shared_secret_.begin(), + secondary_shared_secret_.end()); SendMessage( requests::BuildRequestWifiCredentialsMessage(session_id, shared_secret_str),
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc index 3a6539c..2584266 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc
@@ -139,11 +139,9 @@ EXPECT_TRUE(wifi_request_payload.FindBool("request_wifi")); EXPECT_EQ(wifi_request_payload.FindInt("SESSION_ID"), session_id); - std::string shared_secret_str(kSharedSecret.begin(), kSharedSecret.end()); - std::string shared_secret_base64; - base::Base64Encode(shared_secret_str, &shared_secret_base64); - EXPECT_EQ(*wifi_request_payload.FindString("shared_secret"), - shared_secret_base64); + // TODO(b/234655072): Create kSecondarySharedSecret const and check value + // equals after AuthenticatedConnection refactor is merged. + EXPECT_TRUE(wifi_request_payload.FindString("shared_secret")); } TEST_F(AuthenticatedConnectionTest, RequestAccountTransferAssertion) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc index ba0bc9a5..c9f7c80 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
@@ -17,12 +17,15 @@ SharedSecret shared_secret) : nearby_connection_(nearby_connection), random_session_id_(session_id), - shared_secret_(shared_secret) {} + shared_secret_(shared_secret) { + crypto::RandBytes(secondary_shared_secret_); +} Connection::Connection(NearbyConnection* nearby_connection, RandomSessionId session_id) : nearby_connection_(nearby_connection), random_session_id_(session_id) { crypto::RandBytes(shared_secret_); + crypto::RandBytes(secondary_shared_secret_); } void Connection::SendPayload(const base::Value::Dict& message_payload) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h index 66be7a0..8ac8311e 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
@@ -43,6 +43,7 @@ NearbyConnection* nearby_connection_; RandomSessionId random_session_id_; SharedSecret shared_secret_; + SharedSecret secondary_shared_secret_; }; } // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc index c88dd18..c89095de 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
@@ -16,15 +16,15 @@ namespace { -// Arbitrary string to use as the connection's authentication token. -constexpr char kAuthenticationToken[] = "auth_token"; - // 32 random bytes to use as the shared secret. constexpr std::array<uint8_t, 32> kSharedSecret = { 0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59, 0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4, 0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2}; +// Arbitrary string to use as the connection's authentication token when +// deriving PIN. +constexpr char kAuthenticationToken[] = "auth_token"; } // namespace FakeTargetDeviceConnectionBroker::Factory::Factory() = default; @@ -52,6 +52,7 @@ void FakeTargetDeviceConnectionBroker::StartAdvertising( ConnectionLifecycleListener* listener, + bool use_pin_authentication, ResultCallback on_start_advertising_callback) { ++num_start_advertising_calls_; connection_lifecycle_listener_ = listener; @@ -66,15 +67,14 @@ void FakeTargetDeviceConnectionBroker::InitiateConnection( const std::string& source_device_id) { - auto random_session_id = RandomSessionId(); - fake_nearby_connection_ = std::make_unique<FakeNearbyConnection>(); - NearbyConnection* nearby_connection = fake_nearby_connection_.get(); - fake_quick_start_decoder_ = std::make_unique<FakeQuickStartDecoder>(); - auto fake_incomming_connection = std::make_unique<FakeIncommingConnection>( - nearby_connection, random_session_id, kAuthenticationToken); - connection_lifecycle_listener_->OnIncomingConnectionInitiated( - source_device_id, fake_incomming_connection->AsWeakPtr()); - fake_connection_ = std::move(fake_incomming_connection); + if (use_pin_authentication_) { + connection_lifecycle_listener_->OnPinVerificationRequested( + DerivePin(kAuthenticationToken)); + } else { + auto random_session_id = RandomSessionId(); + connection_lifecycle_listener_->OnQRCodeVerificationRequested( + GetQrCodeData(random_session_id, kSharedSecret)); + } } void FakeTargetDeviceConnectionBroker::AuthenticateConnection(
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h index 4a945a90..f6c347e1d 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
@@ -9,14 +9,14 @@ #include <vector> #include "chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/fake_quick_start_decoder.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_factory.h" -#include "chrome/browser/nearby_sharing/fake_nearby_connection.h" + +class FakeNearbyConnection; namespace ash::quick_start { +class FakeQuickStartDecoder; class RandomSessionId; class FakeTargetDeviceConnectionBroker : public TargetDeviceConnectionBroker { @@ -49,13 +49,6 @@ std::vector<FakeTargetDeviceConnectionBroker*> instances_; }; - class FakeIncommingConnection - : public IncomingConnection, - public base::SupportsWeakPtr<FakeIncommingConnection> { - public: - using IncomingConnection::IncomingConnection; - }; - class FakeAuthenticatedConnection : public AuthenticatedConnection, public base::SupportsWeakPtr<FakeAuthenticatedConnection> { @@ -72,6 +65,7 @@ // TargetDeviceConnectionBroker: FeatureSupportStatus GetFeatureSupportStatus() const override; void StartAdvertising(ConnectionLifecycleListener* listener, + bool use_pin_authentication, ResultCallback on_start_advertising_callback) override; void StopAdvertising(base::OnceClosure on_stop_advertising_callback) override; void InitiateConnection(const std::string& source_device_id); @@ -84,6 +78,10 @@ MaybeNotifyFeatureStatus(); } + void set_use_pin_authentication(bool use_pin_authentication) { + use_pin_authentication_ = use_pin_authentication; + } + size_t num_start_advertising_calls() const { return num_start_advertising_calls_; }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc deleted file mode 100644 index 0538e87..0000000 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h" - -#include "base/base64url.h" -#include "base/hash/sha1.h" -#include "base/strings/string_number_conversions.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" -#include "crypto/random.h" - -namespace ash::quick_start { - -IncomingConnection::IncomingConnection(NearbyConnection* nearby_connection, - RandomSessionId session_id, - const std::string& authentication_token) - : Connection(nearby_connection, session_id), - pin_(DerivePin(authentication_token)) {} - -IncomingConnection::IncomingConnection(NearbyConnection* nearby_connection, - RandomSessionId session_id, - const std::string& authentication_token, - SharedSecret shared_secret) - : Connection(nearby_connection, session_id, shared_secret), - pin_(DerivePin(authentication_token)) {} - -IncomingConnection::~IncomingConnection() = default; - -std::string IncomingConnection::DerivePin( - const std::string& authentication_token) { - std::string hash_str = base::SHA1HashString(authentication_token); - std::vector<int8_t> hash_ints = - std::vector<int8_t>(hash_str.begin(), hash_str.end()); - - return base::NumberToString( - std::abs((hash_ints[0] << 8 | hash_ints[1]) % 10)) + - base::NumberToString( - std::abs((hash_ints[2] << 8 | hash_ints[3]) % 10)) + - base::NumberToString( - std::abs((hash_ints[4] << 8 | hash_ints[5]) % 10)) + - base::NumberToString( - std::abs((hash_ints[6] << 8 | hash_ints[7]) % 10)); -} - -std::vector<uint8_t> IncomingConnection::GetQrCodeData() const { - std::string shared_secret_str(shared_secret_.begin(), shared_secret_.end()); - std::string shared_secret_base64; - base::Base64UrlEncode(shared_secret_str, - base::Base64UrlEncodePolicy::OMIT_PADDING, - &shared_secret_base64); - - std::string url = "https://signin.google/qs/" + - random_session_id_.ToString() + - "?key=" + shared_secret_base64; - - return std::vector<uint8_t>(url.begin(), url.end()); -} - -} // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h deleted file mode 100644 index 1427ea7..0000000 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_ -#define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_ - -#include <array> - -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" - -namespace ash::quick_start { - -// Represents a new incoming connection that has not yet been accepted by the -// remote source device. -class IncomingConnection : public Connection { - public: - IncomingConnection(NearbyConnection* nearby_connection, - RandomSessionId session_id, - const std::string& authentication_token); - - // An alternate constructor that accepts a shared_secret for testing purposes - // or for resuming a connection after a critical update. - IncomingConnection(NearbyConnection* nearby_connection, - RandomSessionId session_id, - const std::string& authentication_token, - std::array<uint8_t, 32> shared_secret); - - IncomingConnection(IncomingConnection&) = delete; - IncomingConnection& operator=(IncomingConnection&) = delete; - ~IncomingConnection() override; - - // Derive a 4-digit decimal pin code from the authentication token. This is - // meant to match the Android implementation found here: - // http://google3/java/com/google/android/gmscore/integ/modules/smartdevice/src/com/google/android/gms/smartdevice/d2d/nearby/advertisement/VerificationUtils.java;l=37;rcl=511361463 - static std::string DerivePin(const std::string& authentication_token); - - // Returns a deep link URL as a vector of bytes that will form the QR code - // used to authenticate the connection. - std::vector<uint8_t> GetQrCodeData() const; - - // Return the 4-digit pin code to be displayed for the user to match against - // the source device in order to authenticate the connection. Derived from the - // Nearby Connection's authentication token. - std::string GetConnectionVerificationPin() const { return pin_; } - - private: - // A 4-digit decimal pin code derived from the connection's authentication - // token for the alternative pin authentication flow. - std::string pin_; -}; - -} // namespace ash::quick_start - -#endif // CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc deleted file mode 100644 index 3743fa5..0000000 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h" - -#include <memory> - -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" -#include "chrome/browser/nearby_sharing/fake_nearby_connection.h" -#include "chrome/browser/nearby_sharing/public/cpp/nearby_connection.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace ash::quick_start { - -namespace { - -// Base qr code url ("https://signin.google/qs/") represented in a 25 byte -// array. -constexpr std::array<uint8_t, 25> kBaseUrl = { - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x71, 0x73, 0x2f}; - -// Qr code key param ("?key=") represented in a 5 byte array. -constexpr std::array<uint8_t, 5> kUrlKeyParam = {0x3f, 0x6b, 0x65, 0x79, 0x3d}; - -// 6 random bytes to use as the RandomSessionId. -constexpr std::array<uint8_t, 6> kRandomSessionId = {0x6b, 0xb3, 0x85, - 0x27, 0xbb, 0x28}; - -// Base64 representation of kRandomSessionId. -constexpr char kRandomSessionIdBase64[] = "a7OFJ7so"; - -// 32 random bytes to use as the shared secret. -constexpr std::array<uint8_t, 32> kSharedSecret = { - 0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59, - 0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4, - 0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2}; - -// Base64 representation of kSharedSecret. -constexpr char kSharedSecretBase64[] = - "VL1Az4p8L2rKFVnP8-sxCJBz79qH1CPAVdWDWwQoSfI"; - -// Arbitrary string to use as the connection's authentication token. -constexpr char kAuthenticationToken[] = "auth_token"; - -// Pin corresponding to |kAuthenticationToken|. -constexpr char kAuthenticationTokenPin[] = "6229"; - -} // namespace - -class IncomingConnectionTest : public testing::Test { - public: - IncomingConnectionTest(const IncomingConnectionTest&) = delete; - IncomingConnectionTest& operator=(const IncomingConnectionTest&) = delete; - - protected: - IncomingConnectionTest() = default; - - void SetUp() override { - RandomSessionId session_id(kRandomSessionId); - fake_nearby_connection_ = std::make_unique<FakeNearbyConnection>(); - NearbyConnection* nearby_connection = fake_nearby_connection_.get(); - incoming_connection_ = std::make_unique<IncomingConnection>( - nearby_connection, session_id, kAuthenticationToken, kSharedSecret); - } - - std::unique_ptr<IncomingConnection> incoming_connection_; - std::unique_ptr<FakeNearbyConnection> fake_nearby_connection_; -}; - -TEST_F(IncomingConnectionTest, TestGetQrCodeData) { - std::string session_id(kRandomSessionIdBase64); - std::string shared_secret(kSharedSecretBase64); - - std::vector<uint8_t> expected_data(std::begin(kBaseUrl), std::end(kBaseUrl)); - expected_data.insert(expected_data.end(), session_id.begin(), - session_id.end()); - expected_data.insert(expected_data.end(), std::begin(kUrlKeyParam), - std::end(kUrlKeyParam)); - expected_data.insert(expected_data.end(), shared_secret.begin(), - shared_secret.end()); - - std::vector<uint8_t> actual_data = incoming_connection_->GetQrCodeData(); - - EXPECT_EQ(expected_data, actual_data); -} - -TEST_F(IncomingConnectionTest, GetConnectionVerificationPin) { - EXPECT_EQ(kAuthenticationTokenPin, - incoming_connection_->GetConnectionVerificationPin()); -} - -} // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc index 70efd57..64229175 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc
@@ -4,9 +4,11 @@ #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h" -namespace ash::quick_start { +#include "base/base64url.h" +#include "base/hash/sha1.h" +#include "base/strings/string_number_conversions.h" -// TODO impl +namespace ash::quick_start { TargetDeviceConnectionBroker::TargetDeviceConnectionBroker() = default; TargetDeviceConnectionBroker::~TargetDeviceConnectionBroker() = default; @@ -29,4 +31,34 @@ } } +std::vector<uint8_t> TargetDeviceConnectionBroker::GetQrCodeData( + const RandomSessionId& random_session_id, + const Connection::SharedSecret shared_secret) const { + std::string shared_secret_str(shared_secret.begin(), shared_secret.end()); + std::string shared_secret_base64; + base::Base64UrlEncode(shared_secret_str, + base::Base64UrlEncodePolicy::OMIT_PADDING, + &shared_secret_base64); + + std::string url = "https://signin.google/qs/" + random_session_id.ToString() + + "?key=" + shared_secret_base64; + + return std::vector<uint8_t>(url.begin(), url.end()); +} + +std::string TargetDeviceConnectionBroker::DerivePin( + const std::string& authentication_token) const { + std::string hash_str = base::SHA1HashString(authentication_token); + std::vector<int8_t> hash_ints = + std::vector<int8_t>(hash_str.begin(), hash_str.end()); + return base::NumberToString( + std::abs((hash_ints[0] << 8 | hash_ints[1]) % 10)) + + base::NumberToString( + std::abs((hash_ints[2] << 8 | hash_ints[3]) % 10)) + + base::NumberToString( + std::abs((hash_ints[4] << 8 | hash_ints[5]) % 10)) + + base::NumberToString( + std::abs((hash_ints[6] << 8 | hash_ints[7]) % 10)); +} + } // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h index 0ea3c05..d6d576d 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
@@ -9,11 +9,12 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h" +#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" namespace ash::quick_start { class AuthenticatedConnection; -class IncomingConnection; // TargetDeviceConnectionBroker is the entrypoint for consuming the Quick Start // connectivity component. Calling code is expected to get an instance of this @@ -45,24 +46,21 @@ ConnectionLifecycleListener() = default; virtual ~ConnectionLifecycleListener() = default; - // A basic encrypted channel has been created between this target device and - // the remote source device. The connection has been blindly accepted by - // this target device, but it is the responsibility of the source device to - // make an informed choice to accept. The user of the source device makes - // this decision by inspecting the UI of this target device, which is - // expected to display the metadata that the IncomingConnection object - // provides (QR Code or shapes/PIN matching). - // - // The IncomingConnection pointer may be cached, but will become invalid - // after either OnConnectionAuthenticated(), OnConnectionRejected(), or - // OnConnectionClosed() are called. - // - // Use source_device_id to understand which connection - // OnConnectionAuthenticated(), OnConnectionRejected(), or - // OnConnectionClosed() refers to. - virtual void OnIncomingConnectionInitiated( - const std::string& source_device_id, - base::WeakPtr<IncomingConnection> connection) = 0; + // A connection has been initiated between this target device and the remote + // source device, but needs to be authenticated before messages can be + // exchanged. The source device has requested that the pin be displayed so + // that the user can check that the codes match, thereby authenticating the + // connection. + virtual void OnPinVerificationRequested(const std::string& pin) = 0; + + // A connection has been initiated between this target device and the remote + // source device, but needs to be authenticated before messages can be + // exchanged. The source device has requested that the QR code be displayed + // so that the user can scan the code. After scanning, the source device + // will accept the connection, and a cryptographic handshake using a secret + // contained in the QR code will be used to authenticate the connection. + virtual void OnQRCodeVerificationRequested( + const std::vector<uint8_t>& qr_code_data) = 0; // Called after both sides have accepted the connection. // @@ -101,15 +99,22 @@ // Will kick off Fast Pair and Nearby Connections advertising. // Clients can use the result of |on_start_advertising_callback| to // immediately understand if advertising succeeded, and can then wait for the - // source device to connect via - // |ConnectionLifecycleListener::OnIncomingConnectionInitiated()|. + // source device to connect and request authentication via + // |ConnectionLifecycleListener::OnPinVerificationRequested()| or + // |ConnectionLifecycleListener::OnQRCodeVerificationRequested()|. // // If the caller paused a connection previously, the connection to the // source device will resume via OnConnectionAuthenticated(). // Clients should check GetFeatureSupportStatus() before calling // StartAdvertising(). + // + // If |use_pin_authentication| is true, then the target device will + // advertise its preference to use pin authentication instead of QR code + // authentication. This should be false unless the user would benefit from + // using pin for, e.g. accessibility reasons. virtual void StartAdvertising( ConnectionLifecycleListener* listener, + bool use_pin_authentication, ResultCallback on_start_advertising_callback) = 0; // Clients are responsible for calling this once they have accepted their @@ -120,6 +125,21 @@ protected: void MaybeNotifyFeatureStatus(); + // Returns a deep link URL as a vector of bytes that will form the QR code + // used to authenticate the connection. + std::vector<uint8_t> GetQrCodeData( + const RandomSessionId& random_session_id, + const Connection::SharedSecret shared_secret) const; + + // Derive a 4-digit decimal pin code from the authentication token. This is + // meant to match the Android implementation found here: + // http://google3/java/com/google/android/gmscore/integ/modules/smartdevice/src/com/google/android/gms/smartdevice/d2d/nearby/advertisement/VerificationUtils.java;l=37;rcl=511361463 + std::string DerivePin(const std::string& authentication_token) const; + + // Determines whether the advertisement info sent to the source device will + // request pin verification or QR code verification. + bool use_pin_authentication_ = false; + private: std::vector<FeatureSupportStatusCallback> feature_status_callbacks_; };
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc index 433989f..28c8d8a 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
@@ -11,14 +11,13 @@ #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/fast_pair_advertiser.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" #include "chrome/browser/ash/login/oobe_quick_start/logging/logging.h" +#include "crypto/random.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "ui/chromeos/devicetype_utils.h" @@ -31,10 +30,12 @@ constexpr uint8_t kEndpointInfoVersion = 1; // Smart Setup verification style, e.g. QR code, pin, etc. -// 6 = "DIGITS", which tells the phone to display a code for the user to match. +// 5 = "OUT_OF_BAND", which tells the phone to scan for the QR code. +// 6 = "DIGITS", which tells the phone to display a PIN for the user to match.// // Values come from the TargetConnectionInfo VerificationStyle enum: -constexpr uint8_t kEndpointInfoVerificationStyle = 6; - +// http://google3/logs/proto/wireless/android/smartsetup/smart_setup_extension.proto;l=894;rcl=489739066 +constexpr uint8_t kEndpointInfoVerificationStyleOutOfBand = 5; +constexpr uint8_t kEndpointInfoVerificationStyleDigits = 6; // Device Type for Smart Setup, e.g. phone, tablet. 8 = "Chrome" // Values come from the DiscoveryEvent DeviceType enum: // http://google3/logs/proto/wireless/android/smartsetup/smart_setup_extension.proto;l=985;rcl=507029311 @@ -124,6 +125,7 @@ base::WeakPtr<NearbyConnectionsManager> nearby_connections_manager) : random_session_id_(session_id), nearby_connections_manager_(nearby_connections_manager) { + crypto::RandBytes(shared_secret_); GetBluetoothAdapter(); } @@ -167,14 +169,13 @@ void TargetDeviceConnectionBrokerImpl::StartAdvertising( ConnectionLifecycleListener* listener, + bool use_pin_authentication, ResultCallback on_start_advertising_callback) { - // TODO(b/234655072): Notify client about incoming connections on the started - // advertisement via ConnectionLifecycleListener. if (GetFeatureSupportStatus() == FeatureSupportStatus::kUndetermined) { - deferred_start_advertising_callback_ = - base::BindOnce(&TargetDeviceConnectionBroker::StartAdvertising, - weak_ptr_factory_.GetWeakPtr(), listener, - std::move(on_start_advertising_callback)); + deferred_start_advertising_callback_ = base::BindOnce( + &TargetDeviceConnectionBroker::StartAdvertising, + weak_ptr_factory_.GetWeakPtr(), listener, use_pin_authentication, + std::move(on_start_advertising_callback)); return; } @@ -196,6 +197,9 @@ return; } + use_pin_authentication_ = use_pin_authentication; + connection_lifecycle_listener_ = listener; + // This will start Nearby Connections advertising if Fast Pair advertising // succeeds. StartFastPairAdvertising(std::move(on_start_advertising_callback)); @@ -269,14 +273,18 @@ // - isQuickStart, byte[12], =1 for Quick Start. // - preferTargetUserVerification, byte[13], =0 for ChromeOS. // - Pad with zeros to 60 bytes. Extra space reserved for futureproofing. -std::vector<uint8_t> TargetDeviceConnectionBrokerImpl::GenerateEndpointInfo() { +std::vector<uint8_t> TargetDeviceConnectionBrokerImpl::GenerateEndpointInfo() + const { std::string session_id = random_session_id_.ToString(); std::vector<uint8_t> display_name_bytes = GetEndpointInfoDisplayNameBytes(random_session_id_); + uint8_t verification_style = use_pin_authentication_ + ? kEndpointInfoVerificationStyleDigits + : kEndpointInfoVerificationStyleOutOfBand; std::vector<uint8_t> advertisement_data; advertisement_data.reserve(60); - advertisement_data.push_back(kEndpointInfoVerificationStyle); + advertisement_data.push_back(verification_style); advertisement_data.push_back(kEndpointInfoDeviceType); advertisement_data.insert(advertisement_data.end(), session_id.begin(), session_id.end()); @@ -368,33 +376,38 @@ void TargetDeviceConnectionBrokerImpl::OnIncomingConnectionInitiated( const std::string& endpoint_id, const std::vector<uint8_t>& endpoint_info) { - absl::optional<std::string> auth_token = - nearby_connections_manager_->GetAuthenticationToken(endpoint_id); - DCHECK(auth_token); - std::string pin = IncomingConnection::DerivePin(*auth_token); QS_LOG(INFO) << "Incoming Nearby Connection Initiated: endpoint_id=" - << endpoint_id << " pin=" << pin; + << endpoint_id + << " use_pin_authentication=" << use_pin_authentication_; - // TODO(b/234655072): Notify ConnectionLifecycleListener about the incoming - // connection if pin authentication is expected. + CHECK(connection_lifecycle_listener_); + if (use_pin_authentication_) { + absl::optional<std::string> auth_token = + nearby_connections_manager_->GetAuthenticationToken(endpoint_id); + CHECK(auth_token); + std::string pin = DerivePin(*auth_token); + QS_LOG(INFO) << "Incoming Nearby Connection Initiated: pin=" << pin; + connection_lifecycle_listener_->OnPinVerificationRequested(pin); + } else { + connection_lifecycle_listener_->OnQRCodeVerificationRequested( + GetQrCodeData(random_session_id_, shared_secret_)); + } } void TargetDeviceConnectionBrokerImpl::OnIncomingConnectionAccepted( const std::string& endpoint_id, const std::vector<uint8_t>& endpoint_info, - NearbyConnection* connection) { - absl::optional<std::string> auth_token = - nearby_connections_manager_->GetAuthenticationToken(endpoint_id); - DCHECK(auth_token); - std::unique_ptr<IncomingConnection> incoming_connection = - std::make_unique<IncomingConnection>(connection, random_session_id_, - *auth_token); + NearbyConnection* nearby_connection) { QS_LOG(INFO) << "Incoming Nearby Connection Accepted: endpoint_id=" - << endpoint_id << " pin=" - << incoming_connection->GetConnectionVerificationPin(); + << endpoint_id; - // TODO(b/234655072): Notify ConnectionLifecycleListener about the incoming - // connection so that the Quick Start flow can proceed. + connection_ = std::make_unique<Connection>( + nearby_connection, random_session_id_, shared_secret_); + + // TODO(b/234655072): Mark the connection_ authenticated if + // |use_pin_authentication_| is true. For pin verification, if the source + // device has accepted the Nearby Connection, then the connection is + // authenticated. } } // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h index 20abdc58..8b6f9c91 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_CONNECTION_BROKER_IMPL_H_ #include "base/memory/weak_ptr.h" +#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h" #include "chrome/browser/nearby_sharing/public/cpp/nearby_connections_manager.h" @@ -53,6 +54,7 @@ // TargetDeviceConnectionBroker: FeatureSupportStatus GetFeatureSupportStatus() const override; void StartAdvertising(ConnectionLifecycleListener* listener, + bool use_pin_authentication, ResultCallback on_start_advertising_callback) override; void StopAdvertising(base::OnceClosure on_stop_advertising_callback) override; @@ -65,9 +67,10 @@ void OnIncomingConnectionInitiated( const std::string& endpoint_id, const std::vector<uint8_t>& endpoint_info) override; - void OnIncomingConnectionAccepted(const std::string& endpoint_id, - const std::vector<uint8_t>& endpoint_info, - NearbyConnection* connection) override; + void OnIncomingConnectionAccepted( + const std::string& endpoint_id, + const std::vector<uint8_t>& endpoint_info, + NearbyConnection* nearby_connection) override; void GetBluetoothAdapter(); void OnGetBluetoothAdapter(scoped_refptr<device::BluetoothAdapter> adapter); @@ -78,7 +81,7 @@ // The EndpointInfo is the set of bytes that SmartSetup on Android expects to // be in the Nearby Connections advertisement. - std::vector<uint8_t> GenerateEndpointInfo(); + std::vector<uint8_t> GenerateEndpointInfo() const; void StartNearbyConnectionsAdvertising(ResultCallback callback); void StopNearbyConnectionsAdvertising(base::OnceClosure callback); @@ -89,11 +92,18 @@ base::OnceClosure callback, NearbyConnectionsManager::ConnectionsStatus status); + // A 4-digit decimal pin code derived from the connection's authentication + // token for the pin authentication flow. + std::string pin_; + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; base::OnceClosure deferred_start_advertising_callback_; std::unique_ptr<FastPairAdvertiser> fast_pair_advertiser_; RandomSessionId random_session_id_; + Connection::SharedSecret shared_secret_; + ConnectionLifecycleListener* connection_lifecycle_listener_ = nullptr; + std::unique_ptr<Connection> connection_; base::WeakPtr<NearbyConnectionsManager> nearby_connections_manager_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc index 956dcfc..48304ed6 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -28,7 +28,9 @@ namespace { constexpr size_t kMaxEndpointInfoDisplayNameLength = 18; -constexpr uint8_t kEndpointInfoVerificationStyle = 6u; +// Default verification style 5 = "OUT_OF_BAND", which tells the phone to scan +// for the QR code. +constexpr uint8_t kEndpointInfoVerificationStyle = 5u; constexpr uint8_t kEndpointInfoDeviceType = 8u; constexpr size_t kEndpointInfoRandomSessionIdLength = 10; @@ -38,6 +40,33 @@ constexpr std::array<uint8_t, 6> kRandomSessionId = {0x13, 0x5e, 0xfb, 0x0f, 0x3a, 0x20}; +// Base qr code url ("https://signin.google/qs/") represented in a 25 byte +// array. +constexpr std::array<uint8_t, 25> kBaseUrl = { + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x71, 0x73, 0x2f}; + +// Qr code key param ("?key=") represented in a 5 byte array. +constexpr std::array<uint8_t, 5> kUrlKeyParam = {0x3f, 0x6b, 0x65, 0x79, 0x3d}; + +// 32 random bytes to use as the shared secret when generating QR Code. +constexpr std::array<uint8_t, 32> kSharedSecret = { + 0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59, + 0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4, + 0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2}; + +// Base64 representation of kSharedSecret. +constexpr char kSharedSecretBase64[] = + "VL1Az4p8L2rKFVnP8-sxCJBz79qH1CPAVdWDWwQoSfI"; + +// Arbitrary string to use as the connection's authentication token when +// deriving PIN. +constexpr char kAuthenticationToken[] = "auth_token"; + +// Expected PIN corresponding to |kAuthenticationToken|. +constexpr char kAuthenticationTokenPin[] = "6229"; + // Perform base64 decoding with the kForgiving option to allow for missing // padding. std::vector<uint8_t> Base64DecodeForgiving(base::span<uint8_t> input) { @@ -282,6 +311,19 @@ ->random_session_id_; } + const std::vector<uint8_t> GetQrCodeData() { + const RandomSessionId& session_id = GetRandomSessionId(); + return static_cast<TargetDeviceConnectionBrokerImpl*>( + connection_broker_.get()) + ->GetQrCodeData(session_id, kSharedSecret); + } + + std::string DerivePin() { + return static_cast<TargetDeviceConnectionBrokerImpl*>( + connection_broker_.get()) + ->DerivePin(kAuthenticationToken); + } + protected: bool is_bluetooth_powered_ = true; bool is_bluetooth_present_ = true; @@ -330,7 +372,7 @@ EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -344,7 +386,7 @@ EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -364,7 +406,7 @@ EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -380,7 +422,7 @@ EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -396,7 +438,7 @@ EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -422,7 +464,7 @@ TEST_F(TargetDeviceConnectionBrokerImplTest, StopFastPairAdvertising_BeforeBTAdapterInitialized) { connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -442,7 +484,7 @@ FinishFetchingBluetoothAdapter(); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -542,7 +584,7 @@ EXPECT_FALSE(fake_nearby_connections_manager_.IsAdvertising()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -561,7 +603,7 @@ EXPECT_FALSE(fake_nearby_connections_manager_.IsAdvertising()); connection_broker_->StartAdvertising( - nullptr, + nullptr, /* use_pin_authentication= */ false, base::BindOnce( &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback, weak_ptr_factory_.GetWeakPtr())); @@ -573,4 +615,24 @@ EXPECT_FALSE(start_advertising_callback_success_); } +TEST_F(TargetDeviceConnectionBrokerImplTest, GetQRCodeData) { + std::string random_session_id = GetRandomSessionId().ToString(); + std::string encoded_shared_secret(kSharedSecretBase64); + + std::vector<uint8_t> expected_data(std::begin(kBaseUrl), std::end(kBaseUrl)); + expected_data.insert(expected_data.end(), random_session_id.begin(), + random_session_id.end()); + expected_data.insert(expected_data.end(), std::begin(kUrlKeyParam), + std::end(kUrlKeyParam)); + expected_data.insert(expected_data.end(), encoded_shared_secret.begin(), + encoded_shared_secret.end()); + + std::vector<uint8_t> actual_data = GetQrCodeData(); + EXPECT_EQ(expected_data, actual_data); +} + +TEST_F(TargetDeviceConnectionBrokerImplTest, DerivePin) { + EXPECT_EQ(kAuthenticationTokenPin, DerivePin()); +} + } // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc index 616e73c..293bb98 100644 --- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc +++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
@@ -8,7 +8,6 @@ #include "base/containers/contains.h" #include "base/functional/bind.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.h" -#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h" #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_factory.h" #include "chrome/browser/ash/login/oobe_quick_start/oobe_quick_start_pref_names.h" @@ -83,7 +82,7 @@ status_.step = Step::ADVERTISING; connection_broker_->StartAdvertising( - this, + this, /*use_pin_authentication=*/false, base::BindOnce(&TargetDeviceBootstrapController::OnStartAdvertisingResult, weak_ptr_factory_.GetWeakPtr())); NotifyObservers(); @@ -116,19 +115,25 @@ prepare_for_update_on_connection_closed_ = true; } -void TargetDeviceBootstrapController::OnIncomingConnectionInitiated( - const std::string& source_device_id, - base::WeakPtr<IncomingConnection> connection) { +void TargetDeviceBootstrapController::OnPinVerificationRequested( + const std::string& pin) { constexpr Step kPossibleSteps[] = {Step::ADVERTISING, Step::QR_CODE_VERIFICATION}; - DCHECK(base::Contains(kPossibleSteps, status_.step)); - if (status_.step == Step::QR_CODE_VERIFICATION) { - // New connection came. It should be a different device. - DCHECK_NE(source_device_id_, source_device_id); - } - source_device_id_ = source_device_id; - incoming_connection_ = std::move(connection); - auto qr_code = GenerateQRCode(incoming_connection_->GetQrCodeData()); + CHECK(base::Contains(kPossibleSteps, status_.step)); + + pin_ = pin; + // TODO: display pin + status_.step = Step::PIN_VERIFICATION; + status_.payload.emplace<absl::monostate>(); + NotifyObservers(); +} + +void TargetDeviceBootstrapController::OnQRCodeVerificationRequested( + const std::vector<uint8_t>& qr_code_data) { + constexpr Step kPossibleSteps[] = {Step::ADVERTISING}; + CHECK(base::Contains(kPossibleSteps, status_.step)); + + auto qr_code = GenerateQRCode(qr_code_data); status_.step = Step::QR_CODE_VERIFICATION; status_.payload.emplace<QRCodePixelData>(std::move(qr_code)); NotifyObservers(); @@ -137,10 +142,8 @@ void TargetDeviceBootstrapController::OnConnectionAuthenticated( const std::string& source_device_id, base::WeakPtr<AuthenticatedConnection> connection) { - DCHECK_EQ(source_device_id_, source_device_id); constexpr Step kPossibleSteps[] = {Step::QR_CODE_VERIFICATION}; - DCHECK(base::Contains(kPossibleSteps, status_.step)); - DCHECK(incoming_connection_.WasInvalidated()); + CHECK(base::Contains(kPossibleSteps, status_.step)); status_.step = Step::CONNECTED; status_.payload.emplace<absl::monostate>(); @@ -149,7 +152,6 @@ void TargetDeviceBootstrapController::OnConnectionRejected( const std::string& source_device_id) { - DCHECK_EQ(source_device_id_, source_device_id); status_.step = Step::ERROR; status_.payload = ErrorCode::CONNECTION_REJECTED; NotifyObservers(); @@ -157,7 +159,6 @@ void TargetDeviceBootstrapController::OnConnectionClosed( const std::string& source_device_id) { - DCHECK_EQ(source_device_id_, source_device_id); status_.step = Step::ERROR; status_.payload = ErrorCode::CONNECTION_CLOSED; NotifyObservers();
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h index fde09b8..34bbd31 100644 --- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h +++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
@@ -19,7 +19,6 @@ namespace ash::quick_start { class AuthenticatedConnection; -class IncomingConnection; class TargetDeviceBootstrapController : public TargetDeviceConnectionBroker::ConnectionLifecycleListener { @@ -36,6 +35,7 @@ ERROR, ADVERTISING, QR_CODE_VERIFICATION, + PIN_VERIFICATION, CONNECTED, GAIA_CREDENTIALS, }; @@ -89,9 +89,9 @@ void PrepareForUpdate(); // TargetDeviceConnectionBroker::ConnectionLifecycleListener: - void OnIncomingConnectionInitiated( - const std::string& source_device_id, - base::WeakPtr<IncomingConnection> connection) override; + void OnPinVerificationRequested(const std::string& pin) override; + void OnQRCodeVerificationRequested( + const std::vector<uint8_t>& qr_code_data) override; void OnConnectionAuthenticated( const std::string& source_device_id, base::WeakPtr<AuthenticatedConnection> connection) override; @@ -104,8 +104,7 @@ void OnStopAdvertising(); std::unique_ptr<TargetDeviceConnectionBroker> connection_broker_; - std::string source_device_id_; - base::WeakPtr<IncomingConnection> incoming_connection_; + std::string pin_; // TODO: Should we enforce one observer at a time here too? base::ObserverList<Observer> observers_; bool prepare_for_update_on_connection_closed_ = false;
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc index 3ce5256..d50ece5 100644 --- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc +++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
@@ -127,7 +127,7 @@ EXPECT_EQ(fake_observer_->last_status.step, Step::NONE); } -TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection) { +TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection_QRCode) { bootstrap_controller_->StartAdvertising(); connection_broker()->on_start_advertising_callback().Run(/*success=*/true); ASSERT_EQ(fake_observer_->last_status.step, Step::ADVERTISING); @@ -140,6 +140,20 @@ fake_observer_->last_status.payload)); } +TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection_Pin) { + connection_broker()->set_use_pin_authentication(true); + bootstrap_controller_->StartAdvertising(); + connection_broker()->on_start_advertising_callback().Run(/*success=*/true); + ASSERT_EQ(fake_observer_->last_status.step, Step::ADVERTISING); + + connection_broker()->InitiateConnection(kSourceDeviceId); + + EXPECT_EQ(fake_observer_->last_status.step, Step::PIN_VERIFICATION); + // TODO: Test PIN payload + EXPECT_TRUE(absl::holds_alternative<absl::monostate>( + fake_observer_->last_status.payload)); +} + TEST_F(TargetDeviceBootstrapControllerTest, AuthenticateConnection) { bootstrap_controller_->StartAdvertising(); connection_broker()->on_start_advertising_callback().Run(/*success=*/true);
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.cc b/chrome/browser/ash/login/screens/quick_start_screen.cc index 051c66b21..acea141 100644 --- a/chrome/browser/ash/login/screens/quick_start_screen.cc +++ b/chrome/browser/ash/login/screens/quick_start_screen.cc
@@ -85,6 +85,7 @@ SavePhoneInstanceID(); return; } + case Step::PIN_VERIFICATION: case Step::NONE: case Step::ERROR: case Step::ADVERTISING:
diff --git a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc index 15a025d..3eb91f2 100644 --- a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc +++ b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
@@ -83,45 +83,6 @@ constexpr char kOncRecommendedFieldsWorkaroundActionHistogram[] = "Network.Ethernet.Policy.OncRecommendedFieldsWorkaroundAction"; -// A utility to wait until a FakeShillServiceClient's service has been -// connected. -// Usage: -// (1) Construct a ServiceConnectedWaiter, specifying the shill service path -// that is expected to connect. -// (2) Call ServiceConnectedWaiter::Wait -// Wait will return when the service passed to (1) connects. If the service has -// connected between (1) and (2), Wait returns immediately. Note that this class -// does not evaluate whether the service was connected before (1). -class ServiceConnectedWaiter { - public: - ServiceConnectedWaiter( - ash::ShillServiceClient::TestInterface* shill_service_client_test, - const std::string& service_path) - : shill_service_client_test_(shill_service_client_test), - service_path_(service_path) { - shill_service_client_test_->SetConnectBehavior(service_path_, - run_loop_.QuitClosure()); - } - - ServiceConnectedWaiter(const ServiceConnectedWaiter&) = delete; - ServiceConnectedWaiter& operator=(const ServiceConnectedWaiter&) = delete; - - // Waits until the |service_path| passed to the constructor has connected. - // If it has connected since the constructor has run, will return immediately. - void Wait() { - run_loop_.Run(); - shill_service_client_test_->SetServiceProperty( - service_path_, shill::kStateProperty, base::Value(shill::kStateOnline)); - shill_service_client_test_->SetConnectBehavior(service_path_, - base::RepeatingClosure()); - } - - private: - ash::ShillServiceClient::TestInterface* shill_service_client_test_; - std::string service_path_; - base::RunLoop run_loop_; -}; - // Records all values that shill service property had during the lifetime of // ServicePropertyValueWatcher. Only supports string properties at the moment. class ServicePropertyValueWatcher : public ash::ShillPropertyChangedObserver { @@ -223,6 +184,28 @@ absl::optional<WaitForValueState> wait_for_value_state_; }; +// Shorthand for ServicePropertyValueWatcher that allows waiting for a specific +// shill::kStateProperty value. +class ServiceStateWaiter { + public: + ServiceStateWaiter( + ash::ShillServiceClient::TestInterface* shill_service_client_test, + const std::string& service_path) + : property_value_watcher_(shill_service_client_test, + service_path, + shill::kStateProperty) {} + + ServiceStateWaiter(const ServiceStateWaiter&) = delete; + ServiceStateWaiter& operator=(const ServiceStateWaiter&) = delete; + + void Wait(const std::string& expected_state) { + property_value_watcher_.WaitForValue(expected_state); + } + + private: + ServicePropertyValueWatcher property_value_watcher_; +}; + // Registers itself as ash::NetworkPolicyObserver and records events for // ash::NetworkPolicyObserver::PoliciesApplied and // ash::NetworkPolicyObserver::PolicyAppliedtoNetwork. @@ -848,11 +831,11 @@ } ] })"; - ServiceConnectedWaiter wifi_one_connected_waiter(shill_service_client_test_, - kServiceWifi1); + ServiceStateWaiter wifi_one_connected_waiter(shill_service_client_test_, + kServiceWifi1); shill_manager_client_test_->SetBestServiceToConnect(kServiceWifi1); SetDeviceOpenNetworkConfiguration(kDeviceONC, /*wait_applied=*/true); - wifi_one_connected_waiter.Wait(); + wifi_one_connected_waiter.Wait(shill::kStateOnline); EXPECT_THAT( network_policy_application_observer.policy_applied_to_network_events(), @@ -1051,11 +1034,10 @@ ] })"; - ServiceConnectedWaiter wifi_one_connected_waiter(shill_client, - kServiceWifi1); + ServiceStateWaiter wifi_one_connected_waiter(shill_client, kServiceWifi1); shill_manager_client_test_->SetBestServiceToConnect(kServiceWifi1); SetDeviceOpenNetworkConfiguration(kDeviceONC, /*wait_applied=*/true); - wifi_one_connected_waiter.Wait(); + wifi_one_connected_waiter.Wait(shill::kStateOnline); } // Check before login that device can connect to any available network. @@ -1310,12 +1292,12 @@ absl::optional<std::string> user_policy_wifi_service_path = shill_service_client_test_->FindServiceMatchingGUID("wifi_policy_2"); ASSERT_TRUE(user_policy_wifi_service_path); - ServiceConnectedWaiter wifi_connected_waiter( + ServiceStateWaiter wifi_connected_waiter( shill_service_client_test_, user_policy_wifi_service_path.value()); SetServiceVisibility("wifi_policy_2", true); SimulateWifiScanCompleted(); - wifi_connected_waiter.Wait(); + wifi_connected_waiter.Wait(shill::kStateOnline); } // Expects that the non-policy WiFi services are now prohibited. @@ -1409,8 +1391,8 @@ absl::optional<std::string> policy_wifi_service_path = shill_service_client_test_->FindServiceMatchingGUID("wifi_policy_1"); ASSERT_TRUE(policy_wifi_service_path); - ServiceConnectedWaiter wifi_connected_waiter( - shill_service_client_test_, policy_wifi_service_path.value()); + ServiceStateWaiter wifi_connected_waiter(shill_service_client_test_, + policy_wifi_service_path.value()); shill_manager_client_test_->SetBestServiceToConnect( policy_wifi_service_path.value()); @@ -1418,7 +1400,7 @@ const std::string user_hash = GetTestUserHash(); shill_profile_client_test_->AddProfile(kUserProfilePath, user_hash); - wifi_connected_waiter.Wait(); + wifi_connected_waiter.Wait(shill::kStateOnline); } // Expects that the non-policy WiFi services are now prohibited.
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc index dfc63c6..46859cc 100644 --- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc +++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
@@ -88,11 +88,26 @@ CHECK(!account_info.IsEmpty()) << "User must be logged in when address profile is going to be saved to " "user's Google Account"; + // Notify user that their address is saved only in Chrome and can be migrated + // to their Google account. + if (is_migration_to_account_) { + return l10n_util::GetStringFUTF16( + IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE, + base::UTF8ToUTF16(account_info.email)); + } + // Notify user that their address has already been saved in their Google + // account and is only going to be updated there. + if (original_profile_) { + return l10n_util::GetStringFUTF16( + IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE, + base::UTF8ToUTF16(account_info.email)); + } + + // Notify the user that their address is going to be saved in their Google + // account if they accept the prompt. return l10n_util::GetStringFUTF16( - original_profile_ - ? IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE - : IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE, + IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE, base::UTF8ToUTF16(account_info.email)); }
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc index 1cbe25f1..c4de81a7 100644 --- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc +++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc
@@ -40,6 +40,8 @@ (override)); }; +// TODO(crbug.com/1432561): remove test parameters to avoid conditionals in +// tests. class SaveUpdateAddressProfilePromptControllerTest : public ChromeRenderViewHostTestHarness, public ::testing::WithParamInterface< @@ -87,7 +89,7 @@ bool is_migration_to_account() const { return std::get<1>(GetParam()); } protected: - bool ShouldShowFooter() const; + bool ShouldShowSourceNotice() const; std::u16string GetExpectedNegativeButtonText() const; void SetUpController(bool is_update); @@ -106,7 +108,8 @@ base::android::JavaParamRef<jobject> mock_caller_{nullptr}; }; -bool SaveUpdateAddressProfilePromptControllerTest::ShouldShowFooter() const { +bool SaveUpdateAddressProfilePromptControllerTest::ShouldShowSourceNotice() + const { return is_migration_to_account() || profile_source() == AutofillProfile::Source::kAccount; } @@ -256,10 +259,12 @@ EXPECT_EQ(GetExpectedNegativeButtonText(), controller_->GetNegativeButtonText()); - if (ShouldShowFooter()) { + if (ShouldShowSourceNotice()) { EXPECT_EQ( l10n_util::GetStringFUTF16( - IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE, + is_migration_to_account() + ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE + : IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE, base::ASCIIToUTF16(kUserEmail)), controller_->GetSourceNotice(identity_test_env_.identity_manager())); } else { @@ -284,10 +289,12 @@ EXPECT_EQ(GetExpectedNegativeButtonText(), controller_->GetNegativeButtonText()); - if (ShouldShowFooter()) { + if (ShouldShowSourceNotice()) { EXPECT_EQ( l10n_util::GetStringFUTF16( - IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE, + is_migration_to_account() + ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE + : IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE, base::ASCIIToUTF16(kUserEmail)), controller_->GetSourceNotice(identity_test_env_.identity_manager())); } else { @@ -315,10 +322,12 @@ u"Underworld\n666 Erebus St.\nApt 8\nElysium, CA 91111\nUnited " u"States\n\n16502111111", differences.second); - if (ShouldShowFooter()) { + if (ShouldShowSourceNotice()) { EXPECT_EQ( l10n_util::GetStringFUTF16( - IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE, + is_migration_to_account() + ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE + : IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE, base::ASCIIToUTF16(kUserEmail)), controller_->GetSourceNotice(identity_test_env_.identity_manager())); } else {
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 81bb885c..0d1aaeb 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -978,6 +978,7 @@ ash::FirmwareUpdateAppUI, ash::ScanningUI, ash::OSFeedbackUI, ash::ShortcutCustomizationAppUI, ash::printing::printing_manager::PrintManagementUI, + ash::InternetDetailDialogUI, #endif NewTabPageUI, OmniboxPopupUI, BookmarksSidePanelUI, CustomizeChromeUI>( map);
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc index d2112c4..cb6e89f 100644 --- a/chrome/browser/dips/dips_bounce_detector.cc +++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -24,6 +24,7 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle_user_data.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h" using content::NavigationHandle; @@ -217,7 +218,26 @@ void DIPSWebContentsObserver::EmitDIPSIssue( const std::set<std::string>& sites) { - // TODO (jdh@): Create a DIPSIssue type and report one from here. + if (sites.empty()) { + return; + } + + auto details = blink::mojom::InspectorIssueDetails::New(); + auto bounce_tracking_issue_details = + blink::mojom::BounceTrackingIssueDetails::New(); + + bounce_tracking_issue_details->tracking_sites.reserve(sites.size()); + for (const auto& site : sites) { + bounce_tracking_issue_details->tracking_sites.push_back(site); + } + + details->bounce_tracking_issue_details = + std::move(bounce_tracking_issue_details); + + web_contents()->GetPrimaryMainFrame()->ReportInspectorIssue( + blink::mojom::InspectorIssueInfo::New( + blink::mojom::InspectorIssueCode::kBounceTrackingIssue, + std::move(details))); } void DIPSWebContentsObserver::ReportRedirectorsWithoutInteraction( @@ -566,9 +586,15 @@ redirectors.insert(GetSiteForDIPS(*it)); } - // Since redirectors that are the same as the start page won't be acted on, - // we don't report on them. + // Since redirectors that are the same as the start or final page won't be + // acted on, we don't report on them. + // + // NOTE: This is not exactly right since the end of this navigation may not + // necessarily be the end of the chain, if a client redirect happens. However, + // this is better for developer experience than waiting until then, since + // notifications come faster. redirectors.erase(initial_site); + redirectors.erase(GetSiteForDIPS(redirect_chain.back())); return redirectors; }
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h index 8be83a8..73562b93 100644 --- a/chrome/browser/dips/dips_bounce_detector.h +++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -207,6 +207,7 @@ // Returns the set of sites in the current (server) redirect chain. If the // navigation started with a client redirect, that site is also included. + // Redirectors matching the initial or end site are omitted. std::set<std::string> GetRedirectors( const DIPSNavigationStart& navigation_start, DIPSNavigationHandle* navigation_handle);
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc index 3d531d3..5ce7fec0 100644 --- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc +++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -22,6 +22,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/hit_test_region_observer.h" +#include "content/public/test/test_devtools_protocol_client.h" #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/http_request.h" @@ -690,3 +691,84 @@ "b.test/cross-site/c.test/title1.html (None) -> " "c.test/title1.html"))); } + +class DIPSBounceTrackingDevToolsIssueTest + : public content::TestDevToolsProtocolClient, + public DIPSBounceDetectorBrowserTest { + protected: + void WaitForIssueAndCheckTrackingSites( + const std::vector<std::string>& sites) { + auto is_dips_issue = [](const base::Value::Dict& params) { + return *(params.FindStringByDottedPath("issue.code")) == + "BounceTrackingIssue"; + }; + + // Wait for notification of a Bounce Tracking Issue. + base::Value::Dict params = WaitForMatchingNotification( + "Audits.issueAdded", base::BindRepeating(is_dips_issue)); + ASSERT_EQ(*params.FindStringByDottedPath("issue.code"), + "BounceTrackingIssue"); + + base::Value::Dict* bounce_tracking_issue_details = + params.FindDictByDottedPath("issue.details.bounceTrackingIssueDetails"); + ASSERT_TRUE(bounce_tracking_issue_details); + + std::vector<std::string> tracking_sites; + base::Value::List* tracking_sites_list = + bounce_tracking_issue_details->FindList("trackingSites"); + if (tracking_sites_list) { + for (const auto& val : *tracking_sites_list) { + tracking_sites.push_back(val.GetString()); + } + } + + // Verify the reported tracking sites match the expected sites. + EXPECT_THAT(tracking_sites, testing::ElementsAreArray(sites)); + + // Clear existing notifications so subsequent calls don't fail by checking + // `sites` against old notifications. + ClearNotifications(); + } + + void TearDownOnMainThread() override { + DetachProtocolClient(); + DIPSBounceDetectorBrowserTest::TearDownOnMainThread(); + } +}; + +IN_PROC_BROWSER_TEST_F(DIPSBounceTrackingDevToolsIssueTest, + BounceTrackingDevToolsIssue) { + WebContents* web_contents = GetActiveWebContents(); + + // Visit initial page on a.test. + ASSERT_TRUE(content::NavigateToURL( + web_contents, embedded_test_server()->GetURL("a.test", "/title1.html"))); + + // Open DevTools and enable Audit domain. + AttachToWebContents(web_contents); + SendCommandSync("Audits.enable"); + ClearNotifications(); + + // Navigate with a click (not a redirect) to b.test, which S-redirects to + // c.test. + ASSERT_TRUE(content::NavigateToURLFromRenderer( + web_contents, + embedded_test_server()->GetURL("b.test", + "/cross-site/c.test/title1.html"), + embedded_test_server()->GetURL("c.test", "/title1.html"))); + WaitForIssueAndCheckTrackingSites({"b.test"}); + + // Navigate without a click (i.e. by C-redirecting) to d.test. + ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture( + web_contents, embedded_test_server()->GetURL("d.test", "/title1.html"))); + WaitForIssueAndCheckTrackingSites({"c.test"}); + + // Navigate without a click (i.e. by C-redirecting) to e.test, which + // S-redirects to f.test, which S-redirects to g.test. + ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture( + web_contents, + embedded_test_server()->GetURL( + "e.test", "/cross-site/f.test/cross-site/g.test/title1.html"), + embedded_test_server()->GetURL("g.test", "/title1.html"))); + WaitForIssueAndCheckTrackingSites({"d.test", "e.test", "f.test"}); +}
diff --git a/chrome/browser/dips/dips_bounce_detector_unittest.cc b/chrome/browser/dips/dips_bounce_detector_unittest.cc index cbbeeda..75fec8f 100644 --- a/chrome/browser/dips/dips_bounce_detector_unittest.cc +++ b/chrome/browser/dips/dips_bounce_detector_unittest.cc
@@ -493,16 +493,17 @@ StartNavigation("http://b.test", kWithUserGesture) .RedirectTo("http://c.test") .Finish(true); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test")); // Navigate without a click (i.e. by C-redirecting) to d.test NavigateTo("http://d.test", kNoUserGesture); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test")); // Navigate without a click (i.e. by C-redirecting) to e.test, which // S-redirects to f.test StartNavigation("http://e.test", kNoUserGesture) .RedirectTo("http://f.test") .Finish(true); - EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test", "d.test, e.test")); } @@ -517,13 +518,13 @@ .RedirectTo("http://c.test") .RedirectTo("http://d.test") .Finish(false); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test, c.test")); // Because the previous navigation didn't commit, the following chain still // starts from http://a.test/. StartNavigation("http://e.test", kWithUserGesture) .RedirectTo("http://f.test") .Finish(true); - EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test, c.test", "e.test")); } @@ -542,9 +543,11 @@ .RedirectTo("http://a.test") .RedirectTo("http://c.test") .Finish(true); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test")); // Navigate without a click (i.e. by C-redirecting) to a.test. NavigateTo("http://a.test", kNoUserGesture); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test")); // Navigate without a click (i.e. by C-redirecting) to d.test, which // S-redirects to e.test, which S-redirects to f.test. @@ -552,11 +555,59 @@ .RedirectTo("http://e.test") .RedirectTo("http://f.test") .Finish(true); - EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test", "d.test, e.test")); } +// This test verifies that sites in a (server) redirect chain that are the same +// as the ending site of a navigation are not reported. +TEST_F(DIPSBounceDetectorTest, + ReportRedirectorsInChain_OmitSitesMatchingEndSite) { + // Visit initial page on a.test. + NavigateTo("http://a.test", kWithUserGesture); + + // Navigate with a click (not a redirect) to b.test, which S-redirects to + // c.test, which S-redirects to c.test. + StartNavigation("http://b.test", kWithUserGesture) + .RedirectTo("http://c.test") + .RedirectTo("http://c.test") + .Finish(true); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test")); + + // Navigate without a click (i.e. by C-redirecting) to d.test. + NavigateTo("http://d.test", kNoUserGesture); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test")); + + // Navigate without a click (i.e. by C-redirecting) to e.test, which + // S-redirects to f.test, which S-redirects to e.test. + StartNavigation("http://e.test", kNoUserGesture) + .RedirectTo("http://f.test") + .RedirectTo("http://e.test") + .Finish(true); + EXPECT_THAT(GetReportedSites(), + testing::ElementsAre("b.test", "c.test", "d.test, f.test")); +} + +TEST_F(DIPSBounceDetectorTest, + ReportRedirectorsInChain_OmitSitesMatchingEndSite_Uncommitted) { + // Visit initial page on a.test. + NavigateTo("http://a.test", kWithUserGesture); + + // Navigate with a click (not a redirect) to b.test, which S-redirects to + // c.test, which S-redirects to c.test. + StartNavigation("http://b.test", kWithUserGesture) + .RedirectTo("http://c.test") + .RedirectTo("http://c.test") + .Finish(false); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test")); + + // Navigate without a click (i.e. by C-redirecting) to d.test. + // NOTE: Because the previous navigation didn't commit, the chain still + // starts from http://a.test/. + NavigateTo("http://d.test", kNoUserGesture); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "a.test")); +} + TEST_F(DIPSBounceDetectorTest, InteractionRecording_Throttled) { base::Time first_time = GetCurrentTime(); NavigateTo("http://a.test", kNoUserGesture);
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 5b3ae149..1470754e 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -299,8 +299,8 @@ set_chromeos_user_(true), #endif context_type_(context_type), - // Default channel is STABLE but override with UNKNOWN so that unlaunched - // or incomplete APIs can write tests. + // TODO(crbug/1427323): Move this ScopedCurrentChannel down into tests + // that specifically require it. current_channel_(version_info::Channel::UNKNOWN), override_prompt_for_external_extensions_( FeatureSwitch::prompt_for_external_extensions(),
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h index f8990a0..d0ed5ed 100644 --- a/chrome/browser/extensions/extension_browsertest.h +++ b/chrome/browser/extensions/extension_browsertest.h
@@ -423,7 +423,13 @@ bool wait_for_idle, bool grant_permissions); - // Make the current channel "dev" for the duration of the test. + // Used for setting the default scoped current channel for extension browser + // tests to UNKNOWN (trunk), in order to enable channel restricted features. + // TODO(crbug/1427323): We should remove this and have the current channel + // respect what is defined on the builder. If a test requires a specific + // channel for a channel restricted feature, it should be defining its own + // scoped channel override. As this stands, it means we don't really have + // non-trunk coverage for most extension browser tests. ScopedCurrentChannel current_channel_; // Disable external install UI.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 923883bc..2612a55 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -7061,6 +7061,11 @@ "expiry_milestone": 114 }, { + "name": "sync-segments-data", + "owners": [ "bwwilliams", "sky", "treib" ], + "expiry_milestone": 130 + }, + { "name": "sync-standalone-invalidations", "owners": [ "treib", "rushans" ], "expiry_milestone": 115
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 7199429..71a2557 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -262,7 +262,6 @@ &kOmniboxConsumesImeInsets, &kOmniboxModernizeVisualUpdate, &kOpaqueOriginForIncomingIntents, - &kOptimizeGeolocationHeaderGeneration, &kPartnerHomepageInitialLoadImprovement, &kProbabilisticCryptidRenderer, &kQuickDeleteForAndroid, @@ -848,10 +847,6 @@ "OpaqueOriginForIncomingIntents", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kOptimizeGeolocationHeaderGeneration, - "OptimizeGeolocationHeaderGeneration", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kPartnerHomepageInitialLoadImprovement, "PartnerHomepageInitialLoadImprovement", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 9c079d8..67e59135 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -395,8 +395,6 @@ "OpaqueOriginForIncomingIntents"; public static final String OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS = "OptimizationGuidePushNotifications"; - public static final String OPTIMIZE_GEOLOCATION_HEADER_GENERATION = - "OptimizeGeolocationHeaderGeneration"; public static final String PAGE_ANNOTATIONS_SERVICE = "PageAnnotationsService"; public static final String PAGE_INFO_ABOUT_THIS_SITE_EN = "PageInfoAboutThisSiteEn"; public static final String PAGE_INFO_ABOUT_THIS_SITE_IMPROVED_BOTTOMSHEET =
diff --git a/chrome/browser/lacros/cert/cert_db_initializer_factory.cc b/chrome/browser/lacros/cert/cert_db_initializer_factory.cc index c6a5892a..8c2549a 100644 --- a/chrome/browser/lacros/cert/cert_db_initializer_factory.cc +++ b/chrome/browser/lacros/cert/cert_db_initializer_factory.cc
@@ -8,7 +8,6 @@ #include "base/system/sys_info.h" #include "chrome/browser/lacros/cert/cert_db_initializer_impl.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" #include "chromeos/lacros/lacros_service.h" class CertDbInitializer; @@ -29,9 +28,7 @@ CertDbInitializerFactory::CertDbInitializerFactory() : ProfileKeyedServiceFactory( "CertDbInitializerFactory", - ProfileSelections::BuildRedirectedInIncognito()) { - DependsOn(IdentityManagerFactory::GetInstance()); -} + ProfileSelections::BuildRedirectedInIncognito()) {} bool CertDbInitializerFactory::ServiceIsCreatedWithBrowserContext() const { return should_create_with_browser_context_;
diff --git a/chrome/browser/media/cast_mirroring_service_host.cc b/chrome/browser/media/cast_mirroring_service_host.cc index eea6301d..2672bffb 100644 --- a/chrome/browser/media/cast_mirroring_service_host.cc +++ b/chrome/browser/media/cast_mirroring_service_host.cc
@@ -72,6 +72,10 @@ // Default resolution constraint. constexpr gfx::Size kMaxResolution(1920, 1080); +// The delay before calling PauseVideoCaptureHostOnIO. This allows us to ensure +// UI elements are hidden before we stop sending frames. +constexpr base::TimeDelta kPauseDelay = base::Milliseconds(500); + // Command line arguments that should be passed to the mirroring service. static const char* kPassthroughSwitches[]{ switches::kCastStreamingForceEnableHardwareH264, @@ -612,9 +616,11 @@ void CastMirroringServiceHost::Pause() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (freeze_ui_enabled_ && video_capture_host_) { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&PauseVideoCaptureHostOnIO, - video_capture_host_->impl(), ignored_token_)); + content::GetIOThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, + base::BindOnce(&PauseVideoCaptureHostOnIO, video_capture_host_->impl(), + ignored_token_), + kPauseDelay); } }
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc index b8fcecd..d99da3f 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -450,6 +450,10 @@ mojo::PendingReceiver<mojom::MediaController> media_controller, mojo::PendingRemote<mojom::MediaStatusObserver> observer) { DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_); + media_controller_receiver_.reset(); + media_controller_receiver_.Bind(std::move(media_controller)); + media_status_observer_.reset(); + media_status_observer_.Bind(std::move(observer)); } std::string MirroringActivity::GetRouteDescription( @@ -666,4 +670,22 @@ debugger_->OnMirroringStats(json_stats.Clone()); } +void MirroringActivity::Play() { + DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_); + if (host_) { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&mirroring::MirroringServiceHost::Resume, + host_->GetWeakPtr())); + } +} + +void MirroringActivity::Pause() { + DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_); + if (host_) { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&mirroring::MirroringServiceHost::Pause, + host_->GetWeakPtr())); + } +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.h b/chrome/browser/media/router/providers/cast/mirroring_activity.h index a5bf9cf..7224163e 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.h +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.h
@@ -19,7 +19,9 @@ #include "components/media_router/common/media_route.h" #include "components/media_router/common/mojom/debugger.mojom.h" #include "components/media_router/common/mojom/logger.mojom.h" +#include "components/media_router/common/mojom/media_controller.mojom.h" #include "components/media_router/common/mojom/media_router.mojom-forward.h" +#include "components/media_router/common/mojom/media_status.mojom.h" #include "components/media_router/common/providers/cast/channel/cast_message_handler.h" #include "components/mirroring/mojom/cast_message_channel.mojom.h" #include "components/mirroring/mojom/session_observer.mojom.h" @@ -37,7 +39,8 @@ class MirroringActivity : public CastActivity, public mirroring::mojom::SessionObserver, - public mirroring::mojom::CastMessageChannel { + public mirroring::mojom::CastMessageChannel, + public mojom::MediaController { public: using OnStopCallback = base::OnceClosure; @@ -80,6 +83,21 @@ void OnAppMessage(const cast::channel::CastMessage& message) override; void OnInternalMessage(const cast_channel::InternalMessage& message) override; + // mojom::MediaController implementation + void SetMute(bool mute) override {} + void SetVolume(float volume) override {} + void Seek(base::TimeDelta time) override {} + void NextTrack() override {} + void PreviousTrack() override {} + // Used during access code casting to resume the mirroring session, if + // frozen. This will send a request to the video capture host to resume + // displaying the casting session. + void Play() override; + // Used during access code casting to freeze the mirroring session. This will + // send a request to the video capture host to pause the display of the + // mirroring session. + void Pause() override; + mirroring::MirroringServiceHost* GetHost() { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); return host_.get(); @@ -161,6 +179,14 @@ // receiver. mojo::Receiver<mirroring::mojom::CastMessageChannel> channel_receiver_{this}; + // To handle freeze and unfreeze requests from the mirroring media controller + // host to the mirroring service host. + mojo::Receiver<mojom::MediaController> media_controller_receiver_{this}; + + // Sends media status updates with mirroring information needed for freezing + // the session. + mojo::Remote<mojom::MediaStatusObserver> media_status_observer_; + // Set before and after a mirroring session is established, for metrics. absl::optional<base::Time> will_start_mirroring_timestamp_; absl::optional<base::Time> did_start_mirroring_timestamp_;
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc index 175da55..f50a4b81 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
@@ -533,4 +533,18 @@ RunUntilIdle(); } +TEST_F(MirroringActivityTest, Pause) { + MakeActivity(); + + EXPECT_CALL(*mirroring_service_, Pause()).Times(testing::Exactly(1)); + activity_->Pause(); +} + +TEST_F(MirroringActivityTest, Play) { + MakeActivity(); + + EXPECT_CALL(*mirroring_service_, Resume()).Times(testing::Exactly(1)); + activity_->Play(); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h b/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h index 28e886f..c0d28ce 100644 --- a/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h +++ b/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h
@@ -23,6 +23,14 @@ MOCK_METHOD(void, SendStopSessionMessageToClients, (const std::string& hash_token)); + + MOCK_METHOD(void, Play, ()); + MOCK_METHOD(void, Pause, ()); + MOCK_METHOD(void, SetMute, (bool mute)); + MOCK_METHOD(void, SetVolume, (float volume)); + MOCK_METHOD(void, Seek, (base::TimeDelta time)); + MOCK_METHOD(void, NextTrack, ()); + MOCK_METHOD(void, PreviousTrack, ()); }; } // namespace media_router
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.cc b/chrome/browser/media/webrtc/capture_policy_utils.cc index 5556863..2bbc78e 100644 --- a/chrome/browser/media/webrtc/capture_policy_utils.cc +++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
@@ -49,12 +49,14 @@ // aligns better than URLMatcher with the rules from: // https://chromeenterprise.google/policies/url-patterns/. for (const auto& value : allowed_origins) { - if (!value.is_string()) + if (!value.is_string()) { continue; + } ContentSettingsPattern pattern = ContentSettingsPattern::FromString(value.GetString()); - if (pattern.IsValid() && pattern.Matches(request_origin)) + if (pattern.IsValid() && pattern.Matches(request_origin)) { return true; + } } return false; @@ -76,12 +78,14 @@ // If we can't get the PrefService, then we won't apply any restrictions. Profile* profile = Profile::FromBrowserContext(capturer_web_contents->GetBrowserContext()); - if (!profile) + if (!profile) { return AllowedScreenCaptureLevel::kUnrestricted; + } const PrefService* prefs = profile->GetPrefs(); - if (!prefs) + if (!prefs) { return AllowedScreenCaptureLevel::kUnrestricted; + } return GetAllowedCaptureLevel(request_origin, *prefs); } @@ -126,6 +130,16 @@ if (!profile) { return false; } + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // To ensure that a user is informed at login time that capturing of all + // screens can happen (for privacy reasons), this API is only available on + // primary profiles. + if (!profile->IsMainProfile()) { + return false; + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + HostContentSettingsMap* host_content_settings_map = HostContentSettingsMapFactory::GetForProfile(profile); if (!host_content_settings_map) { @@ -150,12 +164,24 @@ const GURL& url) { #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) Profile* profile = Profile::FromBrowserContext(context); - if (!profile) + if (!profile) { return false; + } + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // To ensure that a user is informed at login time that capturing of all + // screens can happen (for privacy reasons), this API is only available on + // primary profiles. + if (!profile->IsMainProfile()) { + return false; + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + HostContentSettingsMap* host_content_settings_map = HostContentSettingsMapFactory::GetForProfile(profile); - if (!host_content_settings_map) + if (!host_content_settings_map) { return false; + } ContentSetting auto_accept_enabled = host_content_settings_map->GetContentSetting( url, url,
diff --git a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc index 7d964aa9..4b07d40 100644 --- a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc +++ b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
@@ -4,11 +4,16 @@ #include "chrome/browser/media/webrtc/capture_policy_utils.h" +#include "base/containers/contains.h" #include "base/values.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" +#include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -255,3 +260,90 @@ EXPECT_EQ(expected_media_types, actual_media_types); } + +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) + +class MultiCaptureTest + : public testing::Test, + public ::testing::WithParamInterface< + std::tuple<bool, std::vector<std::string>, std::string>> { + public: + void SetUp() override { + testing::Test::SetUp(); + + TestingProfile::Builder builder; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + builder.SetIsMainProfile(IsMainProfile()); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + profile_ = builder.Build(); + + HostContentSettingsMap* content_settings = + HostContentSettingsMapFactory::GetForProfile(profile()); + for (const std::string& url : AllowedOrigins()) { + content_settings->SetContentSettingDefaultScope( + GURL(url), GURL(url), + ContentSettingsType::GET_DISPLAY_MEDIA_SET_SELECT_ALL_SCREENS, + ContentSetting::CONTENT_SETTING_ALLOW); + } + } + + void TearDown() override { profile_.reset(); } + + Profile* profile() { return profile_.get(); } + bool IsMainProfile() const { return std::get<0>(GetParam()); } + std::vector<std::string> AllowedOrigins() const { + return std::get<1>(GetParam()); + } + std::string CurrentOrigin() const { return std::get<2>(GetParam()); } + + protected: + bool ExpectedIsMultiCaptureAllowed() { + std::vector<std::string> allowed_urls = AllowedOrigins(); + return +#if BUILDFLAG(IS_CHROMEOS_LACROS) + IsMainProfile() && +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + base::Contains(allowed_urls, CurrentOrigin()); + } + + bool ExpectedIsMultiCaptureAllowedForAnyUrl() { + return +#if BUILDFLAG(IS_CHROMEOS_LACROS) + IsMainProfile() && +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + !AllowedOrigins().empty(); + } + + private: + std::unique_ptr<TestingProfile> profile_; + content::BrowserTaskEnvironment task_environment_; +}; + +TEST_P(MultiCaptureTest, IsMultiCaptureAllowedBasedOnPolicy) { + EXPECT_EQ(ExpectedIsMultiCaptureAllowed(), + capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed( + profile(), GURL(CurrentOrigin()))); +} + +TEST_P(MultiCaptureTest, IsMultiCaptureAllowedForAnyUrl) { + EXPECT_EQ( + ExpectedIsMultiCaptureAllowedForAnyUrl(), + capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite( + profile())); +} + +INSTANTIATE_TEST_SUITE_P( + MultiCaptureTestCases, + MultiCaptureTest, + ::testing::Combine( + // Is main profile? + ::testing::Bool(), + // Allowed origins + ::testing::ValuesIn({std::vector<std::string>{}, + std::vector<std::string>{ + "https://www.google.com"}}), + // Origin to test + ::testing::ValuesIn({std::string("https://www.google.com"), + std::string("https://www.notallowed.com")}))); + +#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 7f74410..e6ba3b4 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -245,24 +245,40 @@ BrowserAddedForProfileObserver::BrowserAddedForProfileObserver( Profile* profile, base::OnceClosure callback) - : profile_(profile), callback_(std::move(callback)) { + : profile_(profile->GetWeakPtr()), callback_(std::move(callback)) { DCHECK(callback_); - BrowserList::AddObserver(this); + browser_list_observation_.Observe(BrowserList::GetInstance()); } BrowserAddedForProfileObserver::~BrowserAddedForProfileObserver() {} void BrowserAddedForProfileObserver::OnBrowserAdded(Browser* browser) { - if (browser->profile() == profile_) { - BrowserList::RemoveObserver(this); + if (browser->profile() == profile_.get()) { + browser_ = browser; // By the time the browser is added a tab (or multiple) are about to be // added. Post the callback to the message loop so it gets executed after // the tabs are created. base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, std::move(callback_)); - base::SingleThreadTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE, - this); + FROM_HERE, + base::BindOnce( + &BrowserAddedForProfileObserver::NotifyBrowserCreatedAnDie, + base::Unretained(this))); } } +void BrowserAddedForProfileObserver::OnBrowserRemoved(Browser* browser) { + // The browser was closed before the callback could run. + if (browser == browser_) { + browser_list_observation_.Reset(); + browser_ = nullptr; + } +} + +void BrowserAddedForProfileObserver::NotifyBrowserCreatedAnDie() { + if (browser_) { + std::move(callback_).Run(); + } + delete this; +} + } // namespace profiles
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h index c5e3066..5a7f582 100644 --- a/chrome/browser/profiles/profile_window.h +++ b/chrome/browser/profiles/profile_window.h
@@ -17,6 +17,7 @@ #error "Not used on Android" #endif +class BrowserList; class Profile; namespace base { class FilePath; } @@ -89,10 +90,16 @@ private: // Overridden from BrowserListObserver: void OnBrowserAdded(Browser* browser) override; + void OnBrowserRemoved(Browser* browser) override; + + void NotifyBrowserCreatedAnDie(); // Profile for which the browser should be opened. - raw_ptr<Profile> profile_; + base::WeakPtr<Profile> profile_; + raw_ptr<Browser> browser_ = nullptr; base::OnceClosure callback_; + base::ScopedObservation<BrowserList, BrowserListObserver> + browser_list_observation_{this}; }; } // namespace profiles
diff --git a/chrome/browser/profiles/profile_window_browsertest.cc b/chrome/browser/profiles/profile_window_browsertest.cc index afdea65..57529f942 100644 --- a/chrome/browser/profiles/profile_window_browsertest.cc +++ b/chrome/browser/profiles/profile_window_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/memory/raw_ptr.h" #include "chrome/browser/profiles/profile_window.h" #include <stddef.h> @@ -10,8 +9,11 @@ #include "base/command_line.h" #include "base/functional/bind.h" +#include "base/memory/raw_ptr.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" +#include "base/test/test_future.h" #include "base/values.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -100,6 +102,23 @@ } }; +class BrowserAddedObserver : public BrowserListObserver { + public: + explicit BrowserAddedObserver(base::OnceCallback<void(Browser*)> callback) + : callback_(std::move(callback)) { + CHECK(callback_); + BrowserList::AddObserver(this); + } + + void OnBrowserAdded(Browser* browser) override { + BrowserList::RemoveObserver(this); + std::move(callback_).Run(browser); + } + + private: + base::OnceCallback<void(Browser*)> callback_; +}; + } // namespace class ProfileWindowBrowserTest : public InProcessBrowserTest { @@ -309,13 +328,36 @@ IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest, OpenBrowserWindowForProfile) { Profile* profile = browser()->profile(); size_t num_browsers = BrowserList::GetInstance()->size(); - profiles::OpenBrowserWindowForProfile(base::OnceCallback<void(Profile*)>(), - true, false, false, profile); - base::RunLoop().RunUntilIdle(); + base::test::TestFuture<Profile*> future; + profiles::OpenBrowserWindowForProfile(future.GetCallback(), true, false, + false, profile); + EXPECT_EQ(profile, future.Get()); EXPECT_EQ(num_browsers + 1, BrowserList::GetInstance()->size()); EXPECT_FALSE(ProfilePicker::IsOpen()); } +IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest, + OpenBrowserWindowForProfileBrowserDestroyed) { + Profile* profile = browser()->profile(); + size_t num_browsers = BrowserList::GetInstance()->size(); + + base::RunLoop loop; + BrowserAddedObserver browser_added_observer( + base::BindLambdaForTesting([&loop, this](Browser* browser) { + this->CloseBrowserAsynchronously(browser); + loop.Quit(); + })); + + base::test::TestFuture<Profile*> future; + profiles::OpenBrowserWindowForProfile(future.GetCallback(), true, false, + false, profile); + base::RunLoop().RunUntilIdle(); + // `future` is not called because the browser was already destroyed. + EXPECT_FALSE(future.IsReady()); + EXPECT_EQ(num_browsers, BrowserList::GetInstance()->size()); + EXPECT_FALSE(ProfilePicker::IsOpen()); +} + // TODO(crbug.com/935746): Test is flaky on Win and Linux. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) #define MAYBE_OpenBrowserWindowForProfileWithSigninRequired \
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index b01e70b..74c75f0 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -222,9 +222,12 @@ dest_dir = chromevox_out_dir sources = [ "background/background.html", + "earcons/chromevox_loaded.ogg", + "earcons/chromevox_loading.ogg", "earcons/control.wav", - "earcons/selection.wav", - "earcons/selection_reverse.wav", + "earcons/invalid_keypress.ogg", + "earcons/selection.ogg", + "earcons/selection_reverse.ogg", "earcons/skim.wav", "earcons/small_room_2.wav", "earcons/static.wav",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js index 87e9e73..ba450102 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js
@@ -56,7 +56,7 @@ this.defaultPitch = Note.G3; /** @public {string} The choice of base sound for most controls. */ - this.controlSound = SoundFile.CONTROL; + this.controlSound = WavSoundFile.CONTROL; /** * @public {number} The delay between sounds in the on/off sweep effect, @@ -129,9 +129,11 @@ this.currentTrackedEarcon_; // Initialization: load the base sound data files asynchronously. - Object.values(SoundFile) + Object.values(WavSoundFile) .concat(Object.values(Reverb)) .forEach(sound => this.loadSound(sound, `${BASE_URL}${sound}.wav`)); + Object.values(OggSoundFile) + .forEach(sound => this.loadSound(sound, `${BASE_URL}${sound}.ogg`)); } /** @@ -365,26 +367,26 @@ /** Play the static sound. */ onStatic() { - this.play(SoundFile.STATIC, {gain: this.staticVolume}); + this.play(WavSoundFile.STATIC, {gain: this.staticVolume}); } /** Play the link sound. */ onLink() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound, {pitch: Note.G4}); } /** Play the button sound. */ onButton() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound); } /** Play the text field sound. */ onTextField() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play( - SoundFile.STATIC, + WavSoundFile.STATIC, {time: this.baseDelay * 1.5, gain: this.clickVolume * 0.5}); this.play(this.controlSound, {pitch: Note.B3}); this.play( @@ -394,7 +396,7 @@ /** Play the pop up button sound. */ onPopUpButton() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound); this.play( @@ -407,33 +409,33 @@ /** Play the check on sound. */ onCheckOn() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound, {pitch: Note.D3}); this.play(this.controlSound, {pitch: Note.D4, time: this.baseDelay * 2}); } /** Play the check off sound. */ onCheckOff() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound, {pitch: Note.D4}); this.play(this.controlSound, {pitch: Note.D3, time: this.baseDelay * 2}); } /** Play the smart sticky mode on sound. */ onSmartStickyModeOn() { - this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.5}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.5}); this.play(this.controlSound, {pitch: Note.D4}); } /** Play the smart sticky mode off sound. */ onSmartStickyModeOff() { - this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.5}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.5}); this.play(this.controlSound, {pitch: Note.D3}); } /** Play the select control sound. */ onSelect() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound); this.play(this.controlSound, {time: this.baseDelay}); this.play(this.controlSound, {time: this.baseDelay * 2}); @@ -441,7 +443,7 @@ /** Play the slider sound. */ onSlider() { - this.play(SoundFile.STATIC, {gain: this.clickVolume}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume}); this.play(this.controlSound); this.play( this.controlSound, {time: this.baseDelay, gain: 0.5, pitch: Note.A3}); @@ -458,21 +460,21 @@ /** Play the skim sound. */ onSkim() { - this.play(SoundFile.SKIM); + this.play(WavSoundFile.SKIM); } /** Play the selection sound. */ onSelection() { - this.play(SoundFile.SELECTION); + this.play(OggSoundFile.SELECTION); } /** Play the selection reverse sound. */ onSelectionReverse() { - this.play(SoundFile.SELECTION_REVERSE); + this.play(OggSoundFile.SELECTION_REVERSE); } onNoPointerAnchor() { - this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.2}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.2}); const freq1 = this.frequencyFor_(Note.A_FLAT4); this.generateSinusoidal({ attack: 0.00001, @@ -686,7 +688,7 @@ /** Play a wrap sound. */ onWrap() { - this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.3}); + this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.3}); const freq1 = this.frequencyFor_(this.wrapPitch - 8); const freq2 = this.frequencyFor_(this.wrapPitch + 8); this.generateSinusoidal({ @@ -711,7 +713,8 @@ let t = this.progressTime_ - this.context_.currentTime; this.progressSources_.push([ this.progressTime_, - this.play(SoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}), + this.play( + WavSoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}), ]); this.progressSources_.push([ this.progressTime_, @@ -727,7 +730,8 @@ this.progressSources_.push([ this.progressTime_, - this.play(SoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}), + this.play( + WavSoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}), ]); this.progressSources_.push([ this.progressTime_, @@ -862,14 +866,21 @@ // Local to module. /* @enum {string} The list of sound data files to load. */ -const SoundFile = { +const WavSoundFile = { CONTROL: 'control', - SELECTION: 'selection', - SELECTION_REVERSE: 'selection_reverse', SKIM: 'skim', STATIC: 'static', }; +/* @enum {string} The list of sound data files to load. */ +const OggSoundFile = { + CHROMEVOX_LOADED: 'chromevox_loaded', + CHROMEVOX_LOADING: 'chromevox_loading', + INVALID_KEYPRESS: 'invalid_keypress', + SELECTION: 'selection', + SELECTION_REVERSE: 'selection_reverse', +}; + /** @enum {string} The list of reverb data files to load. */ const Reverb = { SMALL_ROOM: 'small_room_2',
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg new file mode 100644 index 0000000..6dd753a0 --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg new file mode 100644 index 0000000..439bc56 --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg index 292cefd..43701d8 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg index 95dde34..41cda347 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav deleted file mode 100644 index 7be8224..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg index 8b04e73..1f03565 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav deleted file mode 100644 index a42b0d9..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn index b6e0c29..82c918d 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
@@ -35,6 +35,7 @@ "//ash/webui/common/resources:css_wrapper_files", "//ash/webui/common/resources:html_wrapper_files", "//ash/webui/common/resources:preprocess", + "//ui/webui/resources/cr_components/color_change_listener:build_ts", "//ui/webui/resources/cr_components/localized_link:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/mojo:build_ts",
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html index b601673..503001a 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
@@ -1,5 +1,5 @@ <style include="cr-page-host-style cr-shared-style network-shared - iron-flex"> + iron-flex cros-color-overrides"> cr-policy-network-indicator-mojo { margin-inline-end: 10px; }
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js index 48d1a870..750db58 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
@@ -17,6 +17,7 @@ import 'chrome://resources/cr_elements/cr_page_host_style.css.js'; import 'chrome://resources/cr_elements/icons.html.js'; import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js'; import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; import 'chrome://resources/ash/common/network/apn_list.js'; import './strings.m.js'; @@ -29,6 +30,7 @@ import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; import {NetworkListenerBehavior} from 'chrome://resources/ash/common/network/network_listener_behavior.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; +import {startColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js'; import {ApnProperties, ConfigProperties, CrosNetworkConfigRemote, GlobalPolicy, IPConfigProperties, ManagedProperties, MAX_NUM_CUSTOM_APNS, NetworkStateProperties, ProxySettings, StartConnectResult} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType, NetworkType, OncSource, PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -121,6 +123,19 @@ }, /** + * Return true if Jelly feature flag is enabled. + * @private + */ + isJellyEnabled_: { + type: Boolean, + readOnly: true, + value() { + return loadTimeData.valueExists('isJellyEnabled') && + loadTimeData.getBoolean('isJellyEnabled'); + }, + }, + + /** * Return true if custom APNs limit is reached. * @private */ @@ -165,6 +180,14 @@ attached() { this.browserProxy_ = InternetDetailDialogBrowserProxyImpl.getInstance(); const dialogArgs = this.browserProxy_.getDialogArguments(); + if (this.isJellyEnabled_) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = 'chrome://theme/colors.css?sets=legacy,sys'; + document.head.appendChild(link); + document.body.classList.add('jelly-enabled'); + startColorChangeUpdater(); + } let type; let name; if (dialogArgs) {
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn index 53e609d..c804ca5 100644 --- a/chrome/browser/resources/password_manager/BUILD.gn +++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -45,6 +45,7 @@ "dialogs/edit_password_disclaimer_dialog.ts", "dialogs/multi_store_delete_password_dialog.ts", "dialogs/move_passwords_dialog.ts", + "dialogs/password_preview_item.ts", "password_details_card.ts", "password_details_section.ts", "password_list_item.ts",
diff --git a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html index 85b3152..2f19062 100644 --- a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html +++ b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html
@@ -5,18 +5,34 @@ margin-inline-end: 10px; width: 16px; } + + #passwords { + margin-bottom: 4px; + margin-top: 16px; + } </style> -<cr-dialog id="dialog" show-on-attach> +<cr-dialog id="dialog"> <div slot="title" class="dialog-title">$i18n{movePasswordsTitle}</div> <div slot="body"> <div>$i18n{movePasswordsDescription}</div> - <!-- TODO(crbug.com/1420919): Show all passwords --> + <div id="passwords"> + <dom-repeat items="[[passwords]]"> + <template> + <password-preview-item password-id="[[item.id]]" + url="[[getUrl_(item)]]" username="[[item.username]]" + password="[[item.password]]" first="[[!index]]" + on-change="passwordSelected_"> + </password-preview-item> + </template> + </dom-repeat> + </div> </div> <div slot="button-container"> <cr-button id="cancel" class="cancel-button" on-click="onCancel_"> $i18n{cancel} </cr-button> - <cr-button id="move" class="action-button" on-click="onMoveButtonClick_"> + <cr-button id="move" class="action-button" on-click="onMoveButtonClick_" + disabled="[[!selectedPasswordIds_.length]]"> $i18n{movePasswordsButton} </cr-button> </div>
diff --git a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts index 5faa3aa..29753a5a 100644 --- a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts +++ b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts
@@ -6,12 +6,14 @@ import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; import '../shared_style.css.js'; import '../user_utils_mixin.js'; +import './password_preview_item.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PasswordManagerImpl} from '../password_manager_proxy.js'; import {UserUtilMixin} from '../user_utils_mixin.js'; import {getTemplate} from './move_passwords_dialog.html.js'; @@ -46,20 +48,55 @@ type: Array, value: () => [], }, + + selectedPasswordIds_: { + type: Array, + valie: () => [], + }, }; } passwords: chrome.passwordsPrivate.PasswordUiEntry[]; + private selectedPasswordIds_: number[]; + + override connectedCallback() { + super.connectedCallback(); + + this.selectedPasswordIds_ = this.passwords.map(item => item.id); + PasswordManagerImpl.getInstance() + .requestCredentialsDetails(this.selectedPasswordIds_) + .then(entries => { + this.passwords = entries; + this.$.dialog.showModal(); + }) + .catch(() => { + this.$.dialog.close(); + }); + } private onCancel_() { - this.$.dialog.close(); + this.$.dialog.cancel(); } private onMoveButtonClick_() { assert(this.isOptedInForAccountStorage); - // TODO(crbug.com/1420919): Implement password moving. + PasswordManagerImpl.getInstance().movePasswordsToAccount( + this.selectedPasswordIds_); this.$.dialog.close(); } + + private getUrl_(password: chrome.passwordsPrivate.PasswordUiEntry): string { + assert(password.affiliatedDomains); + assert(password.affiliatedDomains.length > 0); + return password.affiliatedDomains[0].name; + } + + private passwordSelected_() { + this.selectedPasswordIds_ = + Array.from(this.shadowRoot!.querySelectorAll('password-preview-item')) + .filter(item => item.checked) + .map(item => item.passwordId); + } } declare global {
diff --git a/chrome/browser/resources/password_manager/dialogs/password_preview_item.html b/chrome/browser/resources/password_manager/dialogs/password_preview_item.html new file mode 100644 index 0000000..3df3cf8 --- /dev/null +++ b/chrome/browser/resources/password_manager/dialogs/password_preview_item.html
@@ -0,0 +1,79 @@ +<style include="shared-style cr-shared-style"> + #checkbox { + --cr-checkbox-label-padding-start: 8px; + --cr-checkbox-size: 14px; + --cr-checkbox-border-size: 1px; + flex-grow: 0; + } + + site-favicon { + height: 16px; + padding-inline-end: 8px; + width: 16px; + } + + #container { + align-items: center; + display: grid; + flex-grow: 1; + grid-template-columns: auto 125px; + width: 100%; + } + + .url-username-group { + column-gap: 16px; + display: grid; + grid-template-columns: fit-content(50%) 1fr; + padding-inline-end: 16px; + width: 100%; + } + + #website { + color: var(--cr-primary-text-color); + } + + #password { + background-color: transparent; + border: none; + } + + #password:disabled { + flex: none; + font-family: inherit; + margin-inline-start: auto; + text-overflow: clip; + width: 50px; + } + + cr-icon-button { + --cr-icon-button-margin-start: 8px; + } + +</style> +<div class="flex-centered" focus-row-container> + <cr-checkbox id="checkbox" checked="{{checked}}"> + </cr-checkbox> + <div id="container" class$="[[getElementClass_(first)]]"> + <div class="flex-centered"> + <site-favicon domain="[[url]]" aria-hidden="true"> + </site-favicon> + <div class="url-username-group"> + <div id="website" class="text-elide">[[url]]</div> + <div id="username" class="text-elide">[[username]]</div> + </div> + </div> + <div class="flex-centered"> + <input id="password" readonly class="text-elide" + type="[[getPasswordInputType(isPasswordVisible)]]" + disabled$="[[!isPasswordVisible]]" + value="[[getPasswordValue_(isPasswordVisible, password)]]" + focus-row-control focus-type="passwordField"> + <cr-icon-button id="showPasswordButton" + title="[[getShowHideButtonLabel(isPasswordVisible)]]" + class$="[[getShowHideButtonIconClass(isPasswordVisible)]]" + on-click="onShowHidePasswordButtonClick" + focus-row-control focus-type="showPassword"> + </cr-icon-button> + </div> + </div> +</div>
diff --git a/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts b/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts new file mode 100644 index 0000000..c75b99a2 --- /dev/null +++ b/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts
@@ -0,0 +1,82 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview PasswordPreviewItem represents one row in a list of passwords. + * It needs to be its own component because FocusRowBehavior provides good a11y. + */ + +import 'chrome://resources/cr_elements/cr_icons.css.js'; +import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import '../site_favicon.js'; +import '../shared_style.css.js'; + +import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; +import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {ShowPasswordMixin} from '../show_password_mixin.js'; + +import {getTemplate} from './password_preview_item.html.js'; + +export interface PasswordPreviewItemElement { + $: { + checkbox: CrCheckboxElement, + website: HTMLElement, + username: HTMLElement, + password: HTMLInputElement, + showPasswordButton: CrIconButtonElement, + }; +} + +const PasswordPreviewItemElementBase = ShowPasswordMixin(PolymerElement); + +export class PasswordPreviewItemElement extends PasswordPreviewItemElementBase { + static get is() { + return 'password-preview-item'; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + passwordId: Number, + url: String, + username: String, + password: String, + first: Boolean, + + checked: { + type: Boolean, + value: true, + }, + }; + } + + passwordId: number; + url: string; + username: string; + password: string; + first: boolean; + checked: boolean; + + private getElementClass_(): string { + return this.first ? '' : 'hr'; + } + + private getPasswordValue_(): string { + return this.isPasswordVisible ? this.password : ' '.repeat(10); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'password-preview-item': PasswordPreviewItemElement; + } +} + +customElements.define( + PasswordPreviewItemElement.is, PasswordPreviewItemElement);
diff --git a/chrome/browser/resources/password_manager/password_manager_proxy.ts b/chrome/browser/resources/password_manager/password_manager_proxy.ts index dd2bf1ee..f3a16ed 100644 --- a/chrome/browser/resources/password_manager/password_manager_proxy.ts +++ b/chrome/browser/resources/password_manager/password_manager_proxy.ts
@@ -308,6 +308,12 @@ * @return A promise that resolves to whether the account store is default. */ isAccountStoreDefault(): Promise<boolean>; + + /** + * Moves a list of passwords from the device to the account + * @param ids The ids for the password entries being moved. + */ + movePasswordsToAccount(ids: number[]): void; } /** @@ -507,6 +513,10 @@ return chrome.passwordsPrivate.isAccountStoreDefault(); } + movePasswordsToAccount(ids: number[]) { + chrome.passwordsPrivate.movePasswordsToAccount(ids); + } + static getInstance(): PasswordManagerProxy { return instance || (instance = new PasswordManagerImpl()); }
diff --git a/chrome/browser/resources/password_manager/shared_style.css b/chrome/browser/resources/password_manager/shared_style.css index 23289d4..e076fb0 100644 --- a/chrome/browser/resources/password_manager/shared_style.css +++ b/chrome/browser/resources/password_manager/shared_style.css
@@ -71,3 +71,9 @@ text-overflow: ellipsis; white-space: nowrap; } + +.text-elide { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +}
diff --git a/chrome/browser/resources/privacy_sandbox/BUILD.gn b/chrome/browser/resources/privacy_sandbox/BUILD.gn index 987bd2f..d03c15d 100644 --- a/chrome/browser/resources/privacy_sandbox/BUILD.gn +++ b/chrome/browser/resources/privacy_sandbox/BUILD.gn
@@ -14,6 +14,7 @@ "privacy_sandbox_dialog.html", "privacy_sandbox_combined_dialog.html", "privacy_sandbox_notice_dialog.html", + "privacy_sandbox_notice_restricted_dialog.html", "images/privacy_sandbox_confirmation_banner.svg", "images/privacy_sandbox_confirmation_banner_dark.svg", @@ -28,6 +29,7 @@ "privacy_sandbox_dialog_app.ts", "privacy_sandbox_combined_dialog_app.ts", "privacy_sandbox_notice_dialog_app.ts", + "privacy_sandbox_notice_restricted_dialog_app.ts", "privacy_sandbox_dialog_consent_step.ts", "privacy_sandbox_dialog_notice_step.ts", "privacy_sandbox_dialog_learn_more.ts",
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html new file mode 100644 index 0000000..3bab63e --- /dev/null +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> +<head> + <meta charset="utf-8"> + <!-- TODO(b/277180532): add actual title, dialog structure, etc. --> + <script type="module" + src="privacy_sandbox_notice_restricted_dialog_app.js"></script> +</head> +<body> + <privacy-sandbox-notice-restricted-dialog-app> + </privacy-sandbox-notice-restricted-dialog-app> +</body> +</html>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html new file mode 100644 index 0000000..b399729 --- /dev/null +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html
@@ -0,0 +1,5 @@ +<!-- TODO(b/277180532): add actual title, dialog structure, etc. --> +<style include="cr-shared-style shared-style"></style> +<div fill-content role="main"> + $i18n{m1NoticeRestrictedDescription1} +</div>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts new file mode 100644 index 0000000..3afa501 --- /dev/null +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts
@@ -0,0 +1,44 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import './shared_style.css.js'; + +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {PrivacySandboxDialogResizeMixin} from './privacy_sandbox_dialog_resize_mixin.js'; +import {getTemplate} from './privacy_sandbox_notice_restricted_dialog_app.html.js'; + +const PrivacySandboxNoticeRestrictedDialogAppElementBase = + PrivacySandboxDialogResizeMixin(PolymerElement); + +export class PrivacySandboxNoticeRestrictedDialogAppElement extends + PrivacySandboxNoticeRestrictedDialogAppElementBase { + static get is() { + return 'privacy-sandbox-notice-restricted-dialog-app'; + } + + static get template() { + return getTemplate(); + } + + override ready() { + super.ready(); + + // TODO(b/277180532): fire the appropriate events, add more structure, etc. + this.resizeAndShowNativeDialog(); + } +} + + +declare global { + interface HTMLElementTagNameMap { + 'privacy-sandbox-notice-restricted-dialog-app': + PrivacySandboxNoticeRestrictedDialogAppElement; + } +} + +customElements.define( + PrivacySandboxNoticeRestrictedDialogAppElement.is, + PrivacySandboxNoticeRestrictedDialogAppElement);
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index 9122fb8..69c8e93e 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -265,6 +265,9 @@ if (is_chromeos) { web_component_files += [ "controls/password_prompt_dialog.ts" ] } + if (is_chrome_branded) { + web_component_files += [ "get_most_chrome_page/get_most_chrome_page.ts" ] + } # -----------------web_component_files end ----------------------------------
diff --git a/chrome/browser/resources/settings/about_page/about_page.ts b/chrome/browser/resources/settings/about_page/about_page.ts index 4608d09d..52c24ff3 100644 --- a/chrome/browser/resources/settings/about_page/about_page.ts +++ b/chrome/browser/resources/settings/about_page/about_page.ts
@@ -31,6 +31,11 @@ import {loadTimeData} from '../i18n_setup.js'; import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; +// <if expr="_google_chrome"> +import {routes} from '../route.js'; +import {Router} from '../router.js'; + +// </if> import {getTemplate} from './about_page.html.js'; import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, UpdateStatus, UpdateStatusChangedEvent} from './about_page_browser_proxy.js'; @@ -40,6 +45,7 @@ // </if> // clang-format on + const SettingsAboutPageElementBase = RelaunchMixin(WebUiListenerMixin(I18nMixin(PolymerElement))); @@ -82,7 +88,8 @@ showGetTheMostOutOfChromeSection_: { type: Boolean, value() { - return loadTimeData.getBoolean('showGetTheMostOutOfChromeSection'); + return loadTimeData.getBoolean('showGetTheMostOutOfChromeSection') && + !loadTimeData.getBoolean('isGuest'); }, }, // </if> @@ -342,8 +349,8 @@ this.aboutBrowserProxy_.openFeedbackDialog(); } - private onGetTheMostOutOfChromeClick_() { - // TODO(crbug.com/1423278): implement. + private onGetTheMostOutOfChromeTap_() { + Router.getInstance().navigateTo(routes.GET_MOST_CHROME); } // </if>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index 55ad4f0..2c9d775 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -205,6 +205,16 @@ <settings-reset-page prefs="{{prefs}}"></settings-reset-page> </settings-section> </template> +<if expr="_google_chrome"> + <template is="dom-if" + if="[[showGetMostChrome_(pageVisibility.getMostChrome)]]" + restamp> + <settings-section page-title="$i18n{getTheMostOutOfChrome}" + section="getMostChrome"> + <settings-get-most-chrome-page></settings-get-most-chrome-page> + </settings-section> + </template> +</if> </div> </template> </settings-idle-load>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.ts b/chrome/browser/resources/settings/basic_page/basic_page.ts index 000a5c0..bea931e 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.ts +++ b/chrome/browser/resources/settings/basic_page/basic_page.ts
@@ -395,6 +395,11 @@ } // <if expr="_google_chrome"> + private showGetMostChrome_(visibility?: boolean): boolean { + return visibility !== false && + loadTimeData.getBoolean('showGetTheMostOutOfChromeSection'); + } + private onSendHighEfficiencyFeedbackClick_(e: Event) { e.stopPropagation(); this.performanceBrowserProxy_.openHighEfficiencyFeedbackDialog();
diff --git a/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html new file mode 100644 index 0000000..7c89b54 --- /dev/null +++ b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html
@@ -0,0 +1 @@ +<div></div>
diff --git a/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts new file mode 100644 index 0000000..029614ab --- /dev/null +++ b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts
@@ -0,0 +1,32 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * 'settings-get-most-chrome-page' is the settings page information about how + * to get the most out of Chrome. + */ + +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './get_most_chrome_page.html.js'; + +export class SettingsGetMostChromePageElement extends PolymerElement { + static get is() { + return 'settings-get-most-chrome-page'; + } + + static get template() { + return getTemplate(); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'settings-get-most-chrome-page': SettingsGetMostChromePageElement; + } +} + +customElements.define( + SettingsGetMostChromePageElement.is, SettingsGetMostChromePageElement);
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts index 4fc7d32..04d16b8 100644 --- a/chrome/browser/resources/settings/lazy_load.ts +++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -66,6 +66,9 @@ // Sections import './a11y_page/a11y_page.js'; import './downloads_page/downloads_page.js'; +// <if expr="_google_chrome"> +import './get_most_chrome_page/get_most_chrome_page.js'; +// </if> // <if expr="not chromeos_ash"> import './languages_page/languages_page.js'; import './languages_page/spell_check_page.js'; @@ -138,6 +141,9 @@ export {SettingsSliderElement} from './controls/settings_slider.js'; export {DownloadsBrowserProxy, DownloadsBrowserProxyImpl} from './downloads_page/downloads_browser_proxy.js'; export {SettingsDownloadsPageElement} from './downloads_page/downloads_page.js'; +// <if expr="_google_chrome"> +export {SettingsGetMostChromePageElement} from './get_most_chrome_page/get_most_chrome_page.js'; +// </if> // <if expr="_google_chrome and is_win"> export {IncompatibleApplicationItemElement} from './incompatible_applications_page/incompatible_application_item.js'; export {ActionTypes, IncompatibleApplication, IncompatibleApplicationsBrowserProxy, IncompatibleApplicationsBrowserProxyImpl} from './incompatible_applications_page/incompatible_applications_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/page_visibility.ts b/chrome/browser/resources/settings/page_visibility.ts index c4829c17..0234474 100644 --- a/chrome/browser/resources/settings/page_visibility.ts +++ b/chrome/browser/resources/settings/page_visibility.ts
@@ -15,6 +15,7 @@ defaultBrowser?: boolean; downloads?: boolean; extensions?: boolean; + getMostChrome?: boolean; languages?: boolean; onStartup?: boolean; people?: boolean; @@ -55,6 +56,7 @@ defaultBrowser: false, downloads: false, extensions: false, + getMostChrome: false, languages: false, onStartup: false, people: false, @@ -87,6 +89,7 @@ downloads: true, a11y: true, extensions: false, + getMostChrome: false, languages: true, performance: false, };
diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts index 13971aa..7b63dfed 100644 --- a/chrome/browser/resources/settings/route.ts +++ b/chrome/browser/resources/settings/route.ts
@@ -262,6 +262,14 @@ '/performance', 'performance', loadTimeData.getString('performancePageTitle')); } + + // <if expr="_google_chrome"> + if (visibility.getMostChrome !== false) { + r.GET_MOST_CHROME = r.ADVANCED.createSection( + '/getMostChrome', 'getMostChrome', + loadTimeData.getString('getTheMostOutOfChrome')); + } + // </if> } return r as unknown as SettingsRoutes; }
diff --git a/chrome/browser/resources/settings/router.ts b/chrome/browser/resources/settings/router.ts index 5656181..c24a1ac 100644 --- a/chrome/browser/resources/settings/router.ts +++ b/chrome/browser/resources/settings/router.ts
@@ -29,6 +29,9 @@ DOWNLOADS: Route; EDIT_DICTIONARY: Route; FONTS: Route; + // <if expr="_google_chrome"> + GET_MOST_CHROME: Route; + // </if> IMPORT_DATA: Route; INCOMPATIBLE_APPLICATIONS: Route; LANGUAGES: Route;
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.html b/chrome/browser/resources/side_panel/read_anything/read_anything.html index 02d87e4..f446a00 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything.html +++ b/chrome/browser/resources/side_panel/read_anything/read_anything.html
@@ -18,7 +18,6 @@ body { overflow-wrap: break-word; overflow-x: hidden; - overflow-y: scroll; } </style> </head>
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper.cc b/chrome/browser/safe_browsing/chrome_user_population_helper.cc index c29d416..b1af691 100644 --- a/chrome/browser/safe_browsing/chrome_user_population_helper.cc +++ b/chrome/browser/safe_browsing/chrome_user_population_helper.cc
@@ -4,9 +4,11 @@ #include "chrome/browser/safe_browsing/chrome_user_population_helper.h" +#include "base/metrics/field_trial.h" #include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/browser_features.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/profiles/profile_manager.h" @@ -114,6 +116,43 @@ return population; } +ChromeUserPopulation GetUserPopulationForProfileWithCookieTheftExperiments( + Profile* profile) { + ChromeUserPopulation population = GetUserPopulationForProfile(profile); + + if (population.user_population() == + ChromeUserPopulation::ENHANCED_PROTECTION) { + static const base::NoDestructor<std::vector<const base::Feature*>> + kCookieTheftExperiments({ +#if BUILDFLAG(IS_WIN) + &features::kLockProfileCookieDatabase +#endif + }); + + GetExperimentStatus(*kCookieTheftExperiments, &population); + } + + return population; +} + +void GetExperimentStatus(const std::vector<const base::Feature*>& experiments, + ChromeUserPopulation* population) { + for (const base::Feature* feature : experiments) { + base::FieldTrial* field_trial = base::FeatureList::GetFieldTrial(*feature); + if (!field_trial) { + continue; + } + const std::string& trial = field_trial->trial_name(); + const std::string& group = field_trial->GetGroupNameWithoutActivation(); + bool is_experimental = group.find("Enabled") != std::string::npos || + group.find("Control") != std::string::npos; + bool is_preperiod = group.find("Preperiod") != std::string::npos; + if (is_experimental && !is_preperiod) { + population->add_finch_active_groups(trial + "." + group); + } + } +} + ChromeUserPopulation::PageLoadToken GetPageLoadTokenForURL(Profile* profile, GURL url) { if (!profile) {
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper.h b/chrome/browser/safe_browsing/chrome_user_population_helper.h index 53e6b95e..1953bd0 100644 --- a/chrome/browser/safe_browsing/chrome_user_population_helper.h +++ b/chrome/browser/safe_browsing/chrome_user_population_helper.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_CHROME_USER_POPULATION_HELPER_H_ #define CHROME_BROWSER_SAFE_BROWSING_CHROME_USER_POPULATION_HELPER_H_ +#include "base/feature_list.h" #include "chrome/browser/profiles/profile.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -15,6 +16,17 @@ // given |profile|. ChromeUserPopulation GetUserPopulationForProfile(Profile* profile); +// A convenience function that creates a ChromeUserPopulation proto for the +// given |profile|. This is used by real-time URL lookups and download pings to +// sometimes add telemetry about running experiments. +ChromeUserPopulation GetUserPopulationForProfileWithCookieTheftExperiments( + Profile* profile); + +// Get the status of each experiment in `experiments` and put it in the +// `finch_active_groups` field of `population`. +void GetExperimentStatus(const std::vector<const base::Feature*>& experiments, + ChromeUserPopulation* population); + // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class NoCachedPopulationReason {
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc b/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc index 9810f9b..abd21378 100644 --- a/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/safe_browsing/chrome_user_population_helper.h" +#include "base/feature_list.h" +#include "base/metrics/field_trial.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h" #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h" @@ -21,11 +24,16 @@ #include "components/version_info/version_info.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/protobuf/src/google/protobuf/repeated_ptr_field.h" namespace safe_browsing { namespace { +BASE_FEATURE(kTestCookieTheftFeature, + "TestCookieTheftFeature", + base::FEATURE_DISABLED_BY_DEFAULT); + std::unique_ptr<KeyedService> CreateTestSyncService( content::BrowserContext* context) { return std::make_unique<syncer::TestSyncService>(); @@ -210,4 +218,84 @@ EXPECT_TRUE(token.has_token_value()); } +TEST(GetExperimentStatusTest, HasEnabled) { + base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Enabled"); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "TestCookieTheftFeature<TestCookieTheftFeature.Enabled", ""); + + ChromeUserPopulation population; + GetExperimentStatus({&kTestCookieTheftFeature}, &population); + + ASSERT_EQ(population.finch_active_groups_size(), 1); + EXPECT_EQ(population.finch_active_groups(0), + "TestCookieTheftFeature.Enabled"); +} + +TEST(GetExperimentStatusTest, HasControl) { + base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Control"); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "TestCookieTheftFeature<TestCookieTheftFeature.Control", ""); + + ChromeUserPopulation population; + GetExperimentStatus({&kTestCookieTheftFeature}, &population); + + ASSERT_EQ(population.finch_active_groups_size(), 1); + EXPECT_EQ(population.finch_active_groups(0), + "TestCookieTheftFeature.Control"); +} + +TEST(GetExperimentStatusTest, OmitsDefault) { + base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Default"); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "TestCookieTheftFeature<TestCookieTheftFeature.Default", ""); + + ChromeUserPopulation population; + GetExperimentStatus({&kTestCookieTheftFeature}, &population); + + ASSERT_EQ(population.finch_active_groups_size(), 0); +} + +#if BUILDFLAG(IS_WIN) +TEST(GetUserPopulationForProfileWithCookieTheftExperiments, + PopulatesExperimentsForEsb) { + content::BrowserTaskEnvironment task_environment; + base::FieldTrialList::CreateFieldTrial("LockProfileCookieDatabase", + "Enabled"); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "LockProfileCookieDatabase<LockProfileCookieDatabase.Enabled", ""); + + TestingProfile profile; + SetSafeBrowsingState(profile.GetPrefs(), + SafeBrowsingState::ENHANCED_PROTECTION); + ChromeUserPopulation population = + GetUserPopulationForProfileWithCookieTheftExperiments(&profile); + + EXPECT_TRUE(base::Contains(population.finch_active_groups(), + "LockProfileCookieDatabase.Enabled")); +} + +TEST(GetUserPopulationForProfileWithCookieTheftExperiments, + DoesNotPopulateExperimentsForSsb) { + content::BrowserTaskEnvironment task_environment; + base::FieldTrialList::CreateFieldTrial("LockProfileCookieDatabase", + "Enabled"); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "LockProfileCookieDatabase<LockProfileCookieDatabase.Enabled", ""); + + TestingProfile profile; + SetSafeBrowsingState(profile.GetPrefs(), + SafeBrowsingState::STANDARD_PROTECTION); + ChromeUserPopulation population = + GetUserPopulationForProfileWithCookieTheftExperiments(&profile); + + EXPECT_FALSE(base::Contains(population.finch_active_groups(), + "LockProfileCookieDatabase.Enabled")); +} +#endif + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc index d585d97..034f7e9a 100644 --- a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc +++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
@@ -165,7 +165,8 @@ profile && AdvancedProtectionStatusManagerFactory::GetForProfile(profile) ->IsUnderAdvancedProtection(); - *request_->mutable_population() = GetUserPopulationForProfile(profile); + *request_->mutable_population() = + GetUserPopulationForProfileWithCookieTheftExperiments(profile); if (base::FeatureList::IsEnabled(kNestedArchives)) { request_->mutable_population()->add_finch_active_groups( "SafeBrowsingArchiveImprovements.Enabled");
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.cc b/chrome/browser/safe_browsing/url_lookup_service_factory.cc index 8fea58d6..8edc3c9 100644 --- a/chrome/browser/safe_browsing/url_lookup_service_factory.cc +++ b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
@@ -74,7 +74,9 @@ return new RealTimeUrlLookupService( network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)), VerdictCacheManagerFactory::GetForProfile(profile), - base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, profile), + base::BindRepeating( + &safe_browsing::GetUserPopulationForProfileWithCookieTheftExperiments, + profile), profile->GetPrefs(), std::make_unique<SafeBrowsingPrimaryAccountTokenFetcher>( IdentityManagerFactory::GetForProfile(profile)),
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java index 670f430..773c6db4 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
@@ -9,6 +9,7 @@ import android.content.ClipboardManager; import android.content.Context; import android.net.Uri; +import android.text.TextUtils; import android.view.View; import androidx.annotation.Nullable; @@ -277,7 +278,7 @@ } private void maybeAddQrCodeFirstPartyOption() { - if (!mIsIncognito) { + if (!mIsIncognito && !TextUtils.isEmpty(mUrl)) { mOrderedFirstPartyOptions.add(createQrCodeFirstPartyOption()); } }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java index c7d8a68..b1b9954 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
@@ -123,11 +123,12 @@ if (showCustomActions) { boolean isInMultiWindow = ApiCompatibilityUtils.isInMultiWindowMode(activity); - var actionProvider = new AndroidCustomActionProvider( - params.getWindow().getActivity().get(), params.getWindow(), mTabProvider, - mController, params, mPrintCallback, isIncognito, this, - TrackerFactory.getTrackerForProfile(profile), params.getUrl(), profile, - chromeShareExtras, isInMultiWindow, mLinkToTextCoordinator); + var actionProvider = + new AndroidCustomActionProvider(params.getWindow().getActivity().get(), + params.getWindow(), mTabProvider, mController, params, mPrintCallback, + isIncognito, this, TrackerFactory.getTrackerForProfile(profile), + getUrlToShare(params, chromeShareExtras), profile, chromeShareExtras, + isInMultiWindow, mLinkToTextCoordinator); if (actionProvider.getCustomActions().size() > 0 || actionProvider.getModifyShareAction() != null) { provider = actionProvider; @@ -142,9 +143,10 @@ // Update the image being shared into ShareParams's url based on the information from // chromeShareExtras. if (chromeShareExtras.isImage()) { - String imageUrlToShare = getImageUrlToShare(params, chromeShareExtras); + String imageUrlToShare = getUrlToShare(params, chromeShareExtras); params.setUrl(imageUrlToShare); } + if (!isLinkSharing(params, chromeShareExtras)) { ShareHelper.shareWithSystemShareSheetUi( params, profile, chromeShareExtras.saveLastUsed(), provider); @@ -221,7 +223,7 @@ || contents.contains(ContentType.LINK_PAGE_NOT_VISIBLE); } - private static String getImageUrlToShare( + private static String getUrlToShare( ShareParams shareParams, ChromeShareExtras chromeShareExtras) { if (!TextUtils.isEmpty(shareParams.getUrl())) { return shareParams.getUrl();
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java index 5973e0a..4db32ae 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.app.FragmentManager; +import android.text.TextUtils; import org.chromium.ui.base.WindowAndroid; @@ -23,6 +24,7 @@ * @param windowAndroid the WindowAndroid to access system permissions. */ public QrCodeCoordinator(Activity activity, String url, WindowAndroid windowAndroid) { + assert !TextUtils.isEmpty(url) : "URL for QR code is empty."; mDialog = QrCodeDialog.newInstance(url, windowAndroid); mFragmentManager = activity.getFragmentManager();
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java index bc0e0d3..5541627 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
@@ -27,6 +27,7 @@ import android.text.TextUtils; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.core.os.BuildCompat; import androidx.lifecycle.Lifecycle.State; import androidx.test.ext.junit.rules.ActivityScenarioRule; @@ -39,6 +40,7 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.Shadows; @@ -63,10 +65,9 @@ import org.chromium.chrome.browser.share.ChromeShareExtras; import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType; import org.chromium.chrome.browser.share.ShareHelper; -import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowBuildCompatForU; -import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowChooserActionHelper; import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowShareImageFileUtils; import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator; +import org.chromium.chrome.browser.share.qrcode.QrCodeDialog; import org.chromium.chrome.browser.share.send_tab_to_self.SendTabToSelfAndroidBridgeJni; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -107,11 +108,6 @@ private static final String KEY_CHOOSER_ACTION_ACTION = "action"; private static final String SELECTOR_FOR_LINK_TO_TEXT = "selector"; - private static final String USER_ACTION_SEND_TAB_TO_SELF_SELECTED = - "SharingHubAndroid.SendTabToSelfSelected"; - private static final String USER_ACTION_QR_CODE_SELECTED = "SharingHubAndroid.QRCodeSelected"; - private static final String USER_ACTION_PRINT_SELECTED = "SharingHubAndroid.PrintSelected"; - private static final Uri TEST_WEB_FAVICON_PREVIEW_URI = Uri.parse("content://test.web.favicon.preview"); private static final Uri TEST_FALLBACK_FAVICON_PREVIEW_URI = @@ -193,6 +189,7 @@ @After public void tearDown() { ShadowLinkToTextCoordinator.setForceToFail(null); + ShadowQrCodeDialog.sLastUrl = null; mWindow.destroy(); TrackerFactory.setTrackerForTests(null); } @@ -258,27 +255,7 @@ () -> mTab, () -> mTabModelSelector, () -> mProfile, mPrintCallback::notifyCalled); Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity(); - Parcelable[] actions = intent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS); - - Assert.assertTrue("More than one action is provided.", actions.length > 0); - - // Find the print callback, since we mocked that out during this test. - Bundle printOption = null; - for (Parcelable parcelable : actions) { - Bundle bundle = (Bundle) parcelable; - if (TextUtils.equals(ContextUtils.getApplicationContext().getString( - R.string.print_share_activity_title), - bundle.getString(KEY_CHOOSER_ACTION_NAME))) { - printOption = bundle; - break; - } - } - - Assert.assertNotNull("Print option is null when the callback is provided.", printOption); - - PendingIntent action = printOption.getParcelable(KEY_CHOOSER_ACTION_ACTION); - action.send(); - ShadowLooper.idleMainLooper(); + chooseCustomAction(intent, R.string.print_share_activity_title); Assert.assertEquals("Print callback is not called.", 1, mPrintCallback.getCallCount()); Assert.assertEquals( "TargetChosenCallback is not called.", 1, callbackHelper.getCallCount()); @@ -456,6 +433,35 @@ assertCustomActions(chooserIntent, R.string.sharing_long_screenshot); } + @Test + @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class, + ShadowQrCodeDialog.class}) + public void + chooseQRCodeAction() throws CanceledException { + Uri testImageUri = Uri.parse("content://test.image.uri"); + ShareParams params = new ShareParams.Builder(mWindow, "", "") + .setFileContentType("image/png") + .setSingleImageUri(testImageUri) + .setBypassFixingDomDistillerUrl(true) + .build(); + ChromeShareExtras chromeShareExtras = + new ChromeShareExtras.Builder() + .setDetailedContentType(DetailedContentType.IMAGE) + .setContentUrl(JUnitTestGURLs.getGURL(JUnitTestGURLs.GOOGLE_URL)) + .setImageSrcUrl(JUnitTestGURLs.getGURL(JUnitTestGURLs.GOOGLE_URL_DOGS)) + .build(); + + mController.showShareSheet(params, chromeShareExtras, 1L); + + Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity(); + assertCustomActions(intent, R.string.sharing_long_screenshot, + R.string.send_tab_to_self_share_activity_title, R.string.qr_code_share_icon_label); + chooseCustomAction(intent, R.string.qr_code_share_icon_label); + + Assert.assertEquals("Last URL does not match content being shared.", + JUnitTestGURLs.GOOGLE_URL_DOGS, ShadowQrCodeDialog.sLastUrl); + } + private void setFaviconToFetchForTest(Bitmap favicon) { doAnswer(invocation -> { FaviconHelper.FaviconImageCallback callback = invocation.getArgument(4); @@ -495,6 +501,31 @@ "Actions and/or the order does not match.", expectedString, actualString); } + private void chooseCustomAction(Intent chooserIntent, @StringRes int iconLabel) + throws CanceledException { + Parcelable[] actions = + chooserIntent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS); + Assert.assertTrue("More than one action is provided.", actions.length > 0); + + // Find the print callback, since we mocked that out during this test. + Bundle expectAction = null; + for (Parcelable parcelable : actions) { + Bundle bundle = (Bundle) parcelable; + if (TextUtils.equals( + ContextUtils.getApplicationContext().getResources().getString(iconLabel), + bundle.getString(KEY_CHOOSER_ACTION_NAME))) { + expectAction = bundle; + break; + } + } + + Assert.assertNotNull("Print option is null when the callback is provided.", expectAction); + + PendingIntent action = expectAction.getParcelable(KEY_CHOOSER_ACTION_ACTION); + action.send(); + ShadowLooper.idleMainLooper(); + } + /** * Test implementation to build a ChooserAction. */ @@ -563,4 +594,15 @@ mRealObj.onSelectorReady(fail ? "" : SELECTOR_FOR_LINK_TO_TEXT); } } + + @Implements(QrCodeDialog.class) + static class ShadowQrCodeDialog { + static @Nullable String sLastUrl; + + @Implementation + protected static QrCodeDialog newInstance(String url, WindowAndroid windowAndroid) { + sLastUrl = url; + return Mockito.mock(QrCodeDialog.class); + } + } }
diff --git a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc index c7130cec..0ed4c33 100644 --- a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc +++ b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc
@@ -4,13 +4,7 @@ #include "chrome/browser/supervised_user/chromeos/web_content_handler_impl.h" -#include "base/check.h" #include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/logging.h" -#include "base/notreached.h" -#include "chrome/browser/ash/crosapi/crosapi_manager.h" -#include "chrome/browser/ash/crosapi/parent_access_ash.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/supervised_user/chromeos/supervised_user_favicon_request_handler.h" @@ -25,6 +19,12 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image_skia.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/crosapi/crosapi_ash.h" +#include "chrome/browser/ash/crosapi/crosapi_manager.h" +#include "chrome/browser/ash/crosapi/parent_access_ash.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + namespace { supervised_user::WebContentHandler::LocalApprovalResult @@ -92,6 +92,7 @@ const GURL& url, const std::u16string& child_display_name, ApprovalRequestInitiatedCallback callback) { +#if BUILDFLAG(IS_CHROMEOS_ASH) CHECK(web_contents_); supervised_user::SupervisedUserSettingsService* settings_service = SupervisedUserSettingsServiceFactory::GetForKey( @@ -100,16 +101,18 @@ crosapi::mojom::ParentAccess* parent_access = crosapi::CrosapiManager::Get()->crosapi_ash()->parent_access_ash(); - DCHECK(parent_access); - - gfx::ImageSkia favicon = favicon_handler_->GetFaviconOrFallback(); + CHECK(parent_access); parent_access->GetWebsiteParentApproval( - url.GetWithEmptyPath(), child_display_name, favicon, + url.GetWithEmptyPath(), child_display_name, + favicon_handler_->GetFaviconOrFallback(), base::BindOnce(&WebContentHandlerImpl::OnLocalApprovalRequestCompleted, weak_ptr_factory_.GetWeakPtr(), std::ref(*settings_service), url, base::TimeTicks::Now())); std::move(callback).Run(true); +#else // Local Web approvals not yet supported on Lacros. + NOTREACHED_NORETURN(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } void WebContentHandlerImpl::ShowFeedback(GURL url, std::u16string reason) {
diff --git a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h index 8995769..e1c8094c 100644 --- a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h +++ b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h
@@ -9,8 +9,8 @@ #include <string> #include "base/memory/weak_ptr.h" -#include "chrome/browser/ash/crosapi/crosapi_ash.h" #include "chrome/browser/supervised_user/chrome_web_content_handler_base.h" +#include "chromeos/crosapi/mojom/parent_access.mojom.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" @@ -22,7 +22,7 @@ class SupervisedUserFaviconRequestHandler; -// Chrome Ash specific implementation of web content handler. +// Chrome OS specific implementation of web content handler. class WebContentHandlerImpl : public ChromeWebContentHandlerBase { public: WebContentHandlerImpl(content::WebContents* web_contents,
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc index b8c0385b..91cf3cac 100644 --- a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc +++ b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
@@ -41,7 +41,7 @@ #include "chrome/browser/supervised_user/android/web_content_handler_impl.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/supervised_user/chromeos/web_content_handler_impl.h" #endif @@ -52,7 +52,7 @@ GURL url, Profile* profile, int frame_id) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) return std::make_unique<WebContentHandlerImpl>( web_contents, url, *LargeIconServiceFactory::GetForBrowserContext(profile), frame_id);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java index 0522bb9b..0d97220 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
@@ -25,7 +25,6 @@ import org.chromium.base.TraceEvent; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi; import org.chromium.chrome.browser.profiles.Profile; @@ -375,17 +374,6 @@ } } - // TODO(crbug.com/1330739): remove this. - if (!ChromeFeatureList.isEnabled( - ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION)) { - // These calls used to be necessary to record obsoleted - // histograms. We keep them here temporarily to measure the - // impact of removing them. - getLocationSource(); - getGeolocationPermission(tab); - getDomainPermission(profile, url); - } - // Proto encoding String locationProtoEncoding = encodeProtoLocation(locationToAttach); String visibleNetworksProtoEncoding =
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java index 98756af6c..e9fda239 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
@@ -30,14 +30,12 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileJni; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni; import org.chromium.components.content_settings.ContentSettingValues; @@ -57,7 +55,6 @@ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) @LooperMode(LooperMode.Mode.LEGACY) -@DisableFeatures({ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION}) public class GeolocationHeaderUnitTest { private static final String SEARCH_URL = "https://www.google.com/search?q=potatoes";
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 1a9051f..1386d9fc 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -167,12 +167,6 @@ return true; } -bool IsPinnedHomeTab(Browser* browser) { - return web_app::AppBrowserController::IsWebApp(browser) && - web_app::IsPinnedHomeTab(browser->tab_strip_model(), - browser->tab_strip_model()->active_index()); -} - } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -1408,9 +1402,11 @@ bool is_isolated_app = current_web_contents->GetPrimaryMainFrame() ->GetWebExposedIsolationLevel() >= WebExposedIsolationLevel::kMaybeIsolatedApplication; + bool is_pinned_home_tab = web_app::IsPinnedHomeTab( + browser_->tab_strip_model(), browser_->tab_strip_model()->active_index()); command_updater_.UpdateCommandEnabled( IDC_OPEN_IN_CHROME, - IsWebAppOrCustomTab() && !is_isolated_app && !IsPinnedHomeTab(browser_)); + IsWebAppOrCustomTab() && !is_isolated_app && !is_pinned_home_tab); command_updater_.UpdateCommandEnabled( IDC_TOGGLE_REQUEST_TABLET_SITE, @@ -1757,8 +1753,8 @@ void BrowserCommandController::UpdateCommandsForTabStripStateChanged() { command_updater_.UpdateCommandEnabled( - IDC_CLOSE_TAB, - !IsPinnedHomeTab(browser_) || browser_->tab_strip_model()->count() == 1); + IDC_CLOSE_TAB, browser_->tab_strip_model()->IsTabClosable( + browser_->tab_strip_model()->active_index())); } BrowserWindow* BrowserCommandController::window() {
diff --git a/chrome/browser/ui/performance_controls/performance_controls_metrics.cc b/chrome/browser/ui/performance_controls/performance_controls_metrics.cc index d2b6e3f..da6b2bed 100644 --- a/chrome/browser/ui/performance_controls/performance_controls_metrics.cc +++ b/chrome/browser/ui/performance_controls/performance_controls_metrics.cc
@@ -21,11 +21,6 @@ "PerformanceControls.HighEfficiency.BubbleAction", type); } -void RecordHighEfficiencyInfoIPHOpenSettings(bool success) { - base::UmaHistogramBoolean( - "PerformanceControls.HighEfficiency.InfoIPHOpenSettings", success); -} - void RecordHighEfficiencyIPHEnableMode(bool success) { base::UmaHistogramBoolean("PerformanceControls.HighEfficiency.IPHEnableMode", success);
diff --git a/chrome/browser/ui/performance_controls/performance_controls_metrics.h b/chrome/browser/ui/performance_controls/performance_controls_metrics.h index 2ae8f21..87f55ae 100644 --- a/chrome/browser/ui/performance_controls/performance_controls_metrics.h +++ b/chrome/browser/ui/performance_controls/performance_controls_metrics.h
@@ -24,7 +24,6 @@ void RecordBatterySaverBubbleAction(BatterySaverBubbleActionType type); void RecordBatterySaverIPHOpenSettings(bool success); void RecordHighEfficiencyBubbleAction(HighEfficiencyBubbleActionType type); -void RecordHighEfficiencyInfoIPHOpenSettings(bool success); void RecordHighEfficiencyIPHEnableMode(bool success); #endif // CHROME_BROWSER_UI_PERFORMANCE_CONTROLS_PERFORMANCE_CONTROLS_METRICS_H_
diff --git a/chrome/browser/ui/quick_answers/BUILD.gn b/chrome/browser/ui/quick_answers/BUILD.gn index d9e6aca4..db7e7a5c 100644 --- a/chrome/browser/ui/quick_answers/BUILD.gn +++ b/chrome/browser/ui/quick_answers/BUILD.gn
@@ -24,6 +24,8 @@ "ui/rich_answers_pre_target_handler.h", "ui/rich_answers_translation_view.cc", "ui/rich_answers_translation_view.h", + "ui/rich_answers_unit_conversion_view.cc", + "ui/rich_answers_unit_conversion_view.h", "ui/rich_answers_view.cc", "ui/rich_answers_view.h", "ui/user_consent_view.cc",
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc new file mode 100644 index 0000000..d54021c --- /dev/null +++ b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc
@@ -0,0 +1,31 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h" + +#include "base/functional/bind.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" +#include "ui/views/layout/fill_layout.h" + +// RichAnswersUnitConversionView +// ----------------------------------------------------------- + +RichAnswersUnitConversionView::RichAnswersUnitConversionView( + const quick_answers::QuickAnswer& result) { + InitLayout(); + + // TODO (b/274184290): Add custom focus behavior according to + // approved greenlines. +} + +RichAnswersUnitConversionView::~RichAnswersUnitConversionView() = default; + +const char* RichAnswersUnitConversionView::GetClassName() const { + return "RichAnswersUnitConversionView"; +} + +void RichAnswersUnitConversionView::InitLayout() { + // TODO (b/265255270): Populate unit conversion view contents. +}
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h new file mode 100644 index 0000000..b296a40 --- /dev/null +++ b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h
@@ -0,0 +1,34 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_ + +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/quick_answers/ui/rich_answers_view.h" +#include "ui/views/view.h" + +// A bubble style view to show QuickAnswer. +class RichAnswersUnitConversionView : public views::View { + public: + explicit RichAnswersUnitConversionView( + const quick_answers::QuickAnswer& result); + + RichAnswersUnitConversionView(const RichAnswersUnitConversionView&) = delete; + RichAnswersUnitConversionView& operator=( + const RichAnswersUnitConversionView&) = delete; + + ~RichAnswersUnitConversionView() override; + + // views::View: + const char* GetClassName() const override; + + private: + void InitLayout(); + + base::WeakPtrFactory<RichAnswersUnitConversionView> weak_factory_{this}; +}; + +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc b/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc index 400df35..63163e8 100644 --- a/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc +++ b/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/quick_answers/ui/rich_answers_definition_view.h" #include "chrome/browser/ui/quick_answers/ui/rich_answers_pre_target_handler.h" #include "chrome/browser/ui/quick_answers/ui/rich_answers_translation_view.h" +#include "chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h" #include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/vector_icons/vector_icons.h" @@ -163,8 +164,10 @@ return; } case quick_answers::ResultType::kUnitConversionResult: + content_view_ = base_view_->AddChildView( + std::make_unique<RichAnswersUnitConversionView>(result)); + return; default: { - // TODO(b/259440976): Add child views for each result type. return; } }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index a3b13fb..800732d7 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -50,6 +50,7 @@ #include "chrome/browser/ui/user_notes/user_notes_controller.h" #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" +#include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -808,6 +809,10 @@ return contents_data_[index]->blocked(); } +bool TabStripModel::IsTabClosable(int index) const { + return !web_app::IsPinnedHomeTab(this, index) || count() == 1; +} + absl::optional<tab_groups::TabGroupId> TabStripModel::GetTabGroupForTab( int index) const { return ContainsIndex(index) ? contents_data_[index]->group() : absl::nullopt;
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index 6f68f06..c1e901c 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -347,6 +347,9 @@ // Returns true if the tab at |index| is blocked by a tab modal dialog. bool IsTabBlocked(int index) const; + // Returns true if the tab at |index| is allowed to be closed. + bool IsTabClosable(int index) const; + // Returns the group that contains the tab at |index|, or nullopt if the tab // index is invalid or not grouped. absl::optional<tab_groups::TabGroupId> GetTabGroupForTab(
diff --git a/chrome/browser/ui/tabs/tab_style.cc b/chrome/browser/ui/tabs/tab_style.cc index cb37a0e..ec1c357c 100644 --- a/chrome/browser/ui/tabs/tab_style.cc +++ b/chrome/browser/ui/tabs/tab_style.cc
@@ -19,64 +19,68 @@ return ui::TouchUiController::Get()->touch_ui() ? 24 : 20; } -class GM2TabStyle : public TabStyle {}; -class ChromeRefresh2023TabStyle : public GM2TabStyle {}; +class GM2TabStyle : public TabStyle { + public: + ~GM2TabStyle() override = default; +}; +class ChromeRefresh2023TabStyle : public GM2TabStyle { + public: + ~ChromeRefresh2023TabStyle() override = default; +}; } // namespace TabStyle::~TabStyle() = default; -// static -int TabStyle::GetStandardWidth() { +int TabStyle::GetStandardWidth() const { // The standard tab width is 240 DIP including both separators. constexpr int kTabWidth = 240; // The overlap includes one separator, so subtract it here. return kTabWidth + GetTabOverlap() - kSeparatorThickness; } -// static -int TabStyle::GetPinnedWidth() { +int TabStyle::GetPinnedWidth() const { constexpr int kTabPinnedContentWidth = 24; return kTabPinnedContentWidth + GetContentsHorizontalInsetSize() * 2; } -// static -int TabStyle::GetTabOverlap() { +int TabStyle::GetTabOverlap() const { return GetCornerRadius() * 2 + kSeparatorThickness; } -// static -int TabStyle::GetDragHandleExtension(int height) { +int TabStyle::GetDragHandleExtension(int height) const { return (height - GetSeparatorHeight()) / 2 - 1; } -// static -gfx::Size TabStyle::GetSeparatorSize() { +gfx::Size TabStyle::GetSeparatorSize() const { return gfx::Size(kSeparatorThickness, GetSeparatorHeight()); } -// static -gfx::Size TabStyle::GetPreviewImageSize() { +gfx::Size TabStyle::GetPreviewImageSize() const { constexpr float kTabHoverCardPreviewImageAspectRatio = 16.0f / 9.0f; const int width = GetStandardWidth(); return gfx::Size(width, width / kTabHoverCardPreviewImageAspectRatio); } -// static -int TabStyle::GetCornerRadius() { +int TabStyle::GetCornerRadius() const { return views::LayoutProvider::Get()->GetCornerRadiusMetric( views::Emphasis::kHigh); } -// static -int TabStyle::GetContentsHorizontalInsetSize() { +int TabStyle::GetContentsHorizontalInsetSize() const { return GetCornerRadius() * 2; } -std::unique_ptr<const TabStyle> TabStyle::Create() { - // If refresh is turned on use ChromeRefresh23 styling. - if (features::IsChromeRefresh2023()) { - return std::make_unique<ChromeRefresh2023TabStyle>(); - } - return std::make_unique<GM2TabStyle>(); +float TabStyle::GetSelectedTabOpacity() const { + return kDefaultSelectedTabOpacity; +} + +// static +const TabStyle* TabStyle::Get() { + static TabStyle* const tab_style = + features::IsChromeRefresh2023() + ? static_cast<TabStyle*>(new ChromeRefresh2023TabStyle()) + : static_cast<TabStyle*>(new GM2TabStyle()); + + return tab_style; }
diff --git a/chrome/browser/ui/tabs/tab_style.h b/chrome/browser/ui/tabs/tab_style.h index 9d835227..104f21f 100644 --- a/chrome/browser/ui/tabs/tab_style.h +++ b/chrome/browser/ui/tabs/tab_style.h
@@ -104,28 +104,31 @@ // Returns the preferred width of a single Tab, assuming space is // available. - static int GetStandardWidth(); + virtual int GetStandardWidth() const; // Returns the width for pinned tabs. Pinned tabs always have this width. - static int GetPinnedWidth(); + virtual int GetPinnedWidth() const; // Returns the overlap between adjacent tabs. - static int GetTabOverlap(); + virtual int GetTabOverlap() const; // Gets the size of the separator drawn between tabs, if any. - static gfx::Size GetSeparatorSize(); + virtual gfx::Size GetSeparatorSize() const; // Returns, for a tab of height |height|, how far the window top drag handle // can extend down into inactive tabs or the new tab button. This behavior // is not used in all cases. - static int GetDragHandleExtension(int height); + virtual int GetDragHandleExtension(int height) const; // Gets the preferred size for tab previews, which could be screencaps, hero // or og:image images, etc. - static gfx::Size GetPreviewImageSize(); + virtual gfx::Size GetPreviewImageSize() const; // Returns the radius of the outer corners of the tab shape. - static int GetCornerRadius(); + virtual int GetCornerRadius() const; + + // Opacity of the active tab background painted over inactive selected tabs. + virtual float GetSelectedTabOpacity() const; // The largest valid value of TabStyle::GetZValue(). Currently, // GM2TabStyle::GetZValue is the only implementation, and it can't return @@ -134,7 +137,7 @@ static constexpr float kDefaultSelectedTabOpacity = 0.75f; - static std::unique_ptr<const TabStyle> Create(); + static const TabStyle* Get(); protected: // Avoid implicitly-deleted constructor. @@ -142,7 +145,7 @@ // Returns how far from the leading and trailing edges of a tab the contents // should actually be laid out. - static int GetContentsHorizontalInsetSize(); + int GetContentsHorizontalInsetSize() const; }; #endif // CHROME_BROWSER_UI_TABS_TAB_STYLE_H_
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc index 4e722c20..ab1473d 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
@@ -49,7 +49,7 @@ // Compute minimum sizes for multiple uses of the thumbnail - currently, // tablet tabstrip previews and tab hover card preview images. - gfx::Size min_target_size = TabStyle::GetPreviewImageSize(); + gfx::Size min_target_size = TabStyle::Get()->GetPreviewImageSize(); min_target_size.SetToMax( {kMinThumbnailDimensionForTablet, kMinThumbnailDimensionForTablet});
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index dd780fd..e3cdbdc 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -134,7 +134,15 @@ UpgradeDetector::GetInstance()->is_outdated_install_no_au()) { return l10n_util::GetStringUTF16(IDS_UPGRADE_BUBBLE_MENU_ITEM); } else { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) + return l10n_util::GetStringUTF16( + base::FeatureList::IsEnabled(features::kUpdateTextOptions) + ? IDS_RELAUNCH_TO_UPDATE_ALT + : IDS_RELAUNCH_TO_UPDATE); +#else return l10n_util::GetStringUTF16(IDS_RELAUNCH_TO_UPDATE); +#endif } }
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 8b53c74..2cc87e8 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -273,6 +273,18 @@ "TopChromeWebUIUsesSpareRenderer", base::FEATURE_ENABLED_BY_DEFAULT); +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +// Enables alternate update-related text to be displayed in browser app menu +// button, menu item and confirmation dialog. +BASE_FEATURE(kUpdateTextOptions, + "UpdateTextOptions", + base::FEATURE_DISABLED_BY_DEFAULT); +// Used to present different flavors of update strings in browser app menu +// button. +const base::FeatureParam<int> kUpdateTextOptionNumber{ + &kUpdateTextOptions, "UpdateTextOptionNumber", 1}; +#endif + // This enables enables persistence of a WebContents in a 1-to-1 association // with the current Profile for WebUI bubbles. See https://crbug.com/1177048. BASE_FEATURE(kWebUIBubblePerProfilePersistence,
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index 96d57a48..fbc1030 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -185,6 +185,11 @@ BASE_DECLARE_FEATURE(kTopChromeWebUIUsesSpareRenderer); +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +BASE_DECLARE_FEATURE(kUpdateTextOptions); +extern const base::FeatureParam<int> kUpdateTextOptionNumber; +#endif + BASE_DECLARE_FEATURE(kWebUIBubblePerProfilePersistence); BASE_DECLARE_FEATURE(kWebUITabStrip);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 5b51144..60ccdbf 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -198,6 +198,7 @@ views::InstallPillHighlightPathGenerator(this); SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); SetHideInkDropWhenShowingContextMenu(false); show_animation_ = std::make_unique<gfx::SlideAnimation>(this);
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc b/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc index 062793c..ad6613f 100644 --- a/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc +++ b/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc
@@ -209,7 +209,8 @@ // TabStripRegionViewTestWithScrollingEnabled.TabStripCanBeLargerThanContainer. TEST_F(TabStripRegionViewTestWithScrollingDisabled, TabStripCannotBeLargerThanContainer) { - const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth(); + const int minimum_active_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); controller_->AddTab(0, TabActive::kActive); CompleteAnimationAndLayout(); @@ -249,7 +250,8 @@ // TabStripCannotBeLargerThanContainer. TEST_F(TabStripRegionViewTestWithScrollingEnabled, TabStripCanBeLargerThanContainer) { - const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth(); + const int minimum_active_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); controller_->AddTab(0, TabActive::kActive); CompleteAnimationAndLayout(); @@ -276,7 +278,8 @@ TEST_F(TabStripRegionViewTestWithScrollingEnabled, TabStripScrollButtonsNotInWindowCaption) { - const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth(); + const int minimum_active_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); controller_->AddTab(0, TabActive::kActive); CompleteAnimationAndLayout();
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc index d53343e8..a7b8f49 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc
@@ -13,6 +13,8 @@ #include "chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/browser/ui/cookie_controls_controller.h" +#include "components/omnibox/browser/omnibox_field_trial.h" +#include "components/omnibox/browser/vector_icons.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" @@ -119,6 +121,12 @@ } const gfx::VectorIcon& CookieControlsIconView::GetVectorIcon() const { + if (OmniboxFieldTrial::IsChromeRefreshIconsEnabled()) { + return status_ == CookieControlsStatus::kDisabledForSite + ? omnibox::kCookieChromeRefreshIcon + : omnibox::kCookieCrossedChromeRefreshIcon; + } + return status_ == CookieControlsStatus::kDisabledForSite ? views::kEyeIcon : views::kEyeCrossedIcon;
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc index 57fa941..a8f903d 100644 --- a/chrome/browser/ui/views/location_bar/find_bar_icon.cc +++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/grit/generated_resources.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/vector_icons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -55,7 +56,9 @@ } const gfx::VectorIcon& FindBarIcon::GetVectorIcon() const { - return omnibox::kFindInPageIcon; + return OmniboxFieldTrial::IsChromeRefreshIconsEnabled() + ? omnibox::kFindInPageChromeRefreshIcon + : omnibox::kFindInPageIcon; } void FindBarIcon::UpdateImpl() {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 09b222c..995186c 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -187,7 +187,7 @@ !v->GetOmniboxPopupView()->IsOpen(); }); if (features::IsChromeRefresh2023()) { - views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); } views::InstallPillHighlightPathGenerator(this);
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc index 430c850..30b4d41 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -113,7 +113,7 @@ }, this)); if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) { - focus_ring->SetOutsetFocusRingDisabled(); + focus_ring->SetOutsetFocusRingDisabled(true); } } // Only shows bubble after mouse is released.
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc index 639480b..7e54608 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" #include "chrome/grit/generated_resources.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/password_manager/core/common/password_manager_ui.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" @@ -81,7 +82,9 @@ } const gfx::VectorIcon& ManagePasswordsIconViews::GetVectorIcon() const { - return kKeyIcon; + return OmniboxFieldTrial::IsChromeRefreshIconsEnabled() + ? kKeyChromeRefreshIcon + : kKeyIcon; } std::u16string ManagePasswordsIconViews::GetTextForTooltipAndAccessibleName()
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc index b2b3041..ca54137 100644 --- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc +++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc
@@ -35,12 +35,6 @@ // The duration that the chip should be expanded for. constexpr base::TimeDelta kChipAnimationDuration = base::Seconds(12); -// The delay before the IPH should be potentially shown. This should be less -// than kChipAnimationDuration but longer than kIconLabelAnimationDurationMs. -constexpr base::TimeDelta kIPHDelayDuration = base::Seconds(1); - -// We want this to show up before the chip finishes animating. -static_assert(kIPHDelayDuration < kChipAnimationDuration); } // namespace @@ -126,14 +120,6 @@ AnimateOut(); ResetSlideAnimation(false); } - - if (base::FeatureList::IsEnabled( - feature_engagement::kIPHHighEfficiencyInfoModeFeature)) { - // Delay the IPH to ensure the chip is not animating when it appears. - timer_.Start(FROM_HERE, kIPHDelayDuration, - base::BindOnce(&HighEfficiencyChipView::MaybeShowIPH, - weak_ptr_factory_.GetWeakPtr())); - } } else { AnimateOut(); ResetSlideAnimation(false); @@ -151,10 +137,6 @@ BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_); - // If the IPH is currently open, close it before opening the dialog. - browser_view->CloseFeaturePromo( - feature_engagement::kIPHHighEfficiencyInfoModeFeature); - // Open the dialog bubble. View* anchor_view = browser_view->toolbar_button_provider()->GetAnchorView( PageActionIconType::kHighEfficiency); @@ -175,26 +157,6 @@ return bubble_; } -void HighEfficiencyChipView::MaybeShowIPH() { - if (browser_->window() != nullptr) { - bool const promo_shown = browser_->window()->MaybeShowFeaturePromo( - feature_engagement::kIPHHighEfficiencyInfoModeFeature, {}, - base::BindOnce(&HighEfficiencyChipView::OnIPHClosed, - weak_ptr_factory_.GetWeakPtr())); - // While the IPH is showing, pause the animation of the chip so it doesn't - // animate closed. - if (promo_shown) { - PauseAnimation(); - SetHighlighted(true); - } - } -} - -void HighEfficiencyChipView::OnIPHClosed() { - SetHighlighted(false); - UnpauseAnimation(); -} - void HighEfficiencyChipView::OnHighEfficiencyModeChanged() { auto* manager = performance_manager::user_tuning:: UserPerformanceTuningManager::GetInstance();
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h index d849d92c..0b805f34 100644 --- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h +++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h
@@ -54,9 +54,6 @@ const gfx::VectorIcon& GetVectorIcon() const override; private: - void MaybeShowIPH(); - void OnIPHClosed(); - // performance_manager::user_tuning::UserPerformanceTuningManager::Observer: // Checks whether high efficiency mode is currently enabled. void OnHighEfficiencyModeChanged() override;
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc index aed3dbb..16014fbb 100644 --- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc +++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc
@@ -61,10 +61,10 @@ ~HighEfficiencyChipViewBrowserTest() override = default; void SetUp() override { - iph_features_.InitForDemo( - feature_engagement::kIPHHighEfficiencyInfoModeFeature, + scoped_feature_list_.InitWithFeaturesAndParameters( {{performance_manager::features::kHighEfficiencyModeAvailable, - {{"default_state", "true"}, {"time_before_discard", "1h"}}}}); + {{"default_state", "true"}, {"time_before_discard", "1h"}}}}, + {}); InProcessBrowserTest::SetUp(); } @@ -130,36 +130,6 @@ manager->DiscardPageForTesting(contents); } - void WaitForIPHToShow() { - views::NamedWidgetShownWaiter waiter( - views::test::AnyWidgetTestPasskey{}, - user_education::HelpBubbleView::kViewClassName); - waiter.WaitIfNeededAndGet(); - } - - user_education::HelpBubbleView* GetHelpBubbleView() { - return GetFeaturePromoController() - ->promo_bubble_for_testing() - ->AsA<user_education::HelpBubbleViews>() - ->bubble_view(); - } - - void ClickIPHCancelButton() { - views::test::WidgetDestroyedWaiter waiter(GetHelpBubbleView()->GetWidget()); - views::test::InteractionTestUtilSimulatorViews::PressButton( - GetHelpBubbleView()->GetDefaultButtonForTesting(), - ui::test::InteractionTestUtil::InputType::kMouse); - waiter.Wait(); - } - - void ClickIPHSettingsButton() { - views::test::WidgetDestroyedWaiter waiter(GetHelpBubbleView()->GetWidget()); - views::test::InteractionTestUtilSimulatorViews::PressButton( - GetHelpBubbleView()->GetNonDefaultButtonForTesting(0), - ui::test::InteractionTestUtil::InputType::kMouse); - waiter.Wait(); - } - views::InkDropState GetInkDropState() { return views::InkDrop::Get(GetHighEfficiencyChipView()) ->GetInkDrop() @@ -167,7 +137,7 @@ } private: - feature_engagement::test::ScopedIphFeatureList iph_features_; + base::test::ScopedFeatureList scoped_feature_list_; base::SimpleTestTickClock test_clock_; resource_coordinator::ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc index 8f7ffce..d2f8872 100644 --- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc +++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
@@ -47,8 +47,10 @@ return base_url.Resolve(chrome::kChromeUIPrivacySandboxDialogNoticePath); case PrivacySandboxService::PromptType::kM1NoticeEEA: return net::AppendQueryParameter(combined_dialog_url, "step", "notice"); - case PrivacySandboxService::PromptType::kNone: case PrivacySandboxService::PromptType::kM1NoticeRestricted: + return base_url.Resolve( + chrome::kChromeUIPrivacySandboxDialogNoticeRestrictedPath); + case PrivacySandboxService::PromptType::kNone: NOTREACHED_NORETURN(); } }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc index 49e613b0..8eccf03 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
@@ -67,7 +67,8 @@ ui::ColorId icon_color) { SetImageModel(views::Button::STATE_NORMAL, ui::ImageModel::FromVectorIcon(icon, icon_color, icon_size)); - views::InkDrop::Get(this)->SetBaseColor(icon_color); + DCHECK(views::InkDrop::Get(this)); + views::InkDrop::Get(this)->SetBaseColorId(icon_color); } void ReadAnythingMenuButton::SetDropdownColorIds(ui::ColorId background_color,
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index f4a5c3a..73eff72 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -318,6 +318,10 @@ bool BrowserTabStripController::BeforeCloseTab(int model_index, CloseTabSource source) { + if (!model_->IsTabClosable(model_index)) { + return false; + } + // Only consider pausing the close operation if this is the last remaining // tab (since otherwise closing it won't close the browser window). if (GetCount() > 1)
diff --git a/chrome/browser/ui/views/tabs/compound_tab_container.cc b/chrome/browser/ui/views/tabs/compound_tab_container.cc index 7bbd24e..143f29f 100644 --- a/chrome/browser/ui/views/tabs/compound_tab_container.cc +++ b/chrome/browser/ui/views/tabs/compound_tab_container.cc
@@ -692,8 +692,8 @@ gfx::Rect(pinned_tab_container_->GetPreferredSize())); // Unpinned container can have whatever is left over. - const int unpinned_container_leading_x = - std::max(0, pinned_tab_container_->width() - TabStyle::GetTabOverlap()); + const int unpinned_container_leading_x = std::max( + 0, pinned_tab_container_->width() - TabStyle::Get()->GetTabOverlap()); const int available_width = width() - unpinned_container_leading_x; const gfx::Size pref_size = unpinned_tab_container_->GetPreferredSize(); @@ -1006,7 +1006,7 @@ return NumPinnedTabs() > 0 ? pinned_tab_container_->GetIdealBounds(NumPinnedTabs() - 1) .right() - - TabStyle::GetTabOverlap() + TabStyle::Get()->GetTabOverlap() : 0; } @@ -1022,8 +1022,8 @@ gfx::Size largest_container = pinned_size; largest_container.SetToMax(unpinned_size); - const int width_with_overlap = - pinned_size.width() + unpinned_size.width() - TabStyle::GetTabOverlap(); + const int width_with_overlap = pinned_size.width() + unpinned_size.width() - + TabStyle::Get()->GetTabOverlap(); return gfx::Size(std::max(width_with_overlap, largest_container.width()), largest_container.height()); }
diff --git a/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc b/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc index d30fdb77..c63bede 100644 --- a/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc
@@ -389,7 +389,7 @@ AddTab(0, TabPinned::kUnpinned, absl::nullopt, TabActive::kActive); // Create just enough tabs so tabs are not full size. - const int standard_width = TabStyleViews::GetStandardWidth(); + const int standard_width = TabStyleViews::Create()->GetStandardWidth(); while (tab_container_->GetActiveTabWidth() == standard_width) { AddTab(0, TabPinned::kUnpinned); tab_container_->CompleteAnimationAndLayout(); @@ -425,7 +425,7 @@ AddTab(1, TabPinned::kUnpinned, absl::nullopt, TabActive::kInactive); // Create just enough (pinned) tabs so the active tab is not full size. - const int standard_width = TabStyleViews::GetStandardWidth(); + const int standard_width = TabStyleViews::Create()->GetStandardWidth(); while (tab_container_->GetActiveTabWidth() == standard_width) { AddTab(0, TabPinned::kPinned, absl::nullopt, TabActive::kInactive); tab_container_->CompleteAnimationAndLayout(); @@ -458,7 +458,7 @@ AddTab(1, TabPinned::kUnpinned, absl::nullopt, TabActive::kActive); // Create just enough (pinned) tabs so the active tab is not full size. - const int standard_width = TabStyleViews::GetStandardWidth(); + const int standard_width = TabStyleViews::Create()->GetStandardWidth(); while (tab_container_->GetActiveTabWidth() == standard_width) { AddTab(0, TabPinned::kPinned); tab_container_->CompleteAnimationAndLayout();
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 56a48b7..8972016a 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -661,7 +661,8 @@ } gfx::Size Tab::CalculatePreferredSize() const { - return gfx::Size(TabStyle::GetStandardWidth(), GetLayoutConstant(TAB_HEIGHT)); + return gfx::Size(tab_style()->GetStandardWidth(), + GetLayoutConstant(TAB_HEIGHT)); } void Tab::PaintChildren(const views::PaintInfo& info) { @@ -717,9 +718,9 @@ } TabSizeInfo Tab::GetTabSizeInfo() const { - return {TabStyle::GetPinnedWidth(), TabStyleViews::GetMinimumActiveWidth(), - TabStyleViews::GetMinimumInactiveWidth(), - TabStyle::GetStandardWidth()}; + return {tab_style()->GetPinnedWidth(), tab_style()->GetMinimumActiveWidth(), + tab_style()->GetMinimumInactiveWidth(), + tab_style()->GetStandardWidth()}; } void Tab::SetClosing(bool closing) { @@ -913,7 +914,7 @@ int visual_width) const { if (ShouldRenderAsNormalTab()) return; - const int pinned_width = TabStyle::GetPinnedWidth(); + const int pinned_width = tab_style()->GetPinnedWidth(); const int ideal_delta = width() - pinned_width; const int ideal_x = (pinned_width - visual_width) / 2; // TODO(crbug.com/533570): This code is broken when the current width is less @@ -1040,7 +1041,7 @@ } bool Tab::ShouldRenderAsNormalTab() const { - return !data().pinned || (width() >= (TabStyle::GetPinnedWidth() + + return !data().pinned || (width() >= (tab_style()->GetPinnedWidth() + kPinnedTabExtraWidthToRenderAsNormal)); } @@ -1076,7 +1077,7 @@ // There may be no focus ring when the tab is closing. if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) { focus_ring->SetColorId(colors.focus_ring_color); - focus_ring->SetOutsetFocusRingDisabled(); + focus_ring->SetOutsetFocusRingDisabled(true); } SchedulePaint(); }
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.cc b/chrome/browser/ui/views/tabs/tab_container_impl.cc index a42203c..5089bc1 100644 --- a/chrome/browser/ui/views/tabs/tab_container_impl.cc +++ b/chrome/browser/ui/views/tabs/tab_container_impl.cc
@@ -528,7 +528,7 @@ // drag handle, to increase draggability. This region starts 1 DIP above // the top of the separator. const int drag_handle_extension = - TabStyle::GetDragHandleExtension(height()); + TabStyle::Get()->GetDragHandleExtension(height()); // A hit on an inactive tab is in the content area unless it is in the thin // strip mentioned above. @@ -705,7 +705,7 @@ const bool is_collapsed = (current_group.has_value() && controller_->IsGroupCollapsed(current_group.value()) && - tab->bounds().width() <= TabStyle::GetTabOverlap()); + tab->bounds().width() <= tab->tab_style()->GetTabOverlap()); const bool should_be_visible = is_collapsed ? false : last_tab_visible; // If we change the visibility of a tab in a group, we must recalculate that @@ -1118,7 +1118,7 @@ bounds.set_height(GetLayoutConstant(TAB_HEIGHT)); // Adjust the starting bounds of the new tab. - const int tab_overlap = TabStyle::GetTabOverlap(); + const int tab_overlap = TabStyle::Get()->GetTabOverlap(); if (model_index > 0) { // If we have a tab to our left, start at its right edge. bounds.set_x(GetTabAtModelIndex(model_index - 1)->bounds().right() - @@ -1190,7 +1190,7 @@ gfx::Rect TabContainerImpl::GetTargetBoundsForClosingTab( Tab* tab, int former_model_index) const { - const int tab_overlap = TabStyle::GetTabOverlap(); + const int tab_overlap = TabStyle::Get()->GetTabOverlap(); // Compute the target bounds for animating this tab closed. The tab's left // edge should stay joined to the right edge of the previous tab, if any. @@ -1309,7 +1309,7 @@ override_available_width_for_tabs_ = tabs_view_model_.ideal_bounds(model_count).right() - size_delta + - TabStyle::GetTabOverlap(); + TabStyle::Get()->GetTabOverlap(); } void TabContainerImpl::ResizeLayoutTabs() { @@ -1535,7 +1535,7 @@ GetModelIndexOf(tab) == controller_->GetFirstTabInGroup(tab->group().value()); - const int overlap = TabStyle::GetTabOverlap(); + const int overlap = tab->tab_style()->GetTabOverlap(); if (!drop_before || !first_in_group || drop_in_group) { // Dropping between tabs, or between a group header and the group's first // tab.
diff --git a/chrome/browser/ui/views/tabs/tab_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_container_unittest.cc index 089724c3..0727bea 100644 --- a/chrome/browser/ui/views/tabs/tab_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_container_unittest.cc
@@ -358,7 +358,7 @@ AddTab(0, absl::nullopt, TabActive::kActive); // Create just enough tabs so tabs are not full size. - const int standard_width = TabStyleViews::GetStandardWidth(); + const int standard_width = TabStyle::Get()->GetStandardWidth(); while (tab_container_->GetActiveTabWidth() == standard_width) { AddTab(0); tab_container_->CompleteAnimationAndLayout(); @@ -392,7 +392,7 @@ AddTab(0, absl::nullopt, TabActive::kActive); // Create enough tabs so tabs are not full size. - const int standard_width = TabStyleViews::GetStandardWidth(); + const int standard_width = TabStyle::Get()->GetStandardWidth(); // Set a tab_counter to avoid infinite loop int tab_counter = 0; @@ -694,7 +694,8 @@ TabGroupHeader* header = views[0]->header(); EXPECT_EQ(first_slot_x, header->x()); EXPECT_GT(header->width(), 0); - EXPECT_EQ(header->bounds().right() - TabStyle::GetTabOverlap(), tab->x()); + EXPECT_EQ(header->bounds().right() - TabStyle::Get()->GetTabOverlap(), + tab->x()); EXPECT_EQ(tab->height(), header->height()); }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index afe0351..c380617 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -2483,7 +2483,7 @@ // space for the rounded feet. Adding {tab_left_inset} to the horizontal // bounds of the tab results in the x position that would be drawn when there // are no feet showing. - const int tab_left_inset = TabStyle::GetTabOverlap() / 2; + const int tab_left_inset = TabStyle::Get()->GetTabOverlap() / 2; const auto tab_bounds_in_drag_context_coords = [this](int model_index) { const Tab* const tab = attached_context_->GetTabAt(model_index);
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 2259d1a7..4d8ab29a 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -2777,21 +2777,23 @@ AddTabsAndResetBrowser(browser(), 1); + const TabStyle* tab_style = TabStyle::Get(); // We must ensure that we set the bounds of the browser window such that it is // wide enough to allow the tab strip to expand to accommodate this tab. browser()->window()->SetBounds( - gfx::Rect(0, 0, TabStyle::GetStandardWidth() * 5, 400)); + gfx::Rect(0, 0, tab_style->GetStandardWidth() * 5, 400)); const int tab_strip_width = tab_strip->width(); const gfx::Point tab_1_center = GetCenterInScreenCoordinates(tab_strip->tab_at(1)); ASSERT_TRUE(PressInput(tab_1_center)); ASSERT_TRUE(DragInputTo(tab_1_center + - gfx::Vector2d(TabStyle::GetStandardWidth(), 0))); + gfx::Vector2d(tab_style->GetStandardWidth(), 0))); BrowserView::GetBrowserViewForBrowser(browser()) ->GetWidget() ->LayoutRootViewIfNecessary(); - EXPECT_EQ(tab_strip_width + TabStyle::GetStandardWidth(), tab_strip->width()); + EXPECT_EQ(tab_strip_width + tab_style->GetStandardWidth(), + tab_strip->width()); ASSERT_TRUE(ReleaseInput()); }
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc index 5eb517f..515c47c6 100644 --- a/chrome/browser/ui/views/tabs/tab_group_header.cc +++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -108,7 +108,8 @@ ? SavedTabGroupServiceFactory::GetForProfile( tab_slot_controller_->GetBrowser()->profile()) : nullptr), - style_(style), + group_style_(style), + tab_style_(TabStyle::Get()), editor_bubble_tracker_(tab_slot_controller) { set_group(group); set_context_menu_controller(this); @@ -131,8 +132,8 @@ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); views::FocusRing::Install(this); views::HighlightPathGenerator::Install( - this, std::make_unique<TabGroupHighlightPathGenerator>(title_chip_, - title_, *style_)); + this, std::make_unique<TabGroupHighlightPathGenerator>( + title_chip_, title_, *group_style_)); // The tab group gets painted with a solid color that may not contrast well // with the focus indicator, so draw an outline around the focus ring for it // to contrast with the solid color. @@ -390,7 +391,7 @@ // The distance from the endge of the view to the tab separator is half of the // overlap distance. We should only accept events between the separators. gfx::Rect contents_rect = GetLocalBounds(); - contents_rect.Inset(gfx::Insets::VH(0, TabStyle::GetTabOverlap() / 2)); + contents_rect.Inset(gfx::Insets::VH(0, tab_style_->GetTabOverlap() / 2)); return contents_rect.Intersects(rect); } @@ -408,7 +409,7 @@ // during layout however; that would cause an the margin to be visually uneven // when the header is in the first slot and thus wouldn't overlap anything to // the left. - const int overlap_margin = TabStyle::GetTabOverlap() * 2; + const int overlap_margin = tab_style_->GetTabOverlap() * 2; // The empty and non-empty chips have different sizes and corner radii, but // both should look nestled against the group stroke of the tab to the right. @@ -419,7 +420,7 @@ const std::u16string title = tab_slot_controller_->GetGroupTitle(group().value()); const int right_adjust = - style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title); + group_style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title); return overlap_margin + title_chip_->width() + right_adjust; } @@ -437,20 +438,21 @@ if (ShouldShowSyncIcon()) { sync_icon_->SetImage(ui::ImageModel::FromVectorIcon( kTabGroupsSyncIcon, color_utils::GetColorWithMaxContrast(color), - style_->GetSyncIconWidth())); + group_style_->GetSyncIconWidth())); } sync_icon_->SetVisible(ShouldShowSyncIcon()); if (title.empty()) { - title_chip_->SetBoundsRect(style_->GetEmptyTitleChipBounds(this)); - title_chip_->SetBackground(style_->GetEmptyTitleChipBackground(color)); + title_chip_->SetBoundsRect(group_style_->GetEmptyTitleChipBounds(this)); + title_chip_->SetBackground( + group_style_->GetEmptyTitleChipBackground(color)); if (ShouldShowSyncIcon()) { // The `sync_icon` should be centered in the title chip. gfx::Rect sync_icon_bounds = title_chip_->GetLocalBounds(); - sync_icon_bounds.ClampToCenteredSize( - gfx::Size(style_->GetSyncIconWidth(), style_->GetSyncIconWidth())); + sync_icon_bounds.ClampToCenteredSize(gfx::Size( + group_style_->GetSyncIconWidth(), group_style_->GetSyncIconWidth())); sync_icon_->SetBoundsRect(sync_icon_bounds); } else { sync_icon_->SetBounds(0, 0, 0, 0); @@ -471,7 +473,7 @@ const gfx::Size sync_icon_size = ShouldShowSyncIcon() - ? gfx::Size(style_->GetSyncIconWidth(), text_height) + ? gfx::Size(group_style_->GetSyncIconWidth(), text_height) : gfx::Size(); const int padding_between_label_sync_icon = @@ -480,7 +482,7 @@ // The max width of the content should be half the standard tab width (not // counting overlap). const int text_max_width = - (TabStyle::GetStandardWidth() - TabStyle::GetTabOverlap()) / 2 - + (tab_style_->GetStandardWidth() - tab_style_->GetTabOverlap()) / 2 - sync_icon_size.width() - padding_between_label_sync_icon; const int text_width = @@ -492,13 +494,14 @@ text_width + sync_icon_size.width() + padding_between_label_sync_icon; // horizontal and vertical insets of the title chip. - const gfx::Insets title_chip_insets = style_->GetInsetsForHeaderChip(); + const gfx::Insets title_chip_insets = + group_style_->GetInsetsForHeaderChip(); const int title_chip_vertical_inset = title_chip_insets.top(); const int title_chip_horizontal_inset = title_chip_insets.left(); // Width of title chip should atleast be the width of an empty title chip. const int title_chip_width = - std::max(style_->GetEmptyTitleChipBounds(this).width(), + std::max(group_style_->GetEmptyTitleChipBounds(this).width(), content_width + 2 * title_chip_horizontal_inset); // The bounds and background for the `title_chip_` is set here. @@ -541,9 +544,11 @@ int TabGroupHeader::GetCollapsedHeaderWidth() const { const int title_adjustment = - style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title_->GetText()); + group_style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth( + title_->GetText()); const int title_chip_width = GetTabSizeInfo().standard_width - - 2 * TabStyle::GetTabOverlap() - title_adjustment; + 2 * tab_style_->GetTabOverlap() - + title_adjustment; return title_chip_width + 2 * TabGroupUnderline::GetStrokeInset(); }
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.h b/chrome/browser/ui/views/tabs/tab_group_header.h index 7a274d8..c3fb780 100644 --- a/chrome/browser/ui/views/tabs/tab_group_header.h +++ b/chrome/browser/ui/views/tabs/tab_group_header.h
@@ -20,6 +20,7 @@ class TabSlotController; class TabGroupStyle; struct TabSizeInfo; +class TabStyle; namespace views { class ImageView; @@ -102,7 +103,8 @@ // Used to verify if this tab group is saved. const raw_ptr<SavedTabGroupKeyedService> saved_tab_group_service_; - const raw_ref<const TabGroupStyle> style_; + const raw_ref<const TabGroupStyle> group_style_; + const raw_ptr<const TabStyle> tab_style_; // Saved collapsed state for usage with activation of element tracker system. bool is_collapsed_;
diff --git a/chrome/browser/ui/views/tabs/tab_group_highlight.cc b/chrome/browser/ui/views/tabs/tab_group_highlight.cc index 5e899daf..2a05578 100644 --- a/chrome/browser/ui/views/tabs/tab_group_highlight.cc +++ b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
@@ -59,7 +59,7 @@ // which is a well-scoped interaction. A dragging group doesn't nestle in with // the tabs around it, so there are no special cases needed when determining // its shape. - const int corner_radius = TabStyle::GetCornerRadius(); + const int corner_radius = TabStyle::Get()->GetCornerRadius(); SkPath path; path.moveTo(0, bounds().height());
diff --git a/chrome/browser/ui/views/tabs/tab_group_style.cc b/chrome/browser/ui/views/tabs/tab_group_style.cc index 2ed2e79..67d899c6 100644 --- a/chrome/browser/ui/views/tabs/tab_group_style.cc +++ b/chrome/browser/ui/views/tabs/tab_group_style.cc
@@ -107,12 +107,13 @@ } float TabGroupStyle::GetSelectedTabOpacity() const { - return TabStyle::kDefaultSelectedTabOpacity; + return TabStyle::Get()->GetSelectedTabOpacity(); } // static int TabGroupStyle::GetChipCornerRadius() { - return TabStyle::GetCornerRadius() - TabGroupUnderline::kStrokeThickness; + return TabStyle::Get()->GetCornerRadius() - + TabGroupUnderline::kStrokeThickness; } ChromeRefresh2023TabGroupStyle::ChromeRefresh2023TabGroupStyle(
diff --git a/chrome/browser/ui/views/tabs/tab_group_underline.cc b/chrome/browser/ui/views/tabs/tab_group_underline.cc index 9ed2faf..d1b5a55 100644 --- a/chrome/browser/ui/views/tabs/tab_group_underline.cc +++ b/chrome/browser/ui/views/tabs/tab_group_underline.cc
@@ -119,7 +119,7 @@ // static int TabGroupUnderline::GetStrokeInset() { - return TabStyle::GetTabOverlap() + kStrokeThickness; + return TabStyle::Get()->GetTabOverlap() + kStrokeThickness; } BEGIN_METADATA(TabGroupUnderline, views::View)
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index a0fc180..7e0dc17 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h" +#include "chrome/browser/ui/views/tabs/tab_style_views.h" #include "chrome/grit/generated_resources.h" #include "components/url_formatter/url_formatter.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -621,8 +622,8 @@ break; case ImageType::kThumbnail: image_view->SetVerticalAlignment(views::ImageView::Alignment::kLeading); - image_view->SetImageSize( - GetPreviewImageSize(image.size(), TabStyle::GetPreviewImageSize())); + image_view->SetImageSize(GetPreviewImageSize( + image.size(), bubble_view_->tab_style_->GetPreviewImageSize())); image_view->SetBackground(nullptr); break; } @@ -632,12 +633,13 @@ gfx::Size GetMinimumSize() const override { return gfx::Size(); } gfx::Size CalculatePreferredSize() const override { - return image_type_ == ImageType::kNone ? gfx::Size() - : TabStyle::GetPreviewImageSize(); + return image_type_ == ImageType::kNone + ? gfx::Size() + : bubble_view_->tab_style_->GetPreviewImageSize(); } gfx::Size GetMaximumSize() const override { - return TabStyle::GetPreviewImageSize(); + return bubble_view_->tab_style_->GetPreviewImageSize(); } // views::AnimationDelegateViews: @@ -733,7 +735,8 @@ TabHoverCardBubbleView::TabHoverCardBubbleView(Tab* tab) : BubbleDialogDelegateView(tab, views::BubbleBorder::TOP_LEFT, - views::BubbleBorder::STANDARD_SHADOW) { + views::BubbleBorder::STANDARD_SHADOW), + tab_style_(TabStyle::Get()) { SetButtons(ui::DIALOG_BUTTON_NONE); // Remove the accessible role so that hover cards are not read when they @@ -988,7 +991,7 @@ gfx::Size TabHoverCardBubbleView::CalculatePreferredSize() const { gfx::Size preferred_size = GetLayoutManager()->GetPreferredSize(this); - preferred_size.set_width(TabStyle::GetPreviewImageSize().width()); + preferred_size.set_width(tab_style_->GetPreviewImageSize().width()); DCHECK(!preferred_size.IsEmpty()); return preferred_size; }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index c8c69f1..36e4106 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -34,6 +34,7 @@ } class Tab; +class TabStyle; // Dialog that displays an informational hover card containing page information. class TabHoverCardBubbleView : public views::BubbleDialogDelegateView { @@ -150,6 +151,7 @@ raw_ptr<FadeLabel> domain_label_ = nullptr; raw_ptr<ThumbnailView> thumbnail_view_ = nullptr; absl::optional<TabAlertState> alert_state_; + const raw_ptr<const TabStyle> tab_style_; int corner_radius_ = ChromeLayoutProvider::Get()->GetCornerRadiusMetric( views::Emphasis::kHigh);
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc index 9e8ec80..77f4beae 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -149,7 +149,9 @@ } base::TimeDelta GetShowDelay(int tab_width) { - static const int max_width_additiona_delay = + const TabStyle* tab_style = TabStyle::Get(); + + static const int max_width_additional_delay = base::GetFieldTrialParamByFeatureAsInt( features::kTabHoverCardImages, features::kTabHoverCardAdditionalMaxWidthDelay, 500); @@ -173,17 +175,19 @@ // | | // pinned tab width standard tab width constexpr base::TimeDelta kMinimumTriggerDelay = base::Milliseconds(300); - if (tab_width < TabStyle::GetPinnedWidth()) + if (tab_width < tab_style->GetPinnedWidth()) { return kMinimumTriggerDelay; + } constexpr base::TimeDelta kMaximumTriggerDelay = base::Milliseconds(800); double logarithmic_fraction = - std::log(tab_width - TabStyle::GetPinnedWidth() + 1) / - std::log(TabStyle::GetStandardWidth() - TabStyle::GetPinnedWidth() + 1); + std::log(tab_width - tab_style->GetPinnedWidth() + 1) / + std::log(tab_style->GetStandardWidth() - tab_style->GetPinnedWidth() + 1); base::TimeDelta scaling_factor = kMaximumTriggerDelay - kMinimumTriggerDelay; base::TimeDelta delay = logarithmic_fraction * scaling_factor + kMinimumTriggerDelay; - if (tab_width >= TabStyle::GetStandardWidth()) - delay += base::Milliseconds(max_width_additiona_delay); + if (tab_width >= tab_style->GetStandardWidth()) { + delay += base::Milliseconds(max_width_additional_delay); + } return delay; }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc b/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc index c822ce8..40e44f49d 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc
@@ -18,7 +18,7 @@ return; subscription_ = current_image_->Subscribe(); - subscription_->SetSizeHint(TabStyle::GetPreviewImageSize()); + subscription_->SetSizeHint(TabStyle::Get()->GetPreviewImageSize()); subscription_->SetUncompressedImageCallback(base::BindRepeating( &TabHoverCardThumbnailObserver::ThumbnailImageCallback, base::Unretained(this), base::Unretained(current_image_.get())));
diff --git a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc index f8e0976..a9cc827 100644 --- a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc +++ b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc
@@ -62,7 +62,8 @@ // opposite edges of the tab, which should be at (overlap / 2). gfx::Rect tab_edges = tab_bounds; // For odd overlap values, be conservative and inset both edges rounding up. - tab_edges.Inset(gfx::Insets::VH(0, (TabStyle::GetTabOverlap() + 1) / 2)); + tab_edges.Inset( + gfx::Insets::VH(0, (tab->tab_style()->GetTabOverlap() + 1) / 2)); const int x = (direction == LEFT) ? std::min(tab_bounds.x() + left, tab_edges.right()) : std::max(tab_bounds.right() - right, tab_edges.x()); @@ -91,7 +92,7 @@ ui::EventTimeForNow(), /*flags=*/0, x_offset, /*y_offset=*/0.f, /*x_offset_ordinal=*/0.f, - /*y_offset_original=*/0.f, kFingerCount); + /*y_offset_ordinal=*/0.f, kFingerCount); OnScrollEvent(&event); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index cd8c664..27328ed 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -66,7 +66,6 @@ #include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" #include "chrome/browser/ui/views/tabs/tab_strip_types.h" -#include "chrome/browser/ui/views/tabs/tab_style_views.h" #include "chrome/browser/ui/views/tabs/z_orderable_tab_container_element.h" #include "chrome/browser/ui/views/touch_uma/touch_uma.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" @@ -452,7 +451,7 @@ constexpr int kHorizontalMoveThreshold = 16; // DIPs. double ratio = static_cast<double>(tab_strip_->GetInactiveTabWidth()) / - TabStyle::GetStandardWidth(); + TabStyle::Get()->GetStandardWidth(); return base::ClampRound(ratio * kHorizontalMoveThreshold); } @@ -491,7 +490,7 @@ DCHECK(!views.empty()); std::vector<gfx::Rect> bounds; - const int overlap = TabStyle::GetTabOverlap(); + const int overlap = TabStyle::Get()->GetTabOverlap(); int x = 0; for (const TabSlotView* view : views) { const int width = view->width(); @@ -834,7 +833,7 @@ if (candidate_index == 0) return 0; - const int tab_overlap = TabStyle::GetTabOverlap(); + const int tab_overlap = TabStyle::Get()->GetTabOverlap(); // We'll insert just right of the tab at |candidate_index| - 1. int ideal_x = @@ -873,7 +872,7 @@ return 0; const int header_width = GetTabGroupHeader(*right_group)->bounds().width() - - TabStyle::GetTabOverlap(); + TabStyle::Get()->GetTabOverlap(); return header_width; } } @@ -910,7 +909,8 @@ *AddChildViewAt(MakeTabContainer(this, hover_card_controller_.get(), base::to_address(drag_context_)), - 0)) { + 0)), + style_(TabStyle::Get()) { // TODO(pbos): This is probably incorrect, the background of individual tabs // depend on their selected state. This should probably be pushed down into // tabs. @@ -954,7 +954,7 @@ for (const TabSlotView* view : views) width += view->width(); if (!views.empty()) - width -= TabStyle::GetTabOverlap() * (views.size() - 1); + width -= TabStyle::Get()->GetTabOverlap() * (views.size() - 1); return width; }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index bae5dee..683accf 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -44,6 +44,7 @@ class TabHoverCardController; class TabStripController; class TabStripObserver; +class TabStyle; namespace gfx { class Rect; @@ -441,6 +442,8 @@ // Used for seek time metrics from the time the mouse enters the tabstrip. absl::optional<base::TimeTicks> mouse_entered_tabstrip_time_; + const raw_ptr<const TabStyle> style_; + // Number of mouse moves. int mouse_move_count_ = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc index a2c0979..58fae26 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
@@ -33,7 +33,7 @@ }; TabLayoutConstants GetTabLayoutConstants() { - return {GetLayoutConstant(TAB_HEIGHT), TabStyle::GetTabOverlap()}; + return {GetLayoutConstant(TAB_HEIGHT), TabStyle::Get()->GetTabOverlap()}; } } // namespace @@ -70,8 +70,8 @@ GetTabsCallback get_tabs_callback) : controller_(controller), get_tabs_callback_(get_tabs_callback), - active_tab_width_(TabStyle::GetStandardWidth()), - inactive_tab_width_(TabStyle::GetStandardWidth()) {} + active_tab_width_(TabStyle::Get()->GetStandardWidth()), + inactive_tab_width_(TabStyle::Get()->GetStandardWidth()) {} TabStripLayoutHelper::~TabStripLayoutHelper() = default;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc b/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc index 86c0b625..b462e26 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc
@@ -115,7 +115,7 @@ double TabStripScrollSessionWithTimer::CalculateBaseScrollOffset() { return kNumberOfTabsScrolledPerSecond * - TabStyleViews::GetMinimumInactiveWidth() * + TabStyleViews::Create()->GetMinimumInactiveWidth() * (kScrollTimerDelay / base::Milliseconds(1000)); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc index 63834378..944ef53 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc
@@ -76,13 +76,13 @@ scroll_session_->SetTimerForTesting(mock_timer_); scroll_view_ = std::make_unique<views::ScrollView>(); - scroll_view_->SetBounds(0, 0, 5 * TabStyleViews::GetMinimumInactiveWidth(), - 5); + scroll_view_->SetBounds( + 0, 0, 5 * TabStyleViews::Create()->GetMinimumInactiveWidth(), 5); attached_context_ = scroll_view_->SetContents(std::make_unique<views::View>()); attached_context_->SetBounds( - 0, 0, 10 * TabStyleViews::GetMinimumInactiveWidth(), 5); + 0, 0, 10 * TabStyleViews::Create()->GetMinimumInactiveWidth(), 5); } void TearDown() override { ChromeViewsTestBase::TearDown(); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc index e41299b1..a02d5172 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
@@ -208,7 +208,7 @@ views::OverflowIndicatorAlignment::kRight); right_overflow_indicator_ = right_overflow_indicator.get(); - const int min_tab_width = TabStyleViews::GetMinimumInactiveWidth(); + const int min_tab_width = TabStyleViews::Create()->GetMinimumInactiveWidth(); left_overflow_indicator_->SetShadowBlurWidth(std::min(64, min_tab_width * 2)); right_overflow_indicator_->SetShadowBlurWidth(
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc index c119117..412e6f3 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -408,7 +408,7 @@ controller_->AddTab(1, TabActive::kActive); controller_->AddTab(2, TabActive::kInactive); - const int standard_width = TabStyle::GetStandardWidth(); + const int standard_width = TabStyle::Get()->GetStandardWidth(); SetMaxTabStripWidth(1000); @@ -422,8 +422,10 @@ SetMaxTabStripWidth(50); - EXPECT_EQ(TabStyleViews::GetMinimumActiveWidth(), GetActiveTabWidth()); - EXPECT_EQ(TabStyleViews::GetMinimumInactiveWidth(), GetInactiveTabWidth()); + EXPECT_EQ(TabStyleViews::Create()->GetMinimumActiveWidth(), + GetActiveTabWidth()); + EXPECT_EQ(TabStyleViews::Create()->GetMinimumInactiveWidth(), + GetInactiveTabWidth()); } // The active tab should always be at least as wide as its minimum width. @@ -435,7 +437,8 @@ SetMaxTabStripWidth(400); // Create a lot of tabs in order to make inactive tabs tiny. - const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth(); + const int min_inactive_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); while (GetInactiveTabWidth() != min_inactive_width) { controller_->CreateNewTab(); CompleteAnimationAndLayout(); @@ -454,7 +457,7 @@ while (tab_strip_->GetTabCount() > 0) { active_index = tab_strip_->GetActiveIndex().value(); EXPECT_GE(tab_strip_->tab_at(active_index)->bounds().width(), - TabStyleViews::GetMinimumActiveWidth()); + TabStyleViews::Create()->GetMinimumActiveWidth()); tab_strip_->CloseTab(tab_strip_->tab_at(active_index), CLOSE_TAB_FROM_MOUSE); CompleteAnimationAndLayout(); @@ -468,8 +471,9 @@ // Create a lot of tabs in order to make inactive tabs smaller than active // tab but not the minimum. - const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth(); - const int min_active_width = TabStyleViews::GetMinimumActiveWidth(); + const int min_inactive_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); + const int min_active_width = TabStyleViews::Create()->GetMinimumActiveWidth(); while (GetInactiveTabWidth() >= (min_inactive_width + min_active_width) / 2) { controller_->CreateNewTab(); CompleteAnimationAndLayout(); @@ -497,13 +501,14 @@ SetMaxTabStripWidth(200); // Create a lot of tabs in order to make inactive tabs tiny. - const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth(); + const int min_inactive_width = + TabStyleViews::Create()->GetMinimumInactiveWidth(); while (GetInactiveTabWidth() != min_inactive_width) { controller_->CreateNewTab(); CompleteAnimationAndLayout(); } - const int min_active_width = TabStyleViews::GetMinimumActiveWidth(); + const int min_active_width = TabStyleViews::Create()->GetMinimumActiveWidth(); int dragged_tab_index = tab_strip_->GetActiveIndex().value(); ASSERT_GE(tab_strip_->tab_at(dragged_tab_index)->bounds().width(),
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 221f622..0dabeae 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -86,21 +86,20 @@ protected: // TabStyle: - SkPath GetPath( - PathType path_type, - float scale, - bool force_active = false, - RenderUnits render_units = RenderUnits::kPixels) const override; + SkPath GetPath(TabStyle::PathType path_type, + float scale, + bool force_active = false, + TabStyle::RenderUnits render_units = + TabStyle::RenderUnits::kPixels) const override; gfx::Insets GetContentsInsets() const override; float GetZValue() const override; float GetActiveOpacity() const override; TabActive GetApparentActiveState() const override; TabStyle::TabColors CalculateColors() const override; - float GetSelectedTabOpacity() const override; void PaintTab(gfx::Canvas* canvas) const override; void SetHoverLocation(const gfx::Point& location) override; - void ShowHover(ShowHoverStyle style) override; - void HideHover(HideHoverStyle style) override; + void ShowHover(TabStyle::ShowHoverStyle style) override; + void HideHover(TabStyle::HideHoverStyle style) override; // Painting helper functions: virtual SkColor GetTabBackgroundColor(TabActive active) const; @@ -113,12 +112,12 @@ private: // Gets the bounds for the leading and trailing separators for a tab. - SeparatorBounds GetSeparatorBounds(float scale) const; + TabStyle::SeparatorBounds GetSeparatorBounds(float scale) const; // Returns the opacities of the separators. If |for_layout| is true, returns // the "layout" opacities, which ignore the effects of surrounding tabs' hover // effects and consider only the current tab's state. - SeparatorOpacities GetSeparatorOpacities(bool for_layout) const; + TabStyle::SeparatorOpacities GetSeparatorOpacities(bool for_layout) const; // Returns a single separator's opacity based on whether it is the // logically |leading| separator. |for_layout| has the same meaning as in @@ -155,7 +154,7 @@ // there are anti-aliasing artifacts in the overlapped lower arc region. This // returns how to modify the tab shape to eliminate the lower arcs on the // right or left based on the state of the adjacent tab(s). - ShapeModifier GetShapeModifier(PathType path_type) const; + ShapeModifier GetShapeModifier(TabStyle::PathType path_type) const; // Painting helper functions: void PaintInactiveTabBackground(gfx::Canvas* canvas) const; @@ -174,13 +173,13 @@ void PaintSeparators(gfx::Canvas* canvas) const; // Given a tab of width |width|, returns the radius to use for the corners. - static float GetTopCornerRadiusForWidth(int width); + float GetTopCornerRadiusForWidth(int width) const; // Scales |bounds| by scale and aligns so that adjacent tabs meet up exactly // during painting. - static gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, - float scale, - int stroke_thickness); + gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, + float scale, + int stroke_thickness) const; const raw_ptr<const Tab> tab_; @@ -198,10 +197,10 @@ // repurposing CONTEXT_BUTTON_MD. } -SkPath GM2TabStyle::GetPath(PathType path_type, +SkPath GM2TabStyle::GetPath(TabStyle::PathType path_type, float scale, bool force_active, - RenderUnits render_units) const { + TabStyle::RenderUnits render_units) const { CHECK(tab()); const int stroke_thickness = GetStrokeThickness(force_active); @@ -211,7 +210,7 @@ gfx::RectF aligned_bounds = ScaleAndAlignBounds(tab_->bounds(), scale, stroke_thickness); - if (path_type == PathType::kInteriorClip) { + if (path_type == TabStyle::PathType::kInteriorClip) { // When there is a separator, animate the clip to account for it, in sync // with the separator's fading. // TODO(pkasting): Consider crossfading the favicon instead of animating @@ -250,20 +249,21 @@ // Path-specific adjustments: const float stroke_adjustment = stroke_thickness * scale; bool extend_to_top = false; - if (path_type == PathType::kInteriorClip) { + if (path_type == TabStyle::PathType::kInteriorClip) { // Inside of the border runs |stroke_thickness| inside the outer edge. tab_left += stroke_adjustment; tab_right -= stroke_adjustment; tab_top += stroke_adjustment; top_radius -= stroke_adjustment; - } else if (path_type == PathType::kFill || path_type == PathType::kBorder) { + } else if (path_type == TabStyle::PathType::kFill || + path_type == TabStyle::PathType::kBorder) { tab_left += 0.5f * stroke_adjustment; tab_right -= 0.5f * stroke_adjustment; tab_top += 0.5f * stroke_adjustment; top_radius -= 0.5f * stroke_adjustment; tab_bottom -= 0.5f * stroke_adjustment; bottom_radius -= 0.5f * stroke_adjustment; - } else if (path_type == PathType::kHitTest) { + } else if (path_type == TabStyle::PathType::kHitTest) { // Outside border needs to draw its bottom line a stroke width above the // bottom of the tab, to line up with the stroke that runs across the rest // of the bottom of the tab bar (when strokes are enabled). @@ -287,10 +287,10 @@ SkPath path; - if (path_type == PathType::kInteriorClip) { + if (path_type == TabStyle::PathType::kInteriorClip) { // Clip path is a simple rectangle. path.addRect(tab_left, tab_top, tab_right, tab_bottom); - } else if (path_type == PathType::kHighlight) { + } else if (path_type == TabStyle::PathType::kHighlight) { // The path is a round rect inset by the focus ring thickness. The // radius is also adjusted by the inset. const float inset = views::FocusRing::kDefaultHaloThickness + @@ -392,8 +392,9 @@ // ┌─╯ ╰─┓ path.lineTo(right, extended_bottom); - if (path_type != PathType::kBorder) + if (path_type != TabStyle::PathType::kBorder) { path.close(); + } } // Convert path to be relative to the tab origin. @@ -402,8 +403,9 @@ path.offset(-origin.x(), -origin.y()); // Possibly convert back to DIPs. - if (render_units == RenderUnits::kDips && scale != 1.0f) + if (render_units == TabStyle::RenderUnits::kDips && scale != 1.0f) { path.transform(SkMatrix::Scale(1.0f / scale, 1.0f / scale)); + } return path; } @@ -489,10 +491,6 @@ close_button_focus_ring_color}; } -float GM2TabStyle::GetSelectedTabOpacity() const { - return kDefaultSelectedTabOpacity; -} - void GM2TabStyle::PaintTab(gfx::Canvas* canvas) const { CHECK(tab()); absl::optional<int> active_tab_fill_id; @@ -528,19 +526,19 @@ hover_controller_->SetLocation(location); } -void GM2TabStyle::ShowHover(ShowHoverStyle style) { +void GM2TabStyle::ShowHover(TabStyle::ShowHoverStyle style) { CHECK(tab()); if (!hover_controller_) return; - if (style == ShowHoverStyle::kSubtle) { + if (style == TabStyle::ShowHoverStyle::kSubtle) { hover_controller_->SetSubtleOpacityScale( tab_->controller()->GetHoverOpacityForRadialHighlight()); } hover_controller_->Show(style); } -void GM2TabStyle::HideHover(HideHoverStyle style) { +void GM2TabStyle::HideHover(TabStyle::HideHoverStyle style) { CHECK(tab()); if (hover_controller_) hover_controller_->Hide(style); @@ -554,7 +552,7 @@ gfx::SizeF separator_size(GetSeparatorSize()); separator_size.Scale(scale); - SeparatorBounds separator_bounds; + TabStyle::SeparatorBounds separator_bounds; separator_bounds.leading = gfx::RectF(aligned_bounds.x() + corner_radius, @@ -787,11 +785,12 @@ return color; } -ShapeModifier GM2TabStyle::GetShapeModifier(PathType path_type) const { +ShapeModifier GM2TabStyle::GetShapeModifier( + TabStyle::PathType path_type) const { CHECK(tab()); ShapeModifier shape_modifier = kNone; - if (path_type == PathType::kFill && tab_->IsSelected() && !IsHoverActive() && - !tab_->IsActive()) { + if (path_type == TabStyle::PathType::kFill && tab_->IsSelected() && + !IsHoverActive() && !tab_->IsActive()) { auto check_adjacent_tab = [](const Tab* tab, int offset, ShapeModifier modifier) { const Tab* adjacent_tab = tab->controller()->GetAdjacentTab(tab, offset); @@ -845,8 +844,9 @@ absl::optional<int> fill_id, int y_inset) const { CHECK(tab()); - const SkPath fill_path = GetPath(PathType::kFill, canvas->image_scale(), - active == TabActive::kActive); + const SkPath fill_path = + GetPath(TabStyle::PathType::kFill, canvas->image_scale(), + active == TabActive::kActive); gfx::ScopedCanvas scoped_canvas(canvas); const float scale = canvas->UndoDeviceScaleFactor(); @@ -928,8 +928,7 @@ canvas->DrawRect(separator_bounds.trailing, flags); } -// static -float GM2TabStyle::GetTopCornerRadiusForWidth(int width) { +float GM2TabStyle::GetTopCornerRadiusForWidth(int width) const { // Get the width of the top of the tab by subtracting the width of the outer // corners. const int ideal_radius = GetCornerRadius(); @@ -941,10 +940,9 @@ return std::clamp<float>(radius, 0, ideal_radius); } -// static gfx::RectF GM2TabStyle::ScaleAndAlignBounds(const gfx::Rect& bounds, float scale, - int stroke_thickness) { + int stroke_thickness) const { // Convert to layout bounds. We must inset the width such that the right edge // of one tab's layout bounds is the same as the left edge of the next tab's; // this way the two tabs' separators will be drawn at the same coordinate. @@ -1069,12 +1067,12 @@ return std::make_unique<GM2TabStyle>(tab); } +// static std::unique_ptr<TabStyleViews> TabStyleViews::Create() { return TabStyleViews::CreateForTab(nullptr); } -// static -int TabStyleViews::GetMinimumActiveWidth() { +int TabStyleViews::GetMinimumActiveWidth() const { int min_active_width = TabCloseButton::GetGlyphSize() + GetContentsHorizontalInsetSize() * 2; if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) { @@ -1087,8 +1085,7 @@ return min_active_width; } -// static -int TabStyleViews::GetMinimumInactiveWidth() { +int TabStyleViews::GetMinimumInactiveWidth() const { // Allow tabs to shrink until they appear to be 16 DIP wide excluding // outer corners. constexpr int kInteriorWidth = 16;
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.h b/chrome/browser/ui/views/tabs/tab_style_views.h index 46cc79db..d4d94e5 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.h +++ b/chrome/browser/ui/views/tabs/tab_style_views.h
@@ -42,11 +42,11 @@ // If |force_active| is true, applies an active appearance on the tab (usually // involving painting an optional stroke) even if the tab is not the active // tab. - virtual SkPath GetPath( - PathType path_type, - float scale, - bool force_active = false, - RenderUnits render_units = RenderUnits::kPixels) const = 0; + virtual SkPath GetPath(TabStyle::PathType path_type, + float scale, + bool force_active = false, + TabStyle::RenderUnits render_units = + TabStyle::RenderUnits::kPixels) const = 0; // Paints the tab. virtual void PaintTab(gfx::Canvas* canvas) const = 0; @@ -67,27 +67,24 @@ virtual float GetActiveOpacity() const = 0; // Derives and returns colors for the tab. See TabColors, above. - virtual TabColors CalculateColors() const = 0; - - // Opacity of the active tab background painted over inactive selected tabs. - virtual float GetSelectedTabOpacity() const = 0; + virtual TabStyle::TabColors CalculateColors() const = 0; // Sets the center of the radial highlight in the hover animation. virtual void SetHoverLocation(const gfx::Point& location) = 0; // Shows the hover animation. - virtual void ShowHover(ShowHoverStyle style) = 0; + virtual void ShowHover(TabStyle::ShowHoverStyle style) = 0; // Hides the hover animation. - virtual void HideHover(HideHoverStyle style) = 0; + virtual void HideHover(TabStyle::HideHoverStyle style) = 0; // Returns the minimum possible width of a selected Tab. Selected tabs must // always show a close button, and thus have a larger minimum size than // unselected tabs. - static int GetMinimumActiveWidth(); + int GetMinimumActiveWidth() const; // Returns the minimum possible width of a single unselected Tab. - static int GetMinimumInactiveWidth(); + int GetMinimumInactiveWidth() const; protected: // Avoid implicitly-deleted constructor.
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index d266038..3d635cc7 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -349,11 +349,12 @@ // Test layout for every width from standard to minimum. int width, min_width; if (is_pinned_tab) { - width = min_width = TabStyle::GetPinnedWidth(); + width = min_width = tab->tab_style()->GetPinnedWidth(); } else { - width = TabStyle::GetStandardWidth(); - min_width = is_active_tab ? TabStyleViews::GetMinimumActiveWidth() - : TabStyleViews::GetMinimumInactiveWidth(); + width = tab->tab_style()->GetStandardWidth(); + min_width = is_active_tab + ? tab->tab_style()->GetMinimumActiveWidth() + : tab->tab_style()->GetMinimumInactiveWidth(); } const int height = GetLayoutConstant(TAB_HEIGHT); for (; width >= min_width; --width) {
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc index 07cf9063..64da8b20 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
@@ -6,6 +6,7 @@ #include <set> +#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/task/single_thread_task_runner.h" @@ -18,6 +19,7 @@ #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/toolbar/app_menu_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/app_menu.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" @@ -151,7 +153,22 @@ } else if (type_and_severity_.type == AppMenuIconController::IconType::UPGRADE_NOTIFICATION) { tooltip_message_id = IDS_APPMENU_TOOLTIP_UPDATE_AVAILABLE; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) + int message_id = IDS_APP_MENU_BUTTON_UPDATE; + if (base::FeatureList::IsEnabled(features::kUpdateTextOptions)) { + if (features::kUpdateTextOptionNumber.Get() == 1) { + message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT1; + } else if (features::kUpdateTextOptionNumber.Get() == 2) { + message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT2; + } else { + message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT3; + } + } + text = l10n_util::GetStringUTF16(message_id); +#else text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_UPDATE); +#endif } else { tooltip_message_id = IDS_APPMENU_TOOLTIP_ALERT; text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_ERROR);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index 485d96c..1340622 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -205,6 +205,7 @@ SetProperty(views::kInternalPaddingKey, gfx::Insets()); SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); } ToolbarButton::~ToolbarButton() = default;
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.cc b/chrome/browser/ui/views/translate/translate_icon_view.cc index 7478c00..f4931d4 100644 --- a/chrome/browser/ui/views/translate/translate_icon_view.cc +++ b/chrome/browser/ui/views/translate/translate_icon_view.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/views/translate/translate_bubble_controller.h" #include "chrome/browser/ui/views/translate/translate_bubble_view.h" #include "chrome/grit/generated_resources.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/translate/core/browser/language_state.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_metrics_logger.h" @@ -97,7 +98,9 @@ PageActionIconView::ExecuteSource execute_source) {} const gfx::VectorIcon& TranslateIconView::GetVectorIcon() const { - return kTranslateIcon; + return OmniboxFieldTrial::IsChromeRefreshIconsEnabled() + ? kTranslateChromeRefreshIcon + : kTranslateIcon; } BEGIN_METADATA(TranslateIconView, PageActionIconView)
diff --git a/chrome/browser/ui/views/update_recommended_message_box.cc b/chrome/browser/ui/views/update_recommended_message_box.cc index 0f21fe5f..366dfdf3 100644 --- a/chrome/browser/ui/views/update_recommended_message_box.cc +++ b/chrome/browser/ui/views/update_recommended_message_box.cc
@@ -4,11 +4,13 @@ #include "chrome/browser/ui/views/update_recommended_message_box.h" +#include "base/feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "components/constrained_window/constrained_window_views.h" @@ -37,10 +39,26 @@ l10n_util::GetStringUTF16(IDS_NOT_NOW)); SetModalType(ui::MODAL_TYPE_WINDOW); SetOwnedByWidget(true); + +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) + SetTitle(base::FeatureList::IsEnabled(features::kUpdateTextOptions) + ? IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT + : IDS_UPDATE_RECOMMENDED_DIALOG_TITLE); +#else SetTitle(IDS_UPDATE_RECOMMENDED_DIALOG_TITLE); +#endif + std::u16string update_message; #if BUILDFLAG(IS_CHROMEOS_ASH) update_message = l10n_util::GetStringUTF16(IDS_UPDATE_RECOMMENDED); +#elif BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) + update_message = l10n_util::GetPluralStringFUTF16( + base::FeatureList::IsEnabled(features::kUpdateTextOptions) + ? IDS_UPDATE_RECOMMENDED_ALT + : IDS_UPDATE_RECOMMENDED, + BrowserList::GetIncognitoBrowserCount()); #else update_message = l10n_util::GetPluralStringFUTF16( IDS_UPDATE_RECOMMENDED, BrowserList::GetIncognitoBrowserCount());
diff --git a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc index c232cee..a1b9901 100644 --- a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc +++ b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc
@@ -97,7 +97,17 @@ #else static const auto kAccelerator = IDC_FOCUS_NEXT_PANE; #endif - CHECK(browser_view_->GetAccelerator(kAccelerator, &accelerator)); + if (browser_view_->GetAccelerator(kAccelerator, &accelerator)) { + accelerator_text = accelerator.GetShortcutText(); + } else { + // TODO(crbug.com/1432803): GetAccelerator appears to be failing + // sporadically on Windows, for unknown reasons. Since we can't have this + // code crashing in release, it's being returned to the original NOTREACHED + // before everything was changed to CHECKs. This bug will continue to be + // researched for a more correct fix. + accelerator_text = u"F6"; + NOTREACHED(); + } return l10n_util::GetStringFUTF16(IDS_FOCUS_HELP_BUBBLE_TUTORIAL_DESCRIPTION, accelerator.GetShortcutText()); }
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc index 19675e11..f4df27ba 100644 --- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc +++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -392,25 +392,6 @@ .SetBubbleTitleText(IDS_BATTERY_SAVER_MODE_PROMO_TITLE) .SetBubbleArrow(HelpBubbleArrow::kTopRight))); - // kIPHHighEfficiencyInfoModeFeature: - registry.RegisterFeature(std::move( - FeaturePromoSpecification::CreateForCustomAction( - feature_engagement::kIPHHighEfficiencyInfoModeFeature, - kHighEfficiencyChipElementId, - IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT, - IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT, - base::BindRepeating( - [](ui::ElementContext ctx, - user_education::FeaturePromoHandle promo_handle) { - auto* browser = chrome::FindBrowserWithUiElementContext(ctx); - if (browser) - chrome::ShowSettingsSubPage(browser, - chrome::kPerformanceSubPage); - RecordHighEfficiencyInfoIPHOpenSettings(browser != nullptr); - })) - .SetBubbleTitleText(IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE) - .SetBubbleArrow(HelpBubbleArrow::kTopCenter))); - // kIPHHighEfficiencyModeFeature: registry.RegisterFeature(std::move( FeaturePromoSpecification::CreateForCustomAction(
diff --git a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc index 4264a5a0..2920935 100644 --- a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/location_bar/custom_tab_bar_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/browser/ui/views/tabs/tab_strip_controller.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" @@ -775,4 +776,40 @@ EXPECT_FALSE(commandController->IsCommandEnabled(IDC_CLOSE_TAB)); } +IN_PROC_BROWSER_TEST_F(WebAppTabStripBrowserTest, + MiddleClickDoesntCloseHomeTab) { + GURL start_url = + embedded_test_server()->GetURL("/web_apps/tab_strip_customizations.html"); + AppId app_id = InstallWebAppFromPage(browser(), start_url); + Browser* app_browser = FindWebAppBrowser(browser()->profile(), app_id); + TabStripModel* tab_strip_model = app_browser->tab_strip_model(); + + EXPECT_TRUE(registrar().IsTabbedWindowModeEnabled(app_id)); + + // Expect app opened with pinned home tab. + EXPECT_EQ(tab_strip_model->count(), 1); + EXPECT_TRUE(tab_strip_model->IsTabPinned(0)); + EXPECT_EQ(tab_strip_model->GetWebContentsAt(0)->GetVisibleURL(), start_url); + EXPECT_EQ(tab_strip_model->active_index(), 0); + + BrowserView* view = BrowserView::GetBrowserViewForBrowser(app_browser); + TabStripController* controller = view->tabstrip()->controller(); + + // The home tab is the only tab open so it can be closed. + EXPECT_TRUE( + controller->BeforeCloseTab(0, CloseTabSource::CLOSE_TAB_FROM_MOUSE)); + + // Open another tab. + OpenUrlAndWait(app_browser, + embedded_test_server()->GetURL("/web_apps/get_manifest.html")); + EXPECT_EQ(tab_strip_model->count(), 2); + + // Home tab should not be closable. + EXPECT_FALSE( + controller->BeforeCloseTab(0, CloseTabSource::CLOSE_TAB_FROM_MOUSE)); + // Non home tab should be closable. + EXPECT_TRUE( + controller->BeforeCloseTab(1, CloseTabSource::CLOSE_TAB_FROM_MOUSE)); +} + } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc b/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc index c47f6c865..573aed9 100644 --- a/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc
@@ -4,17 +4,19 @@ #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h" +#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace web_app { -bool HasPinnedHomeTab(TabStripModel* tab_strip_model) { +bool HasPinnedHomeTab(const TabStripModel* tab_strip_model) { if (!tab_strip_model->ContainsIndex(0)) return false; - return tab_strip_model->IsTabPinned(0); + return tab_strip_model->delegate()->IsForWebApp() && + tab_strip_model->IsTabPinned(0); } -bool IsPinnedHomeTab(TabStripModel* tab_strip_model, int index) { +bool IsPinnedHomeTab(const TabStripModel* tab_strip_model, int index) { return HasPinnedHomeTab(tab_strip_model) && index == 0; }
diff --git a/chrome/browser/ui/web_applications/web_app_tabbed_utils.h b/chrome/browser/ui/web_applications/web_app_tabbed_utils.h index 6b5b785..d9a1e8a 100644 --- a/chrome/browser/ui/web_applications/web_app_tabbed_utils.h +++ b/chrome/browser/ui/web_applications/web_app_tabbed_utils.h
@@ -13,10 +13,10 @@ namespace web_app { // Returns whether the web apps tab strip contains a pinned home tab. -bool HasPinnedHomeTab(TabStripModel* tab_strip_model); +bool HasPinnedHomeTab(const TabStripModel* tab_strip_model); // Returns whether the tab at the given index is the pinned home tab. -bool IsPinnedHomeTab(TabStripModel* tab_strip_model, int index); +bool IsPinnedHomeTab(const TabStripModel* tab_strip_model, int index); // Returns whether the given launch_url should be treated as the home tab URL. bool IsPinnedHomeTabUrl(const WebAppRegistrar& registrar,
diff --git a/chrome/browser/ui/webui/ash/internet_detail_dialog.cc b/chrome/browser/ui/webui/ash/internet_detail_dialog.cc index d55668b..c2ed4c4 100644 --- a/chrome/browser/ui/webui/ash/internet_detail_dialog.cc +++ b/chrome/browser/ui/webui/ash/internet_detail_dialog.cc
@@ -22,6 +22,7 @@ #include "chromeos/ash/components/network/network_state.h" #include "chromeos/ash/components/network/network_state_handler.h" #include "chromeos/ash/components/network/network_util.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/strings/grit/components_strings.h" @@ -31,6 +32,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/strings/grit/ui_chromeos_strings.h" #include "ui/chromeos/strings/network/network_element_localized_strings_provider.h" +#include "ui/webui/color_change_listener/color_change_handler.h" namespace ash { @@ -173,6 +175,7 @@ source->AddBoolean("showTechnologyBadge", !features::IsSeparateNetworkIconsEnabled()); source->AddBoolean("apnRevamp", features::IsApnRevampEnabled()); + source->AddBoolean("isJellyEnabled", chromeos::features::IsJellyEnabled()); cellular_setup::AddNonStringLoadTimeData(source); AddInternetStrings(source); source->AddLocalizedString("title", IDS_SETTINGS_INTERNET_DETAIL); @@ -193,6 +196,12 @@ GetNetworkConfigService(std::move(receiver)); } +void InternetDetailDialogUI::BindInterface( + mojo::PendingReceiver<color_change_listener::mojom::PageHandler> receiver) { + color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>( + web_ui()->GetWebContents(), std::move(receiver)); +} + WEB_UI_CONTROLLER_TYPE_IMPL(InternetDetailDialogUI) } // namespace ash
diff --git a/chrome/browser/ui/webui/ash/internet_detail_dialog.h b/chrome/browser/ui/webui/ash/internet_detail_dialog.h index 834dd63..47025ff 100644 --- a/chrome/browser/ui/webui/ash/internet_detail_dialog.h +++ b/chrome/browser/ui/webui/ash/internet_detail_dialog.h
@@ -13,6 +13,13 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "ui/gfx/native_widget_types.h" #include "ui/web_dialogs/web_dialog_ui.h" +#include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h" + +namespace ui { + +class ColorChangeHandler; + +} // namespace ui namespace ash { @@ -76,7 +83,14 @@ mojo::PendingReceiver<chromeos::network_config::mojom::CrosNetworkConfig> receiver); + // Instantiates the implementor of the mojom::PageHandler mojo interface + // passing the pending receiver that will be internally bound. + void BindInterface( + mojo::PendingReceiver<color_change_listener::mojom::PageHandler> + receiver); + private: + std::unique_ptr<ui::ColorChangeHandler> color_provider_handler_; WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc index d4e316c..ef9c35a1 100644 --- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc +++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc
@@ -40,6 +40,9 @@ source->AddResourcePath( chrome::kChromeUIPrivacySandboxDialogNoticePath, IDR_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_DIALOG_HTML); + source->AddResourcePath( + chrome::kChromeUIPrivacySandboxDialogNoticeRestrictedPath, + IDR_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_RESTRICTED_DIALOG_HTML); static constexpr webui::LocalizedString kStrings[] = { {"privacySandboxTitle", IDS_SETTINGS_PRIVACY_SANDBOX_TITLE}, @@ -168,6 +171,9 @@ IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_LEARN_MORE_DESCRIPTION_4}, {"m1NoticeRowLearnMoreDescription5", IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_LEARN_MORE_DESCRIPTION_5}, + // Strings for the restricted notice dialog (kM1NoticeRestricted). + {"m1NoticeRestrictedDescription1", + IDS_PRIVACY_SANDBOX_M1_NOTICE_RESTRICTED_DESCRIPTION_1}, // Shared for all dialogs. {"m1DialogMoreButton", IDS_PRIVACY_SANDBOX_M1_DIALOG_MORE_BUTTON}}; @@ -195,7 +201,6 @@ prompt_type == PrivacySandboxService::PromptType::kConsent); content::WebUIDataSource::Update( profile, chrome::kChromeUIPrivacySandboxDialogHost, std::move(update)); - auto handler = std::make_unique<PrivacySandboxDialogHandler>( std::move(close_callback), std::move(resize_callback), std::move(show_dialog_callback), std::move(open_settings_callback),
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom index d25eefa..d670e9e9 100644 --- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom +++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom
@@ -20,9 +20,9 @@ enum SortOrder { kNewest = 0, kOldest = 1, - kAlphabetical = 2, - kReverseAlphabetical = 3, - kLastOpened = 4, + kLastOpened = 2, + kAlphabetical = 3, + kReverseAlphabetical = 4, // Must be last. May add new values before this one. kCount = 5,
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc index ccc0390..fba61b7 100644 --- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc +++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -128,12 +128,6 @@ base::Unretained(this))); web_ui()->RegisterMessageCallback( - syncer::sync_ui_util::kRequestStopKeepData, - base::BindRepeating( - &SyncInternalsMessageHandler::HandleRequestStopKeepData, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( syncer::sync_ui_util::kRequestStopClearData, base::BindRepeating( &SyncInternalsMessageHandler::HandleRequestStopClearData, @@ -268,18 +262,6 @@ syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); } -void SyncInternalsMessageHandler::HandleRequestStopKeepData( - const base::Value::List& args) { - DCHECK_EQ(0U, args.size()); - - SyncService* service = GetSyncService(); - if (!service) { - return; - } - - service->GetUserSettings()->ClearSyncRequested(); -} - void SyncInternalsMessageHandler::HandleRequestStopClearData( const base::Value::List& args) { DCHECK_EQ(0U, args.size());
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h index 70f43f2..5f44a4e 100644 --- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h +++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h
@@ -62,9 +62,6 @@ // Handler for requestStart message. void HandleRequestStart(const base::Value::List& args); - // Handler for requestStopKeepData message. - void HandleRequestStopKeepData(const base::Value::List& args); - // Handler for requestStopClearData message. void HandleRequestStopClearData(const base::Value::List& args);
diff --git a/chrome/browser/ui/webui/version/version_ui.cc b/chrome/browser/ui/webui/version/version_ui.cc index 67545be..d0b6ded 100644 --- a/chrome/browser/ui/webui/version/version_ui.cc +++ b/chrome/browser/ui/webui/version/version_ui.cc
@@ -55,6 +55,7 @@ #endif #if BUILDFLAG(IS_WIN) +#include "base/win/windows_version.h" #include "chrome/browser/ui/webui/version/version_handler_win.h" #include "chrome/browser/ui/webui/version/version_util_win.h" #endif @@ -181,6 +182,23 @@ case base::mac::CPUType::kArm: return IDS_VERSION_UI_64BIT_ARM; } +#elif BUILDFLAG(IS_WIN) +#if defined(ARCH_CPU_ARM64) + return IDS_VERSION_UI_64BIT_ARM; +#else + bool emulated = base::win::OSInfo::IsRunningEmulatedOnArm64(); +#if defined(ARCH_CPU_X86) + if (emulated) { + return IDS_VERSION_UI_32BIT_TRANSLATED_INTEL; + } + return IDS_VERSION_UI_32BIT; +#else // defined(ARCH_CPU_X86) + if (emulated) { + return IDS_VERSION_UI_64BIT_TRANSLATED_INTEL; + } + return IDS_VERSION_UI_64BIT; +#endif // defined(ARCH_CPU_X86) +#endif // defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_64_BITS) return IDS_VERSION_UI_64BIT; #elif defined(ARCH_CPU_32_BITS)
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc index bb927a3..7fc40f6e 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc +++ b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
@@ -17,6 +17,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -40,6 +41,26 @@ constexpr int kMaxJumpListItems = 10; +constexpr const char* kShortcutsMenuRegistrationHistogram = + "WebApp.ShortcutsMenu.Win.Results"; + +// This should be kept in sync with ShortcutsMenuWinRegistrationResult inside +// tools/metrics/histograms/enums.xml +enum class ShortcutsMenuRegistrationResult { + kSuccess = 0, + kFailedToCreateShortcutMenuIconsDirectory = 1, + kFailedToCreateIconFromImageFamily = 2, + kFailedToBeginJumplistUpdate = 3, + kFailedToAddLinkItemsToJumplist = 4, + kFailedToCommitJumplistUpdate = 5, + kMaxValue = kFailedToCommitJumplistUpdate +}; + +// Records the result of registering shortcuts menu on Win to UMA. +void RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult result) { + base::UmaHistogramEnumeration(kShortcutsMenuRegistrationHistogram, result); +} + // Testing hook for shell_integration_linux UpdateJumpListForTesting& GetUpdateJumpListForTesting() { static base::NoDestructor<UpdateJumpListForTesting> instance; @@ -65,6 +86,8 @@ const ShortcutsMenuIconBitmaps& shortcut_icons) { if (!base::CreateDirectory( GetShortcutsMenuIconsDirectory(shortcut_data_dir))) { + RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult:: + kFailedToCreateShortcutMenuIconsDirectory); return false; } int icon_index = -1; @@ -81,6 +104,8 @@ image_family.Add(gfx::Image::CreateFrom1xBitmap(item.second)); } if (!IconUtil::CreateIconFileFromImageFamily(image_family, icon_file)) { + RecordShortcutsMenuResult( + ShortcutsMenuRegistrationResult::kFailedToCreateIconFromImageFamily); return false; } } @@ -102,13 +127,24 @@ } JumpListUpdater jumplist_updater(app_user_model_id); - if (!jumplist_updater.BeginUpdate()) + if (!jumplist_updater.BeginUpdate()) { + RecordShortcutsMenuResult( + ShortcutsMenuRegistrationResult::kFailedToBeginJumplistUpdate); return false; + } - if (!jumplist_updater.AddTasks(link_items)) + if (!jumplist_updater.AddTasks(link_items)) { + RecordShortcutsMenuResult( + ShortcutsMenuRegistrationResult::kFailedToAddLinkItemsToJumplist); return false; + } - return jumplist_updater.CommitUpdate(); + bool success = jumplist_updater.CommitUpdate(); + if (!success) { + RecordShortcutsMenuResult( + ShortcutsMenuRegistrationResult::kFailedToCommitJumplistUpdate); + } + return success; } } // namespace @@ -181,6 +217,9 @@ void OnShortcutsMenuRegistrationComplete(RegisterShortcutsMenuCallback callback, bool registration_successful) { + if (registration_successful) { + RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult::kSuccess); + } std::move(callback).Run(registration_successful ? Result::kOk : Result::kError); }
diff --git a/chrome/browser/web_applications/scope_extension_info.cc b/chrome/browser/web_applications/scope_extension_info.cc index 3139b76..7c4db4b 100644 --- a/chrome/browser/web_applications/scope_extension_info.cc +++ b/chrome/browser/web_applications/scope_extension_info.cc
@@ -16,10 +16,10 @@ : origin(origin), has_origin_wildcard(has_origin_wildcard) {} base::Value ScopeExtensionInfo::AsDebugValue() const { - base::Value root(base::Value::Type::DICT); - root.SetStringKey("origin", origin.GetDebugString()); - root.SetBoolKey("has_origin_wildcard", has_origin_wildcard); - return root; + base::Value::Dict root = base::Value::Dict() + .Set("origin", origin.GetDebugString()) + .Set("has_origin_wildcard", has_origin_wildcard); + return base::Value(std::move(root)); } void ScopeExtensionInfo::Reset() {
diff --git a/chrome/browser/web_applications/web_app_chromeos_data.cc b/chrome/browser/web_applications/web_app_chromeos_data.cc index 998de97a..9bb730d 100644 --- a/chrome/browser/web_applications/web_app_chromeos_data.cc +++ b/chrome/browser/web_applications/web_app_chromeos_data.cc
@@ -11,14 +11,16 @@ namespace web_app { base::Value WebAppChromeOsData::AsDebugValue() const { - base::Value root(base::Value::Type::DICT); - root.SetBoolKey("show_in_launcher", show_in_launcher); - root.SetBoolKey("show_in_search", show_in_search); - root.SetBoolKey("show_in_management", show_in_management); - root.SetBoolKey("is_disabled", is_disabled); - root.SetBoolKey("oem_installed", oem_installed); - root.SetBoolKey("handles_file_open_intents", handles_file_open_intents); - return root; + base::Value::Dict root = + base::Value::Dict() + .Set("show_in_launcher", show_in_launcher) + .Set("show_in_search", show_in_search) + .Set("show_in_management", show_in_management) + .Set("is_disabled", is_disabled) + .Set("oem_installed", oem_installed) + .Set("handles_file_open_intents", handles_file_open_intents); + + return base::Value(std::move(root)); } bool operator==(const WebAppChromeOsData& chromeos_data1,
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index d6a1e10..9c3767e 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1681394130-10b03420552d3a7e771d382d6e276bfe2e51e1f6.profdata +chrome-mac-arm-main-1681408779-19562355795693dc9271fba711025a47c2a3373e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index abb63da2..e706f7a 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1681376373-fbe671e0f7d99283c72bb1c3dc3f3820de4f8a59.profdata +chrome-win32-main-1681397997-e43e6f3cbcaa1aa4b0d5bae4dfd28e661595bd29.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9e26dec7..1b04ce3 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1681386955-d6d720bb8e09c04489f197f8c5d4f584c48f89cf.profdata +chrome-win64-main-1681397997-1a8c5ec9d0f5a3f3ea4e108a5fc9e8ee887cae84.profdata
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index e149c52..43071ff 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -166,6 +166,7 @@ "chrome://privacy-sandbox-dialog"; const char kChromeUIPrivacySandboxDialogCombinedPath[] = "combined"; const char kChromeUIPrivacySandboxDialogNoticePath[] = "notice"; +const char kChromeUIPrivacySandboxDialogNoticeRestrictedPath[] = "restricted"; const char kChromeUIPrivacySandboxFledgeURL[] = "chrome://settings/adPrivacy/sites"; const char kChromeUIPrivacySandboxTopicsURL[] =
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 3d09c92..8d3bb6e 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -168,6 +168,7 @@ extern const char kChromeUIPrivacySandboxDialogURL[]; extern const char kChromeUIPrivacySandboxDialogCombinedPath[]; extern const char kChromeUIPrivacySandboxDialogNoticePath[]; +extern const char kChromeUIPrivacySandboxDialogNoticeRestrictedPath[]; extern const char kChromeUIPrivacySandboxFledgeURL[]; extern const char kChromeUIPrivacySandboxTopicsURL[]; extern const char kChromeUIProfileInternalsHost[];
diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc index 9ac378b..d3c5669 100644 --- a/chrome/renderer/chrome_render_thread_observer.cc +++ b/chrome/renderer/chrome_render_thread_observer.cc
@@ -32,6 +32,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/media/media_resource_provider.h" #include "chrome/common/net/net_resource_provider.h" +#include "chrome/common/renderer_configuration.mojom.h" #include "chrome/common/url_constants.h" #include "components/visitedlink/renderer/visitedlink_reader.h" #include "content/public/child/child_thread.h" @@ -127,11 +128,6 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) -chrome::mojom::DynamicParams* GetDynamicConfigParams() { - static base::NoDestructor<chrome::mojom::DynamicParams> dynamic_params; - return dynamic_params.get(); -} - ChromeRenderThreadObserver::ChromeRenderThreadObserver() : visited_link_reader_(new visitedlink::VisitedLinkReader) { // Configure modules that need access to resources. @@ -141,10 +137,15 @@ ChromeRenderThreadObserver::~ChromeRenderThreadObserver() {} -// static -const chrome::mojom::DynamicParams& -ChromeRenderThreadObserver::GetDynamicParams() { - return *GetDynamicConfigParams(); +chrome::mojom::DynamicParams ChromeRenderThreadObserver::GetDynamicParams() + const { + { + base::AutoLock lock(dynamic_params_lock_); + if (dynamic_params_) { + return *dynamic_params_; + } + } + return chrome::mojom::DynamicParams(); } void ChromeRenderThreadObserver::RegisterMojoInterfaces( @@ -180,7 +181,8 @@ void ChromeRenderThreadObserver::SetConfiguration( chrome::mojom::DynamicParamsPtr params) { - *GetDynamicConfigParams() = std::move(*params); + base::AutoLock lock(dynamic_params_lock_); + dynamic_params_ = std::move(params); } void ChromeRenderThreadObserver::OnRendererConfigurationAssociatedRequest(
diff --git a/chrome/renderer/chrome_render_thread_observer.h b/chrome/renderer/chrome_render_thread_observer.h index ad37007..4a4ba4bf 100644 --- a/chrome/renderer/chrome_render_thread_observer.h +++ b/chrome/renderer/chrome_render_thread_observer.h
@@ -7,6 +7,8 @@ #include <memory> +#include "base/synchronization/lock.h" +#include "base/thread_annotations.h" #include "build/chromeos_buildflags.h" #include "chrome/common/renderer_configuration.mojom.h" #include "components/content_settings/common/content_settings_manager.mojom.h" @@ -83,9 +85,9 @@ static bool is_incognito_process() { return is_incognito_process_; } - // Return the dynamic parameters - those that may change while the + // Return a copy of the dynamic parameters - those that may change while the // render process is running. - static const chrome::mojom::DynamicParams& GetDynamicParams(); + chrome::mojom::DynamicParams GetDynamicParams() const; visitedlink::VisitedLinkReader* visited_link_reader() { return visited_link_reader_.get(); @@ -131,6 +133,10 @@ mojo::AssociatedReceiverSet<chrome::mojom::RendererConfiguration> renderer_configuration_receivers_; + chrome::mojom::DynamicParamsPtr dynamic_params_ + GUARDED_BY(dynamic_params_lock_); + mutable base::Lock dynamic_params_lock_; + #if BUILDFLAG(IS_CHROMEOS_ASH) // Only set if the Chrome OS merge session was running when the renderer // was started.
diff --git a/chrome/renderer/url_loader_throttle_provider_impl.cc b/chrome/renderer/url_loader_throttle_provider_impl.cc index 3797bc0..72bd8e1 100644 --- a/chrome/renderer/url_loader_throttle_provider_impl.cc +++ b/chrome/renderer/url_loader_throttle_provider_impl.cc
@@ -190,7 +190,8 @@ #if BUILDFLAG(IS_ANDROID) client_data_header, #endif - ChromeRenderThreadObserver::GetDynamicParams())); + chrome_content_renderer_client_->GetChromeObserver() + ->GetDynamicParams())); #if BUILDFLAG(IS_CHROMEOS_ASH) throttles.emplace_back(std::make_unique<AshMergeSessionLoaderThrottle>(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9768703..674046ab 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -605,9 +605,9 @@ if (is_chromeos_ash) { sources += [ - "../browser/ash/login/app_mode/test/ash_accelerator_helpers.cc", "../browser/apps/app_service/metrics/app_platform_metrics_service_test_base.cc", "../browser/apps/app_service/metrics/app_platform_metrics_service_test_base.h", + "../browser/ash/login/app_mode/test/ash_accelerator_helpers.cc", "../browser/ash/login/lock/screen_locker_tester.cc", "../browser/ash/login/lock/screen_locker_tester.h", "../browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc", @@ -9128,10 +9128,10 @@ sources += [ "../browser/supervised_user/chromeos/mock_large_icon_service.cc", "../browser/supervised_user/chromeos/mock_large_icon_service.h", + "../browser/supervised_user/chromeos/web_content_handler_impl_unittest.cc", ] } if (is_chromeos_ash) { - sources += [ "../browser/supervised_user/chromeos/web_content_handler_impl_unittest.cc" ] deps += [ "//chrome/browser/ash/crosapi" ] } if (is_android) {
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js index f230f6f..542d933 100644 --- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js +++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -20,32 +20,58 @@ var kDefaultPuk = '12345678'; var privateHelpers = { - // Watches for the states |expectedStates| in reverse order. If all states - // were observed in the right order, succeeds and calls |done|. If any + // networkToExpectedStatesMap is a Map string (network GUID) -> array of + // strings (expected states). + // For each network specified there, watches for onNetworksChanged events with + // the specified states, in reverse order. + // If all states were observed (in the right order), succeeds and calls + // |done|. If any // unexpected state is observed, fails. - watchForStateChanges: function(network, expectedStates, done) { - var self = this; - var collectProperties = function(properties) { - var finishTest = function() { + watchForStateChanges: function(networkToExpectedStatesMap, done) { + const networkToLastSeenState = new Map(); + const self = this; + const collectProperties = function(network, properties) { + const finishTest = function() { chrome.networkingPrivate.onNetworksChanged.removeListener( self.onNetworkChange); done(); }; + const currentState = properties.ConnectionState; + + // Ignore if the state has not changed. + const lastSeenState = networkToLastSeenState.get(network); + if (lastSeenState && lastSeenState === currentState) { + return; + } + networkToLastSeenState.set(network, currentState); + + const expectedStates = networkToExpectedStatesMap.get(network); + if (!expectedStates) { + chrome.test.fail( + 'Unexpected state change for network ' + network + ' (' + +')'); + } if (expectedStates.length > 0) { - var expectedState = expectedStates.pop(); - assertEq(expectedState, properties.ConnectionState); - if (expectedStates.length == 0) - finishTest(); + const expectedState = expectedStates.pop(); + assertEq(expectedState, currentState); + if (expectedStates.length == 0) { + networkToExpectedStatesMap.delete(network); + } + } + if (networkToExpectedStatesMap.size == 0) { + finishTest(); } }; this.onNetworkChange = function(changes) { - assertEq([network], changes); - chrome.networkingPrivate.getProperties( - network, - callbackPass(collectProperties)); + for (let network of changes) { + assertTrue(networkToExpectedStatesMap.has(network)); + chrome.networkingPrivate.getProperties( + network, callbackPass(function(properties) { + collectProperties(network, properties); + })); + } }; chrome.networkingPrivate.onNetworksChanged.addListener( - this.onNetworkChange); + self.onNetworkChange); }, networkListChangedListener: function(expected, done) { function listener(list) { @@ -831,17 +857,19 @@ function onNetworksChangedEventConnect() { var network = 'stub_wifi2_guid'; var done = chrome.test.callbackAdded(); - var expectedStates = [ConnectionStateType.CONNECTED]; - var listener = - new privateHelpers.watchForStateChanges(network, expectedStates, done); + var listener = new privateHelpers.watchForStateChanges( + new Map([ + ['stub_wifi1_guid', [ConnectionStateType.NOT_CONNECTED]], + [network, [ConnectionStateType.CONNECTED]] + ]), + done); chrome.networkingPrivate.startConnect(network, networkCallbackPass()); }, function onNetworksChangedEventDisconnect() { var network = 'stub_wifi1_guid'; var done = chrome.test.callbackAdded(); - var expectedStates = [ConnectionStateType.NOT_CONNECTED]; - var listener = - new privateHelpers.watchForStateChanges(network, expectedStates, done); + var listener = new privateHelpers.watchForStateChanges( + new Map([[network, [ConnectionStateType.NOT_CONNECTED]]]), done); chrome.networkingPrivate.startDisconnect(network, networkCallbackPass()); }, function onNetworkListChangedEvent() {
diff --git a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js index 329af08..fe645945 100644 --- a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js +++ b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
@@ -405,4 +405,25 @@ assertTrue(!!internetDetailDialog.shadowRoot.querySelector('apn-list') .shadowRoot.querySelector('apn-detail-dialog')); }); + + [false, true].forEach(isJellyEnabled => { + test('Dynamic theme CSS is added when isJellyEnabled is set', async () => { + loadTimeData.overrideValues({ + isJellyEnabled: isJellyEnabled, + }); + await setupCellularNetwork( + /*isPrimary=*/ true, /*isInhibited=*/ false); + await init(); + + const linkEl = + document.querySelector('link[href*=\'chrome://theme/colors.css\']'); + if (isJellyEnabled) { + assertTrue(!!linkEl); + assertTrue(document.body.classList.contains('jelly-enabled')); + } else { + assertEquals(null, linkEl); + assertFalse(document.body.classList.contains('jelly-enabled')); + } + }); + }); });
diff --git a/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts b/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts index 8b1aa6b..dfa0b52 100644 --- a/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts +++ b/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts
@@ -5,7 +5,7 @@ import 'chrome://password-manager/password_manager.js'; import {PasswordManagerImpl, SyncBrowserProxyImpl} from 'chrome://password-manager/password_manager.js'; -import {assertEquals} from 'chrome://webui-test/chai_assert.js'; +import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; import {TestPasswordManagerProxy} from './test_password_manager_proxy.js'; @@ -32,6 +32,7 @@ createAffiliatedDomain('test.com'), createAffiliatedDomain('m.test.com'), ]; + passwordManager.setRequestCredentialsDetailsResponse([password]); syncProxy.accountInfo = { email: 'test@gmail.com', @@ -43,8 +44,136 @@ document.body.appendChild(dialog); await flushTasks(); + assertTrue(dialog.$.dialog.open); assertEquals( syncProxy.accountInfo.email, dialog.$.accountEmail.textContent!.trim()); assertEquals(syncProxy.accountInfo.avatarImage, dialog.$.avatar.src); + + const passwordItems = + dialog.shadowRoot!.querySelectorAll('password-preview-item'); + assertEquals(1, passwordItems.length); + + const passwordItem = passwordItems[0]; + assertTrue(!!passwordItem); + // Checked by default. + assertTrue(passwordItem.$.checkbox.checked); + assertTrue(passwordItem.checked); + assertEquals(password.id, passwordItem.passwordId); + assertEquals( + password.affiliatedDomains[0]!.name, + passwordItem.$.website.textContent!.trim()); + assertEquals( + password.username, passwordItem.$.username.textContent!.trim()); + // Password hidden by default. + assertEquals('password', passwordItem.$.password.type); + + passwordItem.$.showPasswordButton.click(); + assertEquals('text', passwordItem.$.password.type); + assertEquals(password.password, passwordItem.$.password.value); + }); + + test('Move passwords', async function() { + const passwords = [ + createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}), + ]; + passwords.forEach( + item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]); + passwordManager.setRequestCredentialsDetailsResponse(passwords); + passwordManager.data.isOptedInAccountStorage = true; + + syncProxy.accountInfo = { + email: 'test@gmail.com', + avatarImage: 'chrome://image-url/', + }; + syncProxy.syncInfo = {isEligibleForAccountStorage: true}; + + const dialog = document.createElement('move-passwords-dialog'); + dialog.passwords = passwords; + document.body.appendChild(dialog); + await flushTasks(); + + dialog.$.move.click(); + + const ids = await passwordManager.whenCalled('movePasswordsToAccount'); + assertArrayEquals([0, 1, 2], ids); + }); + + test('Move only selected passwords', async function() { + const passwords = [ + createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}), + ]; + passwords.forEach( + item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]); + passwordManager.setRequestCredentialsDetailsResponse(passwords); + passwordManager.data.isOptedInAccountStorage = true; + + syncProxy.accountInfo = { + email: 'test@gmail.com', + avatarImage: 'chrome://image-url/', + }; + syncProxy.syncInfo = {isEligibleForAccountStorage: true}; + + const dialog = document.createElement('move-passwords-dialog'); + dialog.passwords = passwords; + document.body.appendChild(dialog); + await flushTasks(); + + const passwordItems = + dialog.shadowRoot!.querySelectorAll('password-preview-item'); + assertEquals(3, passwordItems.length); + + // Deselect 2nd item. + passwordItems[1]!.$.checkbox.click(); + + dialog.$.move.click(); + + const ids = await passwordManager.whenCalled('movePasswordsToAccount'); + assertArrayEquals([0, 2], ids); + }); + + test('Move dialog not shown when auth fails', async function() { + const password = createPasswordEntry({id: 0, username: 'user1'}); + password.affiliatedDomains = [createAffiliatedDomain('test.com')]; + + const dialog = document.createElement('move-passwords-dialog'); + dialog.passwords = [password]; + document.body.appendChild(dialog); + await flushTasks(); + + assertFalse(dialog.$.dialog.open); + }); + + test('Move button disabled when nothing to move', async function() { + const passwords = [ + createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}), + createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}), + ]; + passwords.forEach( + item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]); + passwordManager.setRequestCredentialsDetailsResponse(passwords); + passwordManager.data.isOptedInAccountStorage = true; + + syncProxy.accountInfo = { + email: 'test@gmail.com', + avatarImage: 'chrome://image-url/', + }; + syncProxy.syncInfo = {isEligibleForAccountStorage: true}; + + const dialog = document.createElement('move-passwords-dialog'); + dialog.passwords = passwords; + document.body.appendChild(dialog); + await flushTasks(); + + const passwordItems = + dialog.shadowRoot!.querySelectorAll('password-preview-item'); + assertEquals(3, passwordItems.length); + passwordItems.forEach(item => item.$.checkbox.click()); + + assertTrue(dialog.$.move.disabled); }); });
diff --git a/chrome/test/data/webui/password_manager/passwords_section_test.ts b/chrome/test/data/webui/password_manager/passwords_section_test.ts index 56855b1..0be928d8 100644 --- a/chrome/test/data/webui/password_manager/passwords_section_test.ts +++ b/chrome/test/data/webui/password_manager/passwords_section_test.ts
@@ -446,9 +446,15 @@ passwordManager.data.isOptedInAccountStorage = true; passwordManager.data.groups = [createCredentialGroup({ name: 'test.com', - credentials: [createPasswordEntry( - {username: 'user', id: 0, inProfileStore: true})], + credentials: [createPasswordEntry({ + username: 'user', + id: 0, + inProfileStore: true, + affiliatedDomains: [createAffiliatedDomain('test.com')], + })], })]; + passwordManager.setRequestCredentialsDetailsResponse( + passwordManager.data.groups[0]!.entries); syncProxy.syncInfo = { isEligibleForAccountStorage: true, };
diff --git a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts index 2b692e6..a9cd260 100644 --- a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts +++ b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts
@@ -56,6 +56,7 @@ 'getPasswordCheckStatus', 'getSavedPasswordList', 'getUrlCollection', + 'movePasswordsToAccount', 'muteInsecureCredential', 'optInForAccountStorage', 'recordPasswordCheckInteraction', @@ -316,4 +317,8 @@ this.methodCalled('isAccountStoreDefault'); return Promise.resolve(this.data.isAccountStorageDefault); } + + movePasswordsToAccount(ids: number[]) { + this.methodCalled('movePasswordsToAccount', ids); + } }
diff --git a/chrome/test/data/webui/password_manager/test_util.ts b/chrome/test/data/webui/password_manager/test_util.ts index 2ac6bb4..cd8f7db7 100644 --- a/chrome/test/data/webui/password_manager/test_util.ts +++ b/chrome/test/data/webui/password_manager/test_util.ts
@@ -31,6 +31,7 @@ inProfileStore?: boolean; isAndroidCredential?: boolean; note?: string; + affiliatedDomains?: chrome.passwordsPrivate.DomainInfo[]; } /** @@ -73,6 +74,7 @@ isAndroidCredential: params.isAndroidCredential || false, note: note, password: params.password || '', + affiliatedDomains: params.affiliatedDomains, }; }
diff --git a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts index 1c9847d8..2658f562 100644 --- a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts +++ b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
@@ -4,6 +4,7 @@ import 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_app.js'; import 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_dialog_app.js'; +import 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_restricted_dialog_app.js'; import 'chrome://privacy-sandbox-dialog/privacy_sandbox_combined_dialog_app.js'; import {PrivacySandboxCombinedDialogAppElement, PrivacySandboxCombinedDialogStep} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_combined_dialog_app.js'; @@ -13,6 +14,7 @@ import {PrivacySandboxDialogMixin} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_mixin.js'; import {PrivacySandboxDialogNoticeStepElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_notice_step'; import {PrivacySandboxNoticeDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_dialog_app.js'; +import {PrivacySandboxNoticeRestrictedDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_restricted_dialog_app.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; @@ -735,6 +737,29 @@ }); }); +suite('PrivacySandboxDialogNoticeRestricted', function() { + let page: PrivacySandboxNoticeRestrictedDialogAppElement; + let browserProxy: TestPrivacySandboxDialogBrowserProxy; + + setup(async function() { + browserProxy = new TestPrivacySandboxDialogBrowserProxy(); + PrivacySandboxDialogBrowserProxy.setInstance(browserProxy); + + document.body.innerHTML = window.trustedTypes!.emptyHTML; + page = + document.createElement('privacy-sandbox-notice-restricted-dialog-app'); + document.body.appendChild(page); + await browserProxy.whenCalled('resizeDialog'); + await browserProxy.whenCalled('showDialog'); + }); + + test('validDialog', async function() { + // Asserting very basic functionality for now. + // TODO(b/277180677): add more tests as functionality is implemented. + assertTrue(!!page.shadowRoot!.querySelector('div')); + }); +}); + suite('PrivacySandboxDialogMixin', function() { const TestElementBase = PrivacySandboxDialogMixin(PolymerElement);
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index bc0a325..e29a69f 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -201,6 +201,10 @@ files += [ "incompatible_applications_page_test.ts" ] } + if (is_chrome_branded) { + files += [ "get_most_chrome_page_test.ts" ] + } + ts_path_mappings = [ # Settings tests should only be importing from one of the URLs below, so # that tests work both in optimize_webui=true/false modes.
diff --git a/chrome/test/data/webui/settings/advanced_page_test.ts b/chrome/test/data/webui/settings/advanced_page_test.ts index 1ff212d..dd31556 100644 --- a/chrome/test/data/webui/settings/advanced_page_test.ts +++ b/chrome/test/data/webui/settings/advanced_page_test.ts
@@ -5,6 +5,9 @@ /** @fileoverview Suite of tests for the Settings advanced page. */ // clang-format off +// <if expr="_google_chrome"> +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +// </if> import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {CrSettingsPrefs, SettingsBasicPageElement, SettingsSectionElement} from 'chrome://settings/settings.js'; import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -17,6 +20,9 @@ let basicPage: SettingsBasicPageElement; suiteSetup(function() { + // <if expr="_google_chrome"> + loadTimeData.overrideValues({showGetTheMostOutOfChromeSection: true}); + // </if> document.body.innerHTML = window.trustedTypes!.emptyHTML; const settingsUi = document.createElement('settings-ui'); document.body.appendChild(settingsUi); @@ -82,6 +88,9 @@ test('advanced pages', function() { const sections = ['a11y', 'languages', 'downloads', 'reset']; + // <if expr="_google_chrome"> + sections.push('getMostChrome'); + // </if> for (let i = 0; i < sections.length; i++) { const section = getSection(basicPage, sections[i]!); assertTrue(!!section);
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index b037f55..ff8713f 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1005,6 +1005,10 @@ registerTest('MetricsReporting', 'metrics_reporting_tests.js'); GEN('#endif'); +GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)'); +registerTest('GetMostChromePage', 'get_most_chrome_page_test.js'); +GEN('#endif'); + function registerTest(testName, module, caseName) { const className = `CrSettings${testName}Test`; this[className] = class extends CrSettingsBrowserTest {
diff --git a/chrome/test/data/webui/settings/get_most_chrome_page_test.ts b/chrome/test/data/webui/settings/get_most_chrome_page_test.ts new file mode 100644 index 0000000..68cafbb --- /dev/null +++ b/chrome/test/data/webui/settings/get_most_chrome_page_test.ts
@@ -0,0 +1,26 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://settings/lazy_load.js'; + +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {SettingsGetMostChromePageElement} from 'chrome://settings/lazy_load.js'; +import {assertTrue} from 'chrome://webui-test/chai_assert.js'; + +/** @fileoverview Suite of tests for get_most_chrome_page. */ +suite('GetMostChromePage', function() { + let testElement: SettingsGetMostChromePageElement; + + setup(function() { + document.body.innerHTML = window.trustedTypes!.emptyHTML; + testElement = document.createElement('settings-get-most-chrome-page'); + document.body.appendChild(testElement); + flush(); + }); + + test('Basic', function() { + assertTrue(!!testElement); + // TODO(crbug.com/143278): Expand this test as the element gets implemented. + }); +});
diff --git a/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc b/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc index d84878e..38616e7 100644 --- a/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc +++ b/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc
@@ -861,12 +861,40 @@ base::IgnoreResult(&FakeShillServiceClient::SetServiceProperty), weak_ptr_factory_.GetWeakPtr(), service_path, shill::kErrorProperty, base::Value(shill::kErrorBadPassphrase))); - } else { - // Set Online. - VLOG(1) << "Setting state to Online " << service_path; - SetServiceProperty(service_path, shill::kStateProperty, - base::Value(shill::kStateOnline)); + return; } + + // Set other services of the same type that were previously not "idle" to + // "idle". + const std::string* service_type = + service_properties->FindString(shill::kTypeProperty); + for (const auto service_pair : stub_services_) { + const auto& other_service_path = service_pair.first; + if (other_service_path == service_path) { + continue; + } + + const base::Value::Dict& other_service_properties = + service_pair.second.GetDict(); + const std::string* other_service_type = + other_service_properties.FindString(shill::kTypeProperty); + if (!service_type || !other_service_type || + *other_service_type != *service_type) { + continue; + } + const std::string* other_service_state = + other_service_properties.FindString(shill::kStateProperty); + if (!other_service_state || *other_service_type == shill::kStateIdle) { + continue; + } + SetServiceProperty(other_service_path, shill::kStateProperty, + base::Value(shill::kStateIdle)); + } + + // Set the connected service to "online". + VLOG(1) << "Setting state to Online " << service_path; + SetServiceProperty(service_path, shill::kStateProperty, + base::Value(shill::kStateOnline)); } void FakeShillServiceClient::SetDefaultFakeTrafficCounters() {
diff --git a/chromeos/ash/components/nearby/presence/credentials/BUILD.gn b/chromeos/ash/components/nearby/presence/credentials/BUILD.gn index 7901448..03974ba 100644 --- a/chromeos/ash/components/nearby/presence/credentials/BUILD.gn +++ b/chromeos/ash/components/nearby/presence/credentials/BUILD.gn
@@ -12,14 +12,20 @@ "local_device_data_provider.h", "local_device_data_provider_impl.cc", "local_device_data_provider_impl.h", + "nearby_presence_credential_manager.h", + "nearby_presence_credential_manager_impl.cc", + "nearby_presence_credential_manager_impl.h", "nearby_presence_server_client.h", "nearby_presence_server_client_impl.cc", "nearby_presence_server_client_impl.h", + "prefs.cc", + "prefs.h", "proto_conversions.cc", "proto_conversions.h", ] deps = [ + "//base", "//chromeos/ash/components/nearby/common/client", "//chromeos/ash/components/nearby/presence/proto", "//components/prefs", @@ -42,6 +48,7 @@ sources = [ "local_device_data_provider_impl_unittest.cc", + "nearby_presence_credential_manager_impl_unittest.cc", "nearby_presence_server_client_impl_unittest.cc", "proto_conversions_unittest.cc", ]
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc index decc3b73..912f40c 100644 --- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc +++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc
@@ -4,13 +4,27 @@ #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h" +#include "base/rand_util.h" +#include "chromeos/ash/components/nearby/presence/credentials/prefs.h" #include "chromeos/ash/components/nearby/presence/credentials/proto_conversions.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "google_apis/gaia/gaia_auth_util.h" namespace { -constexpr char kPlaceHolderString[] = "0123456789"; +// Using the alphanumeric characters below, this provides 36^10 unique device +// IDs. Note that the uniqueness requirement is not global; the IDs are only +// used to differentiate between devices associated with a single GAIA account. +const size_t kDeviceIdLength = 10; + +// Possible characters used in a randomly generated device ID. +constexpr std::array<char, 36> kAlphaNumericChars = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + +const std::string& kPlaceHolderString = "0123456789"; } // namespace @@ -18,9 +32,10 @@ LocalDeviceDataProviderImpl::LocalDeviceDataProviderImpl( PrefService* pref_service, - signin::IdentityManager* identity_manager) { - CHECK(identity_manager); - CHECK(pref_service); + signin::IdentityManager* identity_manager) + : pref_service_(pref_service), identity_manager_(identity_manager) { + CHECK(identity_manager_); + CHECK(pref_service_); } LocalDeviceDataProviderImpl::~LocalDeviceDataProviderImpl() = default; @@ -38,9 +53,22 @@ } std::string LocalDeviceDataProviderImpl::GetDeviceId() { - // TODO (b/276307539): Implement `GetDeviceId`, this - // default implementation is to get the skeleton class to compile. - return kPlaceHolderString; + std::string id = + pref_service_->GetString(prefs::kNearbyPresenceDeviceIdPrefName); + + // If the local device ID has already been generated, then return it. If this + // this is the first time `GetDeviceID` has been called, then generate the + // local device ID, persist it, and return it to callers. + if (!id.empty()) { + return id; + } + + for (size_t i = 0; i < kDeviceIdLength; ++i) { + id += kAlphaNumericChars[base::RandGenerator(kAlphaNumericChars.size())]; + } + + pref_service_->SetString(prefs::kNearbyPresenceDeviceIdPrefName, id); + return id; } ::nearby::internal::Metadata LocalDeviceDataProviderImpl::GetDeviceMetadata() { @@ -56,9 +84,10 @@ } std::string LocalDeviceDataProviderImpl::GetAccountName() { - // TODO (b/276307539): Implement `GetAccountName`, this - // default implementation is to get the skeleton class to compile. - return kPlaceHolderString; + const std::string& email = + identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) + .email; + return gaia::CanonicalizeEmail(email); } void LocalDeviceDataProviderImpl::SaveUserRegistrationInfo(
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h index 4f63be9..623d40c43 100644 --- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h +++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h
@@ -5,6 +5,7 @@ #ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_LOCAL_DEVICE_DATA_PROVIDER_IMPL_H_ #define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_LOCAL_DEVICE_DATA_PROVIDER_IMPL_H_ +#include "base/memory/raw_ptr.h" #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider.h" #include "third_party/nearby/internal/proto/credential.pb.h" #include "third_party/nearby/internal/proto/metadata.pb.h" @@ -38,6 +39,10 @@ std::string GetAccountName() override; void SaveUserRegistrationInfo(const std::string& display_name, const std::string& image_url) override; + + private: + PrefService* pref_service_ = nullptr; + const raw_ptr<signin::IdentityManager> identity_manager_; }; } // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc index 445410a9..d0c75d7 100644 --- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc +++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc
@@ -1,26 +1,43 @@ // Copyright 2023 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <string> #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h" #include "base/test/gtest_util.h" #include "base/test/task_environment.h" #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider.h" +#include "chromeos/ash/components/nearby/presence/credentials/prefs.h" #include "components/prefs/testing_pref_service.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "components/signin/public/identity_manager/identity_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { + +const std::string kUserEmail = "test.tester@gmail.com"; +const std::string kCanocalizedUserEmail = "testtester@gmail.com"; + +} // namespace + namespace ash::nearby::presence { class LocalDeviceDataProviderImplTest : public testing::Test { public: void SetUp() override { + RegisterNearbyPresenceCredentialPrefs(pref_service_.registry()); + identity_test_env_.MakePrimaryAccountAvailable( + kUserEmail, signin::ConsentLevel::kSignin); + } + + void CreateDataProvider() { local_device_data_provider_ = std::make_unique<LocalDeviceDataProviderImpl>( &pref_service_, identity_test_env_.identity_manager()); } + void DestroyDataProvider() { local_device_data_provider_.reset(); } + protected: base::test::TaskEnvironment task_environment_; TestingPrefServiceSimple pref_service_; @@ -28,8 +45,27 @@ std::unique_ptr<LocalDeviceDataProvider> local_device_data_provider_; }; -TEST_F(LocalDeviceDataProviderImplTest, ObjectConstructionSuccess) { - ASSERT_TRUE(local_device_data_provider_); +TEST_F(LocalDeviceDataProviderImplTest, DeviceId) { + CreateDataProvider(); + + // A 10-character alphanumeric ID is automatically generated if one doesn't + // already exist. + std::string id = local_device_data_provider_->GetDeviceId(); + EXPECT_EQ(10u, id.size()); + for (const char c : id) { + EXPECT_TRUE(std::isalnum(c)); + } + + // The ID is persisted. + DestroyDataProvider(); + CreateDataProvider(); + EXPECT_EQ(id, local_device_data_provider_->GetDeviceId()); +} + +TEST_F(LocalDeviceDataProviderImplTest, AccountName) { + CreateDataProvider(); + EXPECT_EQ(kCanocalizedUserEmail, + local_device_data_provider_->GetAccountName()); } } // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h new file mode 100644 index 0000000..674b0ae --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h
@@ -0,0 +1,40 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_ +#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_ + +#include "base/functional/callback_forward.h" + +namespace ash::nearby::presence { + +// The entry point for the credential web integration component. This class is +// responsible for communicating with the Nearby Presence library to fetch, +// save, and generate credentials. Exposed API's provide callers with +// information about whether the user's local device has been registered with +// the Nearby Presence server and the ability to trigger an immediate credential +// upload/download. In addition,this class is responsible for daily credential +// upload/downloads with the server. +class NearbyPresenceCredentialManager { + public: + NearbyPresenceCredentialManager() = default; + virtual ~NearbyPresenceCredentialManager() = default; + + // Returns whether this is this device has been registered with the server + // for NP before. + virtual bool IsLocalDeviceRegistered() = 0; + + // Kicks off the first time initialization flow for registering presence + // with the Nearby Presence server. Returns the success of registration. + virtual void RegisterPresence( + base::OnceCallback<void(bool)> on_registered_callback) = 0; + + // Schedules an immediate task to upload/download credentials to/from the + // server. + virtual void UpdateCredentials() = 0; +}; + +} // namespace ash::nearby::presence + +#endif // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc new file mode 100644 index 0000000..4d1e8beb --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc
@@ -0,0 +1,37 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h" + +#include "base/functional/callback.h" +#include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" + +namespace ash::nearby::presence { + +NearbyPresenceCredentialManagerImpl::NearbyPresenceCredentialManagerImpl( + PrefService* pref_service, + signin::IdentityManager* identity_manager) { + // TODO (b/276307539): Add mojo remote as a parameter once implemented. +} + +NearbyPresenceCredentialManagerImpl::~NearbyPresenceCredentialManagerImpl() = + default; + +bool NearbyPresenceCredentialManagerImpl::IsLocalDeviceRegistered() { + // TODO (b/276307539): Implement `IsLocalDeviceRegistered`, this + // default implementation is to get the skeleton class to compile. + return false; +} + +void NearbyPresenceCredentialManagerImpl::RegisterPresence( + base::OnceCallback<void(bool)> on_registered_callback) { + // TODO (b/276307539): Implement `RegisterPresence`. +} + +void NearbyPresenceCredentialManagerImpl::UpdateCredentials() { + // TODO (b/276307539): Implement `UpdateCredentials`. +} + +} // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h new file mode 100644 index 0000000..d44c47ae --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h
@@ -0,0 +1,40 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_ +#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_ + +#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h" + +class PrefService; + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace ash::nearby::presence { + +class NearbyPresenceCredentialManagerImpl + : public NearbyPresenceCredentialManager { + public: + NearbyPresenceCredentialManagerImpl( + PrefService* pref_service, + signin::IdentityManager* identity_manager); + ~NearbyPresenceCredentialManagerImpl() override; + + NearbyPresenceCredentialManagerImpl(NearbyPresenceCredentialManagerImpl&) = + delete; + NearbyPresenceCredentialManagerImpl& operator=( + NearbyPresenceCredentialManagerImpl&) = delete; + + // NearbyPresenceCredentialManager: + bool IsLocalDeviceRegistered() override; + void RegisterPresence( + base::OnceCallback<void(bool)> on_registered_callback) override; + void UpdateCredentials() override; +}; + +} // namespace ash::nearby::presence + +#endif // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc new file mode 100644 index 0000000..9468e65f --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc
@@ -0,0 +1,34 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h" +#include "base/test/gtest_util.h" +#include "base/test/task_environment.h" +#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h" +#include "components/prefs/testing_pref_service.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash::nearby::presence { + +class NearbyPresenceCredentialManagerImplTest : public testing::Test { + protected: + void SetUp() override { + credential_manager_ = std::make_unique<NearbyPresenceCredentialManagerImpl>( + &pref_service_, identity_test_env_.identity_manager()); + } + + protected: + base::test::TaskEnvironment task_environment_; + TestingPrefServiceSimple pref_service_; + signin::IdentityTestEnvironment identity_test_env_; + std::unique_ptr<NearbyPresenceCredentialManager> credential_manager_; +}; + +TEST_F(NearbyPresenceCredentialManagerImplTest, ObjectConstructionSuccess) { + ASSERT_TRUE(credential_manager_); +} + +} // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/prefs.cc b/chromeos/ash/components/nearby/presence/credentials/prefs.cc new file mode 100644 index 0000000..3841be65 --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/prefs.cc
@@ -0,0 +1,25 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/ash/components/nearby/presence/credentials/prefs.h" + +#include "components/prefs/pref_registry.h" +#include "components/prefs/pref_registry_simple.h" + +namespace ash::nearby::presence { + +namespace prefs { + +const char kNearbyPresenceDeviceIdPrefName[] = + "nearby_presence.local_device_id"; + +} // namespace prefs + +void RegisterNearbyPresenceCredentialPrefs(PrefRegistrySimple* registry) { + // These prefs are not synced across devices on purpose. + registry->RegisterStringPref(prefs::kNearbyPresenceDeviceIdPrefName, + /*default_value=*/std::string()); +} + +} // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/prefs.h b/chromeos/ash/components/nearby/presence/credentials/prefs.h new file mode 100644 index 0000000..2d5328fa --- /dev/null +++ b/chromeos/ash/components/nearby/presence/credentials/prefs.h
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_ +#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_ + +class PrefRegistrySimple; + +namespace ash::nearby::presence { + +namespace prefs { + +extern const char kNearbyPresenceDeviceIdPrefName[]; + +} // namespace prefs + +void RegisterNearbyPresenceCredentialPrefs(PrefRegistrySimple* registry); + +} // namespace ash::nearby::presence + +#endif // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_
diff --git a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc index f857da29..65e936e8 100644 --- a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc +++ b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc
@@ -9,8 +9,7 @@ #include "chromeos/ash/components/phonehub/notification.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { -namespace phonehub { +namespace ash::phonehub { namespace { @@ -128,12 +127,16 @@ TEST_F(AppStreamLauncherDataModelTest, SetAppsList) { std::vector<Notification::AppMetadata> apps_list; - apps_list.emplace_back(Notification::AppMetadata( - u"GPay", "com.fakeapp1", gfx::Image(), absl::nullopt, true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - apps_list.emplace_back(Notification::AppMetadata( - u"Gboard", "com.fakeapp2", gfx::Image(), absl::nullopt, true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); + apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); SetAppList(apps_list); EXPECT_TRUE(IsObserverAppListChanged()); EXPECT_EQ(GetAppsList()->size(), 2u); @@ -146,26 +149,26 @@ TEST_F(AppStreamLauncherDataModelTest, AddAppToList) { std::vector<Notification::AppMetadata> apps_list; - apps_list.emplace_back(Notification::AppMetadata( - u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, - proto::AppStreamabilityStatus::STREAMABLE)); - apps_list.emplace_back(Notification::AppMetadata( - u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, - proto::AppStreamabilityStatus::STREAMABLE)); + apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); + apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); SetAppList(apps_list); AddAppToList(Notification::AppMetadata( u"added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt, - /*icon_is_monochrome*/ true, /*user_id=*/1, + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); AddAppToList(Notification::AppMetadata( u"a_added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt, - /*icon_is_monochrome*/ true, /*user_id=*/1, + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); EXPECT_TRUE(IsObserverAppListChanged()); EXPECT_EQ(GetAppsList()->size(), 4u); @@ -182,16 +185,16 @@ TEST_F(AppStreamLauncherDataModelTest, RemoveAppFromList) { std::vector<Notification::AppMetadata> apps_list; - apps_list.emplace_back(Notification::AppMetadata( - u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, - proto::AppStreamabilityStatus::STREAMABLE)); - apps_list.emplace_back(Notification::AppMetadata( - u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, - proto::AppStreamabilityStatus::STREAMABLE)); + apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); + apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, /*user_id=*/1, + proto::AppStreamabilityStatus::STREAMABLE); SetAppList(apps_list); auto app_to_remove = proto::App(); app_to_remove.set_package_name("com.fakeapp1"); @@ -209,5 +212,5 @@ EXPECT_EQ(GetLauncherHeight(), 400); EXPECT_EQ(GetLauncherWidth(), 300); } -} // namespace phonehub -} // namespace ash + +} // namespace ash::phonehub
diff --git a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc index 17f0dd6..e4a857f9f5 100644 --- a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc +++ b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
@@ -353,18 +353,18 @@ TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back(Notification::AppMetadata( - u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back(Notification::AppMetadata( - u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(u"App1", "com.fakeapp1", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); + streamable_apps.emplace_back(u"App2", "com.fakeapp2", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); handler().SetStreamableApps(streamable_apps); @@ -382,18 +382,18 @@ TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps_ClearsPreviousState) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back(Notification::AppMetadata( - u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back(Notification::AppMetadata( - u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(u"App1", "com.fakeapp1", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); + streamable_apps.emplace_back(u"App2", "com.fakeapp2", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); handler().SetStreamableApps(streamable_apps); @@ -408,12 +408,12 @@ .first.package_name); std::vector<Notification::AppMetadata> streamable_apps2; - streamable_apps2.emplace_back(Notification::AppMetadata( - u"App3", "com.fakeapp3", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps2.emplace_back(u"App3", "com.fakeapp3", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); handler().SetStreamableApps(streamable_apps2); @@ -434,18 +434,18 @@ TEST_F(RecentAppsInteractionHandlerTest, RemoveStreamableApp) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back(Notification::AppMetadata( - u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/absl::nullopt, - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back(Notification::AppMetadata( - u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), - /*monochrome_icon_mask=*/gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(u"App1", "com.fakeapp1", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); + streamable_apps.emplace_back(u"App2", "com.fakeapp2", + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE); handler().SetStreamableApps(streamable_apps);
diff --git a/chromeos/ash/components/proximity_auth/metrics.cc b/chromeos/ash/components/proximity_auth/metrics.cc index b942bc7..a819dc1 100644 --- a/chromeos/ash/components/proximity_auth/metrics.cc +++ b/chromeos/ash/components/proximity_auth/metrics.cc
@@ -9,7 +9,6 @@ #include <algorithm> #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/hash/md5.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -50,7 +49,7 @@ void RecordAuthProximityRollingRssi(int rolling_rssi) { if (rolling_rssi != kUnknownProximityValue) - rolling_rssi = base::clamp(rolling_rssi, -100, 50); + rolling_rssi = std::clamp(rolling_rssi, -100, 50); base::UmaHistogramSparse("EasyUnlock.AuthProximity.RollingRssi", rolling_rssi);
diff --git a/chromeos/ash/components/tether/device_status_util.cc b/chromeos/ash/components/tether/device_status_util.cc index d440ef86..ffe72b6 100644 --- a/chromeos/ash/components/tether/device_status_util.cc +++ b/chromeos/ash/components/tether/device_status_util.cc
@@ -4,7 +4,7 @@ #include "chromeos/ash/components/tether/device_status_util.h" -#include "base/cxx17_backports.h" +#include <algorithm> namespace ash { @@ -31,7 +31,7 @@ if (battery_percentage_out) { *battery_percentage_out = status.has_battery_percentage() - ? base::clamp(status.battery_percentage(), 0, 100) + ? std::clamp(status.battery_percentage(), 0, 100) : 100; } if (signal_strength_out) { @@ -42,8 +42,8 @@ constexpr int32_t kConversionFactor = 100 / 4; *signal_strength_out = status.has_connection_strength() - ? base::clamp(kConversionFactor * status.connection_strength(), 0, - 100) + ? std::clamp(kConversionFactor * status.connection_strength(), 0, + 100) : 100; } }
diff --git a/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc b/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc index a8b35977..49179e7e 100644 --- a/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc +++ b/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc
@@ -188,6 +188,10 @@ FullyInitializedAssistantState& assistant_state() { return assistant_state_; } + void SetAssistantStateContext(bool enabled) { + assistant_state_.SetContextEnabled(enabled); + } + FakeServiceContext* fake_service_context() { return service_context_.get(); } base::test::TaskEnvironment& task_environment() { return task_environment_; } @@ -759,4 +763,18 @@ EXPECT_TRUE(mojom_service_controller().dark_mode_enabled().value()); } +TEST_F(AssistantManagerServiceImplTest, ShouldNotCrashRunningAfterStopped) { + Start(); + SetAssistantStateContext(/*enabled=*/false); + WaitForState(AssistantManagerService::STARTED); + + // http://crbug.com/1414264: calling Stop() before Running is set, should not + // crash. + assistant_manager_service()->Stop(); + WaitForState(AssistantManagerService::STOPPING); + + mojom_service_controller().SetState(ServiceState::kRunning); + WaitForState(AssistantManagerService::RUNNING); +} + } // namespace ash::assistant
diff --git a/chromeos/ash/services/assistant/media_host.cc b/chromeos/ash/services/assistant/media_host.cc index f4e8310..8ad3168 100644 --- a/chromeos/ash/services/assistant/media_host.cc +++ b/chromeos/ash/services/assistant/media_host.cc
@@ -237,11 +237,17 @@ } void MediaHost::ResumeInternalMediaPlayer() { - libassistant_media_controller().ResumeInternalMediaPlayer(); + if (!libassistant_media_controller_) { + return; + } + libassistant_media_controller_->ResumeInternalMediaPlayer(); } void MediaHost::PauseInternalMediaPlayer() { - libassistant_media_controller().PauseInternalMediaPlayer(); + if (!libassistant_media_controller_) { + return; + } + libassistant_media_controller_->PauseInternalMediaPlayer(); } void MediaHost::SetRelatedInfoEnabled(bool enable) { @@ -253,13 +259,6 @@ } } -libassistant::mojom::MediaController& -MediaHost::libassistant_media_controller() { - // Initialize must be called first. - DCHECK(libassistant_media_controller_); - return *libassistant_media_controller_; -} - void MediaHost::UpdateMediaState( const base::UnguessableToken& media_session_id, libassistant::mojom::MediaStatePtr media_state) { @@ -271,12 +270,18 @@ return; } - libassistant_media_controller().SetExternalPlaybackState( + if (!libassistant_media_controller_) { + return; + } + libassistant_media_controller_->SetExternalPlaybackState( std::move(media_state)); } void MediaHost::ResetMediaState() { - libassistant_media_controller().SetExternalPlaybackState( + if (!libassistant_media_controller_) { + return; + } + libassistant_media_controller_->SetExternalPlaybackState( libassistant::mojom::MediaState::New()); }
diff --git a/chromeos/ash/services/assistant/media_host.h b/chromeos/ash/services/assistant/media_host.h index 02faae02..7c84023 100644 --- a/chromeos/ash/services/assistant/media_host.h +++ b/chromeos/ash/services/assistant/media_host.h
@@ -56,8 +56,6 @@ class LibassistantMediaDelegate; class ChromeosMediaStateObserver; - libassistant::mojom::MediaController& libassistant_media_controller(); - void UpdateMediaState(const base::UnguessableToken& media_session_id, libassistant::mojom::MediaStatePtr media_state); void ResetMediaState();
diff --git a/chromeos/ash/services/assistant/test_support/fake_service_controller.cc b/chromeos/ash/services/assistant/test_support/fake_service_controller.cc index c1f22f8..9047f8fc 100644 --- a/chromeos/ash/services/assistant/test_support/fake_service_controller.cc +++ b/chromeos/ash/services/assistant/test_support/fake_service_controller.cc
@@ -92,7 +92,13 @@ } void FakeServiceController::Stop() { - SetState(State::kStopped); + // Post a delayed task to make it possible to set other state between + // kStopping and kStopped. + base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&FakeServiceController::SetState, + weak_factory_.GetWeakPtr(), State::kStopped), + base::Milliseconds(1)); } void FakeServiceController::ResetAllDataAndStop() {
diff --git a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc index 04f2c30..1df9168 100644 --- a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc +++ b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc
@@ -17,6 +17,10 @@ observer.OnAssistantSettingsEnabled(settings_enabled_.value()); } +void FullyInitializedAssistantState::SetContextEnabled(bool enabled) { + context_enabled_ = enabled; +} + void FullyInitializedAssistantState::InitializeAllValues() { settings_enabled_ = true; consent_status_ = prefs::ConsentStatus::kActivityControlAccepted;
diff --git a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h index 0fb499bf..c14400e 100644 --- a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h +++ b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h
@@ -24,6 +24,8 @@ void SetAssistantEnabled(bool enabled); + void SetContextEnabled(bool enabled); + private: void InitializeAllValues(); };
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc index e504a835..c9ca8de 100644 --- a/components/autofill/core/browser/autofill_test_utils.cc +++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -569,9 +569,16 @@ } } +std::string GetStrippedValue(const char* value) { + std::u16string stripped_value; + base::RemoveChars(base::UTF8ToUTF16(value), base::kWhitespaceUTF16, + &stripped_value); + return base::UTF16ToUTF8(stripped_value); +} + IBAN GetIBAN() { IBAN iban(base::GenerateUuid()); - iban.set_value(u"DE91 1000 0000 0123 4567 89"); + iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); iban.set_nickname(u"Nickname for Iban"); return iban; }
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h index e48976b..72b9688 100644 --- a/components/autofill/core/browser/autofill_test_utils.h +++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -171,6 +171,11 @@ bool ignore_status = false); const char kEmptyOrigin[] = ""; +// A valid France IBAN number. +const char kIbanValue[] = "FR76 3000 6000 0112 3456 7890 189"; +// Two valid Switzerland IBAN numbers. +const char kIbanValue_1[] = "CH56 0483 5012 3456 7800 9"; +const char kIbanValue_2[] = "CH93 0076 2011 6238 5295 7"; // The following methods return a PrefService that can be used for // Autofill-related testing in contexts where the PrefService would otherwise @@ -259,9 +264,8 @@ // Populates `form_data` with data corresponding to an IBAN form (a form with a // single IBAN field). Note that this actually appends fields to the form data, // which can be useful for building up more complex test forms. -void CreateTestIbanFormData( - FormData* form_data, - const char* value = "FR76 3000 6000 0112 3456 7890 189"); +void CreateTestIbanFormData(FormData* form_data, + const char* value = kIbanValue); // Strips those members from |form| and |field| that are not serialized via // mojo, i.e., resets them to `{}`. @@ -300,6 +304,10 @@ AutofillProfile& profile, autofill_metrics::AutofillProfileSourceCategory category); +// Returns the stripped (without characters representing whitespace) value of +// the given `value`. +std::string GetStrippedValue(const char* value); + // Returns an IBAN full of dummy info. IBAN GetIBAN();
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index 3c17170..d88d377 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -115,12 +115,6 @@ constexpr char kDefaultCreditCardExpMonth[] = "01"; constexpr char kDefaultCreditCardExpYear[] = "2999"; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -// Define default value for Iban. -constexpr char kIbanValue[] = "FR76 3000 6000 0112 3456 7890 189"; -constexpr char kIbanValueWithoutWhitespaces[] = "FR7630006000011234567890189"; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // For a given ServerFieldType |type| returns a pair of field name and label // that should be parsed into this type by our field type parsers. std::pair<std::string, std::string> GetLabelAndNameForType( @@ -3198,7 +3192,7 @@ TEST_P(FormDataImporterTest, ExtractFormData_ImportIbanRecordType_LocalIban) { IBAN iban; - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); personal_data_manager_->AddIBAN(iban); WaitForOnPersonalDataChanged(); @@ -4390,7 +4384,7 @@ TEST_P(FormDataImporterTest, ExtractFormData_ProcessIBANImportCandidate_LocalIban) { IBAN iban; - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); personal_data_manager_->AddIBAN(iban); WaitForOnPersonalDataChanged(); @@ -4415,7 +4409,8 @@ iban_save_strike_database.AddStrikes( iban_save_strike_database.GetMaxStrikesLimit(), - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + IBANSaveManager::GetPartialIbanHashString( + test::GetStrippedValue(test::kIbanValue))); // Simulate a form submission with a new IBAN. FormData form;
diff --git a/components/autofill/core/browser/iban_manager_unittest.cc b/components/autofill/core/browser/iban_manager_unittest.cc index eca1d277..1eb46cb 100644 --- a/components/autofill/core/browser/iban_manager_unittest.cc +++ b/components/autofill/core/browser/iban_manager_unittest.cc
@@ -29,14 +29,8 @@ namespace autofill { -// Valid Ireland IBAN number. -constexpr char16_t kIbanValue_0[] = u"FR76 3000 6000 0112 3456 7890 189"; -// Two valid Switzerland IBAN numbers. -constexpr char16_t kIbanValue_1[] = u"CH56 0483 5012 3456 7800 9"; -constexpr char16_t kIbanValue_2[] = u"CH93 0076 2011 6238 5295 7"; - -constexpr char16_t kNickname_0[] = u"Nickname 0"; -constexpr char16_t kNickname_1[] = u"Nickname 1"; +constexpr char kNickname_0[] = "Nickname 0"; +constexpr char kNickname_1[] = "Nickname 1"; namespace { @@ -91,12 +85,12 @@ } // Sets up the TestPersonalDataManager with an IBAN. - IBAN SetUpIBAN(base::StringPiece16 value, base::StringPiece16 nickname) { + IBAN SetUpIBAN(base::StringPiece value, base::StringPiece nickname) { IBAN iban; std::string guid = base::GenerateUuid(); iban.set_guid(guid); - iban.set_value(std::u16string(value)); - iban.set_nickname(std::u16string(nickname)); + iban.set_value(base::UTF8ToUTF16(std::string(value))); + iban.set_nickname(base::UTF8ToUTF16(std::string(nickname))); personal_data_manager_.AddIBANForTest(std::make_unique<IBAN>(iban)); return iban; } @@ -117,8 +111,8 @@ // Sets up the TestPersonalDataManager with an IBAN and corresponding // suggestion. - Suggestion SetUpIBANAndSuggestion(base::StringPiece16 value, - base::StringPiece16 nickname) { + Suggestion SetUpIBANAndSuggestion(base::StringPiece value, + base::StringPiece nickname) { IBAN iban = SetUpIBAN(value, nickname); Suggestion iban_suggestion(iban.GetIdentifierStringForAutofillDisplay()); iban_suggestion.frontend_id = POPUP_ITEM_ID_IBAN_ENTRY; @@ -157,9 +151,9 @@ TEST_F(IBANManagerTest, ShowsIBANSuggestions) { Suggestion iban_suggestion_0 = - SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0); Suggestion iban_suggestion_1 = - SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1); + SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1); AutofillField test_field; SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); @@ -185,8 +179,8 @@ TEST_F(IBANManagerTest, PaymentsAutofillEnabledPrefOff_NoIbanSuggestionsShown) { personal_data_manager_.SetAutofillCreditCardEnabled(false); - SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0); - SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1); + SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1); AutofillField test_field; SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); @@ -203,7 +197,7 @@ TEST_F(IBANManagerTest, IBANSuggestions_SeparatorAndFooter) { Suggestion iban_suggestion_0 = - SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0); Suggestion iban_suggestion_1 = SetUpSeparator(); Suggestion iban_suggestion_2 = SetUpFooterManagePaymentMethods(); @@ -233,12 +227,12 @@ TEST_F(IBANManagerTest, ShowsIBANSuggestions_NoSuggestion) { Suggestion iban_suggestion_0 = - SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0); Suggestion iban_suggestion_1 = - SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1); + SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1); AutofillField test_field; - test_field.value = std::u16string(kIbanValue_0); + test_field.value = base::UTF8ToUTF16(std::string(test::kIbanValue)); SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); // Verify that `OnSuggestionsReturned` handler is not triggered any IBAN-based @@ -256,9 +250,9 @@ TEST_F(IBANManagerTest, ShowsIBANSuggestions_OnlyPrefixMatch) { Suggestion iban_suggestion_0 = - SetUpIBANAndSuggestion(kIbanValue_1, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_0); Suggestion iban_suggestion_1 = - SetUpIBANAndSuggestion(kIbanValue_2, kNickname_1); + SetUpIBANAndSuggestion(test::kIbanValue_2, kNickname_1); Suggestion iban_suggestion_2 = SetUpSeparator(); Suggestion iban_suggestion_3 = SetUpFooterManagePaymentMethods(); @@ -327,7 +321,7 @@ } TEST_F(IBANManagerTest, DoesNotShowIBANsForBlockedWebsite) { - SetUpIBAN(kIbanValue_0, kNickname_0); + SetUpIBAN(test::kIbanValue, kNickname_0); AutofillField test_field; SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); @@ -351,7 +345,7 @@ // suggestions cannot and will not be blocked. TEST_F(IBANManagerTest, ShowsIBANSuggestions_OptimizationGuideNotPresent) { Suggestion iban_suggestion_0 = - SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0); + SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0); AutofillField test_field; SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); @@ -377,10 +371,10 @@ } TEST_F(IBANManagerTest, NotIbanFieldFocused_NoSuggestionsShown) { - SetUpIBAN(kIbanValue_0, kNickname_0); + SetUpIBAN(test::kIbanValue, kNickname_0); AutofillField test_field; - test_field.value = std::u16string(kIbanValue_0); + test_field.value = base::UTF8ToUTF16(std::string(test::kIbanValue)); // Set the field type to any type than "IBAN_VALUE". SuggestionsContext context = GetIbanFocusedSuggestionsContext( test_field, CREDIT_CARD_VERIFICATION_CODE); @@ -400,7 +394,7 @@ // logged correctly. TEST_F(IBANManagerTest, Metrics_SuggestionsShown) { base::HistogramTester histogram_tester; - SetUpIBAN(kIbanValue_0, kNickname_0); + SetUpIBAN(test::kIbanValue, kNickname_0); AutofillField test_field; test_field.unique_renderer_id = test::MakeFieldRendererId(); @@ -429,9 +423,9 @@ // are logged correctly. TEST_F(IBANManagerTest, Metrics_SuggestionSelected) { base::HistogramTester histogram_tester; - SetUpIBAN(kIbanValue_0, kNickname_0); - SetUpIBAN(kIbanValue_1, kNickname_1); - SetUpIBAN(kIbanValue_2, u""); + SetUpIBAN(test::kIbanValue, kNickname_0); + SetUpIBAN(test::kIbanValue_1, kNickname_1); + SetUpIBAN(test::kIbanValue_2, ""); AutofillField test_field; test_field.unique_renderer_id = test::MakeFieldRendererId(); @@ -465,8 +459,8 @@ TEST_F(IBANManagerTest, Metrics_NoSuggestionShown) { base::HistogramTester histogram_tester; - SetUpIBAN(kIbanValue_0, kNickname_0); - SetUpIBAN(kIbanValue_1, kNickname_1); + SetUpIBAN(test::kIbanValue, kNickname_0); + SetUpIBAN(test::kIbanValue_1, kNickname_1); AutofillField test_field; // Input a prefix that does not have any matching IBAN value so that no IBAN // suggestions will be shown.
diff --git a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc index bcb1e0b..87a82517 100644 --- a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
@@ -19,11 +19,6 @@ namespace autofill { -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -constexpr char kIbanValue[] = "DE91 1000 0000 0123 4567 89"; -constexpr char kIbanValueWithoutWhitespaces[] = "DE91100000000123456789"; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - class IBANSaveManagerTest : public testing::Test { public: IBANSaveManagerTest() { @@ -67,7 +62,7 @@ #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) TEST_F(IBANSaveManagerTest, AttemptToOfferIBANLocalSave_ValidIBAN) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); } @@ -75,14 +70,14 @@ TEST_F(IBANSaveManagerTest, AttemptToOfferIBANLocalSave_IsOffTheRecord) { personal_data().set_is_off_the_record_for_testing(true); IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); } TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Accepted) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); @@ -95,12 +90,12 @@ EXPECT_EQ(ibans.size(), 1U); EXPECT_EQ(ibans[0]->nickname(), u"My teacher's IBAN"); EXPECT_EQ(ibans[0]->value(), - base::UTF8ToUTF16(std::string(kIbanValueWithoutWhitespaces))); + base::UTF8ToUTF16(test::GetStrippedValue(test::kIbanValue))); } TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Declined) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(iban_save_manager_->AttemptToOfferIBANLocalSave(iban)); EXPECT_TRUE(personal_data().GetLocalIBANs().empty()); @@ -114,7 +109,7 @@ TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Ignored) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(iban_save_manager_->AttemptToOfferIBANLocalSave(iban)); EXPECT_TRUE(personal_data().GetLocalIBANs().empty()); @@ -128,85 +123,86 @@ TEST_F(IBANSaveManagerTest, LocallySaveIBAN_NotEnoughStrikesShouldOfferToSave) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); - iban_save_strike_database.AddStrike( - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + iban_save_strike_database.AddStrike(IBANSaveManager::GetPartialIbanHashString( + test::GetStrippedValue(test::kIbanValue))); - // Verify `kIbanValue` has been successfully added to the strike database. + // Verify the IBAN has been successfully added to the strike database. EXPECT_EQ(1, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); } TEST_F(IBANSaveManagerTest, LocallySaveIBAN_MaxStrikesShouldNotOfferToSave) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); iban_save_strike_database.AddStrikes( iban_save_strike_database.GetMaxStrikesLimit(), - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + IBANSaveManager::GetPartialIbanHashString( + test::GetStrippedValue(test::kIbanValue))); EXPECT_EQ(iban_save_strike_database.GetMaxStrikesLimit(), iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); } TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Accepted_ClearsStrikes) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); iban_save_strike_database.AddStrike( - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + IBANSaveManager::GetPartialIbanHashString(test::kIbanValue)); - // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been + // Verify partial hashed value of the IBAN has been // successfully added to the strike database. - EXPECT_EQ(1, iban_save_strike_database.GetStrikes( - IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + EXPECT_EQ(1, + iban_save_strike_database.GetStrikes( + IBANSaveManager::GetPartialIbanHashString(test::kIbanValue))); GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting( AutofillClient::SaveIBANOfferUserDecision::kAccepted, u"My teacher's IBAN"); - // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been + // Verify partial hashed value of the IBAN has been // cleared in the strike database. EXPECT_EQ(0, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); } TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Declined_AddsStrike) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); EXPECT_EQ(0, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting( AutofillClient::SaveIBANOfferUserDecision::kDeclined, u"My teacher's IBAN"); - // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been + // Verify partial hashed value of the IBAN has been // added to the strike database. EXPECT_EQ(1, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); } TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Ignored_AddsStrike) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); @@ -214,22 +210,22 @@ EXPECT_EQ(0, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting( AutofillClient::SaveIBANOfferUserDecision::kDeclined, u"My teacher's IBAN"); - // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been + // Verify partial hashed value of the IBAN has been // added to the strike database. EXPECT_EQ(1, iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); } TEST_F(IBANSaveManagerTest, LocallySaveIBAN_AttemptToOfferIBANLocalSave) { IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); EXPECT_TRUE(autofill_client_.ConfirmSaveIBANLocallyWasCalled()); @@ -239,16 +235,17 @@ LocallySaveIBAN_MaxStrikesShouldNotOfferToSave_Metrics) { base::HistogramTester histogram_tester; IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); iban_save_strike_database.AddStrikes( iban_save_strike_database.GetMaxStrikesLimit(), - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + IBANSaveManager::GetPartialIbanHashString( + test::GetStrippedValue(test::kIbanValue))); EXPECT_EQ(iban_save_strike_database.GetMaxStrikesLimit(), iban_save_strike_database.GetStrikes( IBANSaveManager::GetPartialIbanHashString( - kIbanValueWithoutWhitespaces))); + test::GetStrippedValue(test::kIbanValue)))); EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); histogram_tester.ExpectBucketCount( "Autofill.StrikeDatabase.IbanSaveNotOfferedDueToMaxStrikes", @@ -258,10 +255,10 @@ TEST_F(IBANSaveManagerTest, StrikesPresentWhenIBANSaved_Local) { base::HistogramTester histogram_tester; IBAN iban(base::GenerateUuid()); - iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); + iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); IBANSaveStrikeDatabase iban_save_strike_database(strike_database_); - iban_save_strike_database.AddStrike( - IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces)); + iban_save_strike_database.AddStrike(IBANSaveManager::GetPartialIbanHashString( + test::GetStrippedValue(test::kIbanValue))); EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban)); GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting(
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 5988c219c..1299a97f 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -906,11 +906,11 @@ TEST_F(PersonalDataManagerTest, NoIBANsAddedIfDisabled) { prefs::SetAutofillIBANEnabled(prefs_.get(), false); IBAN iban0(base::GenerateUuid()); - iban0.set_value(u"IE12 BOFI 9000 0112 3456 78"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); iban0.set_nickname(u"Nickname 0"); IBAN iban1(base::GenerateUuid()); - iban1.set_value(u"DE91 1000 0000 0123 4567 89"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1))); iban1.set_nickname(u"Nickname 1"); personal_data_->AddIBAN(iban0); @@ -934,18 +934,18 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveIBANs) { prefs::SetAutofillIBANEnabled(prefs_.get(), true); IBAN iban0(base::GenerateUuid()); - iban0.set_value(u"IE12 BOFI 9000 0112 3456 78"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); iban0.set_nickname(u"Nickname 0"); IBAN iban1(base::GenerateUuid()); - iban1.set_value(u"DE91 1000 0000 0123 4567 89"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1))); iban1.set_nickname(u"Nickname 1"); IBAN iban1_1 = iban1; iban1_1.set_nickname(u"Nickname 1_1"); IBAN iban2(base::GenerateUuid()); - iban2.set_value(u"ES79 2100 0813 6101 2345 6789"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_2))); iban2.set_nickname(u"Nickname 2"); // Add two test IBANs to the database. `iban1_1` has the same value @@ -1010,7 +1010,7 @@ // Start with a new IBAN. IBAN iban0(base::GenerateUuid()); - iban0.set_value(u"FR76 3000 6000 0112 3456 7890 189"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); iban0.set_nickname(u"Nickname 0"); // Add the IBAN to the database. personal_data_->OnAcceptedLocalIBANSave(iban0); @@ -1022,7 +1022,7 @@ // Creates a new IBAN and call `OnAcceptedLocalIBANSave()` and verify that // the new IBAN is saved. IBAN iban1(base::GenerateUuid()); - iban1.set_value(u"DE91 1000 0000 0123 4567 89"); + iban1.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1))); iban1.set_nickname(u"Nickname 1"); personal_data_->OnAcceptedLocalIBANSave(iban1); WaitForOnPersonalDataChanged(); @@ -1039,7 +1039,7 @@ // Creates a new `iban2` which has the same value as `iban0` but with // different nickname and call `OnAcceptedLocalIBANSave()`. IBAN iban2(base::GenerateUuid()); - iban2.set_value(u"FR76 3000 6000 0112 3456 7890 189"); + iban2.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); iban2.set_nickname(u"Nickname 2"); personal_data_->OnAcceptedLocalIBANSave(iban2); WaitForOnPersonalDataChanged(); @@ -1077,7 +1077,7 @@ // Start with a new IBAN. IBAN iban0(base::GenerateUuid()); - iban0.set_value(u"FR76 3000 6000 0112 3456 7890 189"); + iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue))); iban0.set_nickname(u"Nickname 0"); // Add the IBAN to the database. @@ -1089,7 +1089,7 @@ // Creates a new IBAN and call `OnAcceptedLocalIBANSave()` and verify that // the new IBAN is not saved. IBAN iban1(base::GenerateUuid()); - iban1.set_value(u"DE91 1000 0000 0123 4567 89"); + iban1.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1))); iban1.set_nickname(u"Nickname 1"); personal_data_->OnAcceptedLocalIBANSave(iban1);
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index fb4e030..5b587dc 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp
@@ -235,6 +235,9 @@ <message name="IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE" desc="The footer message used to notify user that their address will be saved in their account." formatter_data="android_java"> You can use saved addresses across Google products. This address will be saved in your Google Account (<ph name="ACCOUNT">$1<ex>alexpark@gmail.com</ex></ph>). </message> + <message name="IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE" desc="The description message used to notify the user that their address will be migrated to their account." formatter_data="android_java"> + This address is saved only to Chrome. To use it across Google products, save it in your Google Account, (<ph name="ACCOUNT">$1<ex>alexpark@gmail.com</ex></ph>). + </message> <message name="IDS_AUTOFILL_EDIT_ADDRESS_REQUIRED_FIELD_FORM_ERROR" desc="The form error message shown to the user in case of a single required field missing."> A required field is empty. Fill it before saving. </message>
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1 new file mode 100644 index 0000000..3eda7da --- /dev/null +++ b/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1
@@ -0,0 +1 @@ +bc1f614b455da4273811dc7777fc293ad6bffbad \ No newline at end of file
diff --git a/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java b/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java index 0488a86..6f3addd 100644 --- a/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java +++ b/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java
@@ -923,7 +923,8 @@ // Setting state to SCROLLING is not a valid operation. This can happen only when // we're already in the scrolling state. Make it no-op. if (state == SheetState.SCROLLING) { - assert mCurrentState == SheetState.SCROLLING && isRunningSettleAnimation(); + // TODO(mdjones): The isRunningSettleAnimation should hold but currently doesn't. + assert mCurrentState == SheetState.SCROLLING; // && isRunningSettleAnimation(); return; }
diff --git a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java index e88f45d..57dc887 100644 --- a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java +++ b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java
@@ -4,6 +4,7 @@ package org.chromium.components.browser_ui.bottomsheet; +import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; @@ -112,7 +113,8 @@ * @return Whether has any token to suppress the bottom sheet. */ public boolean hasSuppressionTokens() { - return mController.hasSuppressionTokensForTesting(); + return ThreadUtils.runOnUiThreadBlockingNoException( + () -> mController.hasSuppressionTokensForTesting()); } /**
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc index 96f576a..07c252b 100644 --- a/components/feature_engagement/public/feature_configurations.cc +++ b/components/feature_engagement/public/feature_configurations.cc
@@ -162,20 +162,6 @@ return config; } - if (kIPHHighEfficiencyInfoModeFeature.name == feature->name) { - absl::optional<FeatureConfig> config = FeatureConfig(); - config->valid = true; - config->availability = Comparator(ANY, 0); - config->session_rate = Comparator(EQUAL, 0); - // Show the promo up to 3 times if the page action chip was not opened - // within the last week - config->trigger = EventConfig("high_efficiency_info_trigger", - Comparator(LESS_THAN, 3), 360, 360); - config->used = - EventConfig("high_efficiency_info_shown", Comparator(EQUAL, 0), 7, 360); - return config; - } - if (kIPHHighEfficiencyModeFeature.name == feature->name) { absl::optional<FeatureConfig> config = FeatureConfig(); config->valid = true;
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index de71e7d1..a9aab07 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -44,9 +44,6 @@ BASE_FEATURE(kIPHGMCCastStartStopFeature, "IPH_GMCCastStartStop", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kIPHHighEfficiencyInfoModeFeature, - "IPH_HighEfficiencyInfoMode", - base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kIPHHighEfficiencyModeFeature, "IPH_HighEfficiencyMode", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index a5824b8..1bad8ab5f 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -31,7 +31,6 @@ BASE_DECLARE_FEATURE(kIPHExtensionsMenuFeature); BASE_DECLARE_FEATURE(kIPHFocusHelpBubbleScreenReaderPromoFeature); BASE_DECLARE_FEATURE(kIPHGMCCastStartStopFeature); -BASE_DECLARE_FEATURE(kIPHHighEfficiencyInfoModeFeature); BASE_DECLARE_FEATURE(kIPHHighEfficiencyModeFeature); BASE_DECLARE_FEATURE(kIPHLiveCaptionFeature); BASE_DECLARE_FEATURE(kIPHTabAudioMutingFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index bf9c3bd7..b428e41 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -142,7 +142,6 @@ &kIPHExtensionsMenuFeature, &kIPHFocusHelpBubbleScreenReaderPromoFeature, &kIPHGMCCastStartStopFeature, - &kIPHHighEfficiencyInfoModeFeature, &kIPHHighEfficiencyModeFeature, &kIPHLiveCaptionFeature, &kIPHTabAudioMutingFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index a972135d..d38335ab 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -258,8 +258,6 @@ DEFINE_VARIATION_PARAM(kIPHFocusModeFeature, "IPH_FocusMode"); DEFINE_VARIATION_PARAM(kIPHGlobalMediaControls, "IPH_GlobalMediaControls"); DEFINE_VARIATION_PARAM(kIPHGMCCastStartStopFeature, "IPH_GMCCastStartStop"); -DEFINE_VARIATION_PARAM(kIPHHighEfficiencyInfoModeFeature, - "IPH_HighEfficiencyInfoMode"); DEFINE_VARIATION_PARAM(kIPHHighEfficiencyModeFeature, "IPH_HighEfficiencyMode"); DEFINE_VARIATION_PARAM(kIPHLiveCaption, "IPH_LiveCaption"); DEFINE_VARIATION_PARAM(kIPHPasswordsAccountStorageFeature, @@ -442,7 +440,6 @@ VARIATION_ENTRY(kIPHFocusModeFeature), VARIATION_ENTRY(kIPHGlobalMediaControls), VARIATION_ENTRY(kIPHGMCCastStartStopFeature), - VARIATION_ENTRY(kIPHHighEfficiencyInfoModeFeature), VARIATION_ENTRY(kIPHHighEfficiencyModeFeature), VARIATION_ENTRY(kIPHLiveCaption), VARIATION_ENTRY(kIPHPasswordsAccountStorageFeature),
diff --git a/components/media_router/browser/mirroring_media_controller_host.cc b/components/media_router/browser/mirroring_media_controller_host.cc index 29a5eac..0300cbf 100644 --- a/components/media_router/browser/mirroring_media_controller_host.cc +++ b/components/media_router/browser/mirroring_media_controller_host.cc
@@ -35,11 +35,17 @@ observers_.RemoveObserver(observer); } -// TODO(b/271442872): Update these two method once freeze and unfreeze are -// implemented in MediaController. -void MirroringMediaControllerHost::Freeze() {} +void MirroringMediaControllerHost::Freeze() { + if (mirroring_controller_) { + mirroring_controller_->Pause(); + } +} -void MirroringMediaControllerHost::Unfreeze() {} +void MirroringMediaControllerHost::Unfreeze() { + if (mirroring_controller_) { + mirroring_controller_->Play(); + } +} void MirroringMediaControllerHost::OnMediaStatusUpdated( media_router::mojom::MediaStatusPtr status) {
diff --git a/components/media_router/browser/mirroring_media_controller_host_unittest.cc b/components/media_router/browser/mirroring_media_controller_host_unittest.cc index d9c7dac..13abb56 100644 --- a/components/media_router/browser/mirroring_media_controller_host_unittest.cc +++ b/components/media_router/browser/mirroring_media_controller_host_unittest.cc
@@ -4,6 +4,8 @@ #include "components/media_router/browser/mirroring_media_controller_host.h" +#include "base/run_loop.h" +#include "base/test/gmock_callback_support.h" #include "base/test/task_environment.h" #include "components/media_router/common/media_route.h" #include "testing/gmock/include/gmock/gmock.h" @@ -33,20 +35,45 @@ raw_ptr<MirroringMediaControllerHost> host_ = nullptr; }; +class MockMediaController : public mojom::MediaController { + public: + explicit MockMediaController( + mojo::PendingReceiver<mojom::MediaController> receiver) + : receiver_(this, std::move(receiver)) {} + ~MockMediaController() override = default; + + MOCK_METHOD(void, Play, ()); + MOCK_METHOD(void, Pause, ()); + MOCK_METHOD(void, SetMute, (bool mute)); + MOCK_METHOD(void, SetVolume, (float volume)); + MOCK_METHOD(void, Seek, (base::TimeDelta time)); + MOCK_METHOD(void, NextTrack, ()); + MOCK_METHOD(void, PreviousTrack, ()); + + void FlushForTesting() { receiver_.FlushForTesting(); } + + private: + mojo::Receiver<mojom::MediaController> receiver_; +}; + class MirroringMediaControllerHostTest : public ::testing::Test { public: MirroringMediaControllerHostTest() = default; ~MirroringMediaControllerHostTest() override = default; void SetUp() override { + mojo::Remote<mojom::MediaController> controller_remote; + media_controller_ = std::make_unique<MockMediaController>( + controller_remote.BindNewPipeAndPassReceiver()); + host_ = std::make_unique<MirroringMediaControllerHost>( - std::move(controller_remote_)); + std::move(controller_remote)); } protected: base::test::SingleThreadTaskEnvironment task_environment_; - mojo::Remote<mojom::MediaController> controller_remote_; std::unique_ptr<MirroringMediaControllerHost> host_; + std::unique_ptr<MockMediaController> media_controller_; }; TEST_F(MirroringMediaControllerHostTest, GetMediaStatusObserverPendingRemote) { @@ -62,4 +89,16 @@ host_->OnMediaStatusUpdated({}); } +TEST_F(MirroringMediaControllerHostTest, Freeze) { + EXPECT_CALL(*media_controller_, Pause); + host_->Freeze(); + media_controller_->FlushForTesting(); +} + +TEST_F(MirroringMediaControllerHostTest, Unfreeze) { + EXPECT_CALL(*media_controller_, Play); + host_->Unfreeze(); + media_controller_->FlushForTesting(); +} + } // namespace media_router
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 7dcede2..b248bd3e 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -38,6 +38,8 @@ "chevron.icon", "clear.icon", "clock.icon", + "cookie_chrome_refresh.icon", + "cookie_crossed_chrome_refresh.icon", "dino.icon", "drive_docs.icon", "drive_folder.icon", @@ -50,6 +52,7 @@ "drive_video.icon", "extension_app.icon", "find_in_page.icon", + "find_in_page_chrome_refresh.icon", "http.icon", "http_chrome_refresh.icon", "https_valid_in_chip.icon",
diff --git a/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon b/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon new file mode 100644 index 0000000..10b6235b --- /dev/null +++ b/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon
@@ -0,0 +1,68 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 8.75f, 8.5f, +R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f, +R_CUBIC_TO, 0.25f, -0.24f, 0.36f, -0.54f, 0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f, +CUBIC_TO_SHORTHAND, 9.1f, 6, 8.75f, 6, +R_CUBIC_TO, -0.35f, 0, -0.64f, 0.12f, -0.89f, 0.36f, +R_CUBIC_TO, -0.25f, 0.24f, -0.36f, 0.54f, -0.36f, 0.89f, +R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.36f, 0.89f, +R_CUBIC_TO, 0.24f, 0.25f, 0.54f, 0.36f, 0.89f, 0.36f, +CLOSE, +R_MOVE_TO, -2, 4, +R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f, +R_CUBIC_TO, 0.25f, -0.24f, 0.36f, -0.54f, 0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f, +CUBIC_TO_SHORTHAND, 7.1f, 10, 6.75f, 10, +R_CUBIC_TO, -0.35f, 0, -0.64f, 0.12f, -0.89f, 0.36f, +R_CUBIC_TO, -0.25f, 0.24f, -0.36f, 0.54f, -0.36f, 0.89f, +R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.36f, 0.89f, +R_CUBIC_TO, 0.24f, 0.25f, 0.54f, 0.36f, 0.89f, 0.36f, +CLOSE, +R_MOVE_TO, 5.75f, 0.75f, +R_CUBIC_TO, 0.21f, 0, 0.39f, -0.07f, 0.54f, -0.21f, +R_CUBIC_TO, 0.15f, -0.14f, 0.22f, -0.32f, 0.22f, -0.53f, +R_CUBIC_TO, 0, -0.21f, -0.07f, -0.39f, -0.21f, -0.54f, +R_CUBIC_TO, -0.14f, -0.15f, -0.32f, -0.22f, -0.53f, -0.22f, +R_CUBIC_TO, -0.21f, 0, -0.39f, 0.07f, -0.54f, 0.21f, +R_CUBIC_TO, -0.15f, 0.14f, -0.22f, 0.32f, -0.22f, 0.53f, +R_CUBIC_TO, 0, 0.21f, 0.07f, 0.39f, 0.21f, 0.54f, +R_CUBIC_TO, 0.14f, 0.15f, 0.32f, 0.22f, 0.53f, 0.22f, +CLOSE, +MOVE_TO, 10, 18, +R_CUBIC_TO, -1.1f, 0, -2.14f, -0.21f, -3.11f, -0.63f, +R_CUBIC_TO, -0.97f, -0.42f, -1.82f, -0.99f, -2.55f, -1.72f, +R_CUBIC_TO, -0.73f, -0.73f, -1.3f, -1.58f, -1.72f, -2.55f, +R_CUBIC_TO, -0.42f, -0.97f, -0.63f, -2.01f, -0.63f, -3.11f, +R_CUBIC_TO, 0, -1.29f, 0.28f, -2.49f, 0.84f, -3.59f, +R_CUBIC_TO, 0.56f, -1.1f, 1.3f, -2.02f, 2.22f, -2.76f, +CUBIC_TO, 5.97f, 2.9f, 7, 2.39f, 8.15f, 2.1f, +R_CUBIC_TO, 1.15f, -0.29f, 2.32f, -0.27f, 3.5f, 0.06f, +R_CUBIC_TO, -0.11f, 0.61f, -0.08f, 1.17f, 0.1f, 1.69f, +R_CUBIC_TO, 0.18f, 0.52f, 0.47f, 0.94f, 0.85f, 1.28f, +R_CUBIC_TO, 0.38f, 0.34f, 0.86f, 0.58f, 1.42f, 0.71f, +R_CUBIC_TO, 0.56f, 0.13f, 1.15f, 0.12f, 1.77f, -0.03f, +R_CUBIC_TO, -0.35f, 0.79f, -0.3f, 1.55f, 0.16f, 2.26f, +R_CUBIC_TO, 0.45f, 0.72f, 1.11f, 1.09f, 1.99f, 1.11f, +R_CUBIC_TO, 0.13f, 1.18f, 0, 2.3f, -0.38f, 3.37f, +R_CUBIC_TO, -0.38f, 1.06f, -0.93f, 2, -1.65f, 2.8f, +R_CUBIC_TO, -0.73f, 0.81f, -1.6f, 1.45f, -2.62f, 1.93f, +R_CUBIC_TO, -1.02f, 0.48f, -2.12f, 0.72f, -3.31f, 0.72f, +CLOSE, +R_MOVE_TO, 0, -1.5f, +R_CUBIC_TO, 1.74f, 0, 3.23f, -0.59f, 4.47f, -1.76f, +R_CUBIC_TO, 1.24f, -1.17f, 1.92f, -2.63f, 2.03f, -4.36f, +R_CUBIC_TO, -0.63f, -0.25f, -1.15f, -0.64f, -1.56f, -1.16f, +R_CUBIC_TO, -0.41f, -0.52f, -0.68f, -1.11f, -0.79f, -1.78f, +R_CUBIC_TO, -1.06f, -0.15f, -1.95f, -0.59f, -2.69f, -1.31f, +R_CUBIC_TO, -0.74f, -0.72f, -1.17f, -1.6f, -1.31f, -2.63f, +R_CUBIC_TO, -0.88f, -0.06f, -1.71f, 0.08f, -2.51f, 0.41f, +R_ARC_TO, 6.71f, 6.71f, 0, 0, 0, -3.6f, 3.5f, +R_CUBIC_TO, -0.36f, 0.81f, -0.54f, 1.68f, -0.54f, 2.59f, +R_CUBIC_TO, 0, 1.8f, 0.63f, 3.33f, 1.9f, 4.6f, +R_CUBIC_TO, 1.27f, 1.27f, 2.8f, 1.9f, 4.6f, 1.9f, +CLOSE
diff --git a/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon b/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon new file mode 100644 index 0000000..3819f684 --- /dev/null +++ b/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon
@@ -0,0 +1,61 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.63f, 14.5f, +R_LINE_TO, -1.1f, -1.1f, +R_CUBIC_TO, 0.28f, -0.44f, 0.5f, -0.92f, 0.66f, -1.43f, +R_CUBIC_TO, 0.17f, -0.51f, 0.27f, -1.04f, 0.31f, -1.59f, +R_CUBIC_TO, -0.63f, -0.25f, -1.15f, -0.64f, -1.56f, -1.16f, +R_CUBIC_TO, -0.41f, -0.52f, -0.68f, -1.11f, -0.79f, -1.78f, +R_CUBIC_TO, -1.06f, -0.15f, -1.95f, -0.59f, -2.69f, -1.31f, +R_CUBIC_TO, -0.74f, -0.72f, -1.17f, -1.6f, -1.31f, -2.63f, +R_CUBIC_TO, -0.65f, -0.04f, -1.28f, 0.02f, -1.89f, 0.19f, +R_CUBIC_TO, -0.61f, 0.17f, -1.17f, 0.42f, -1.7f, 0.75f, +R_LINE_TO, -1.1f, -1.1f, +R_CUBIC_TO, 0.89f, -0.64f, 1.87f, -1.07f, 2.95f, -1.3f, +R_CUBIC_TO, 1.08f, -0.23f, 2.16f, -0.18f, 3.26f, 0.14f, +R_CUBIC_TO, -0.11f, 0.61f, -0.08f, 1.17f, 0.1f, 1.69f, +R_CUBIC_TO, 0.18f, 0.52f, 0.47f, 0.94f, 0.85f, 1.28f, +R_CUBIC_TO, 0.38f, 0.34f, 0.86f, 0.58f, 1.42f, 0.71f, +R_CUBIC_TO, 0.56f, 0.13f, 1.15f, 0.12f, 1.77f, -0.03f, +R_CUBIC_TO, -0.35f, 0.79f, -0.3f, 1.55f, 0.16f, 2.26f, +R_CUBIC_TO, 0.45f, 0.72f, 1.11f, 1.09f, 1.99f, 1.11f, +R_CUBIC_TO, 0.11f, 0.99f, 0.05f, 1.93f, -0.2f, 2.83f, +R_CUBIC_TO, -0.24f, 0.9f, -0.62f, 1.73f, -1.14f, 2.48f, +CLOSE, +R_MOVE_TO, -9.88f, -2, +R_CUBIC_TO, -0.35f, 0, -0.64f, -0.12f, -0.89f, -0.36f, +R_CUBIC_TO, -0.25f, -0.24f, -0.36f, -0.54f, -0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, 0.12f, -0.64f, 0.36f, -0.89f, +R_CUBIC_TO, 0.24f, -0.25f, 0.54f, -0.36f, 0.89f, -0.36f, +R_CUBIC_TO, 0.35f, 0, 0.64f, 0.12f, 0.89f, 0.36f, +R_CUBIC_TO, 0.25f, 0.24f, 0.36f, 0.54f, 0.36f, 0.89f, +R_CUBIC_TO, 0, 0.35f, -0.12f, 0.64f, -0.36f, 0.89f, +R_CUBIC_TO, -0.24f, 0.25f, -0.54f, 0.36f, -0.89f, 0.36f, +CLOSE, +MOVE_TO, 16, 18.13f, +R_LINE_TO, -1.5f, -1.5f, +R_CUBIC_TO, -0.68f, 0.44f, -1.4f, 0.78f, -2.16f, 1.02f, +CUBIC_TO_SHORTHAND, 10.8f, 18, 10, 18, +R_CUBIC_TO, -1.1f, 0, -2.14f, -0.21f, -3.11f, -0.63f, +R_CUBIC_TO, -0.97f, -0.42f, -1.82f, -0.99f, -2.55f, -1.72f, +R_CUBIC_TO, -0.73f, -0.73f, -1.3f, -1.58f, -1.72f, -2.55f, +R_CUBIC_TO, -0.42f, -0.97f, -0.63f, -2.01f, -0.63f, -3.11f, +R_CUBIC_TO, 0, -0.81f, 0.12f, -1.59f, 0.35f, -2.34f, +R_CUBIC_TO, 0.23f, -0.75f, 0.58f, -1.48f, 1.02f, -2.16f, +R_LINE_TO, -1.5f, -1.5f, +R_LINE_TO, 1.06f, -1.06f, +R_LINE_TO, 14.13f, 14.13f, +R_LINE_TO, -1.06f, 1.06f, +CLOSE, +R_MOVE_TO, -6, -1.63f, +R_CUBIC_TO, 0.61f, 0, 1.2f, -0.09f, 1.77f, -0.27f, +R_CUBIC_TO, 0.57f, -0.18f, 1.12f, -0.42f, 1.65f, -0.71f, +LINE_TO, 4.48f, 6.58f, +R_CUBIC_TO, -0.29f, 0.53f, -0.53f, 1.08f, -0.71f, 1.65f, +R_CUBIC_TO, -0.18f, 0.57f, -0.27f, 1.16f, -0.27f, 1.77f, +R_CUBIC_TO, 0, 1.8f, 0.63f, 3.34f, 1.9f, 4.6f, +R_CUBIC_TO, 1.27f, 1.27f, 2.8f, 1.9f, 4.6f, 1.9f, +CLOSE
diff --git a/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon b/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon new file mode 100644 index 0000000..5904b2b --- /dev/null +++ b/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon
@@ -0,0 +1,46 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 12.33f, 16.5f, +R_LINE_TO, 1.5f, 1.5f, +H_LINE_TO, 5.5f, +R_CUBIC_TO, -0.41f, 0, -0.77f, -0.15f, -1.06f, -0.44f, +R_CUBIC_TO, -0.29f, -0.29f, -0.44f, -0.65f, -0.44f, -1.06f, +R_V_LINE_TO, -13, +R_CUBIC_TO, 0, -0.41f, 0.15f, -0.77f, 0.44f, -1.06f, +R_CUBIC_TO, 0.29f, -0.29f, 0.65f, -0.44f, 1.06f, -0.44f, +H_LINE_TO, 12, +R_LINE_TO, 4, 4, +R_V_LINE_TO, 9.92f, +R_CUBIC_TO, 0, 0.5f, -0.04f, 0.88f, -0.11f, 1.13f, +R_CUBIC_TO, -0.07f, 0.25f, -0.19f, 0.43f, -0.34f, 0.54f, +R_LINE_TO, -4.02f, -4.02f, +R_CUBIC_TO, -0.21f, 0.14f, -0.44f, 0.24f, -0.71f, 0.3f, +R_CUBIC_TO, -0.26f, 0.06f, -0.53f, 0.09f, -0.81f, 0.09f, +R_CUBIC_TO, -0.83f, 0, -1.54f, -0.29f, -2.13f, -0.88f, +CUBIC_TO_SHORTHAND, 7, 11.79f, 7, 10.95f, +R_CUBIC_TO, 0, -0.84f, 0.29f, -1.54f, 0.88f, -2.13f, +R_CUBIC_TO, 0.59f, -0.59f, 1.29f, -0.88f, 2.13f, -0.88f, +R_CUBIC_TO, 0.84f, 0, 1.54f, 0.29f, 2.13f, 0.88f, +R_CUBIC_TO, 0.59f, 0.59f, 0.88f, 1.29f, 0.88f, 2.13f, +R_CUBIC_TO, 0, 0.28f, -0.03f, 0.55f, -0.1f, 0.82f, +R_CUBIC_TO, -0.07f, 0.27f, -0.17f, 0.51f, -0.31f, 0.72f, +R_LINE_TO, 1.92f, 1.92f, +V_LINE_TO, 6.63f, +LINE_TO, 11.4f, 3.5f, +H_LINE_TO, 5.5f, +R_V_LINE_TO, 13, +R_H_LINE_TO, 6.83f, +CLOSE, +MOVE_TO, 10, 12.46f, +R_CUBIC_TO, 0.41f, 0, 0.77f, -0.15f, 1.06f, -0.46f, +R_CUBIC_TO, 0.29f, -0.31f, 0.44f, -0.72f, 0.44f, -1.25f, +R_CUBIC_TO, 0, -0.32f, -0.15f, -0.61f, -0.44f, -0.89f, +R_CUBIC_TO, -0.29f, -0.27f, -0.65f, -0.41f, -1.06f, -0.41f, +R_CUBIC_TO, -0.41f, 0, -0.77f, 0.14f, -1.06f, 0.41f, +R_CUBIC_TO, -0.29f, 0.27f, -0.44f, 0.57f, -0.44f, 0.89f, +R_CUBIC_TO, 0, 0.53f, 0.15f, 0.94f, 0.44f, 1.25f, +R_CUBIC_TO, 0.29f, 0.31f, 0.65f, 0.46f, 1.06f, 0.46f, +CLOSE
diff --git a/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon b/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon index a0e65d49..71dbfaf 100644 --- a/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon +++ b/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon
@@ -3,33 +3,35 @@ // found in the LICENSE file. CANVAS_DIMENSIONS, 16, -MOVE_TO, 4.25f, 7, -CUBIC_TO, 5.49f, 7, 6.5f, 5.99f, 6.5f, 4.75f, -CUBIC_TO_SHORTHAND, 5.49f, 2.5f, 4.25f, 2.5f, -CUBIC_TO_SHORTHAND, 2, 3.51f, 2, 4.75f, -CUBIC_TO_SHORTHAND, 3.01f, 7, 4.25f, 7, -CLOSE, -R_MOVE_TO, 0, -3.1f, -R_ARC_TO, 0.85f, 0.85f, 0, 1, 1, 0, 1.7f, -ARC_TO, 0.85f, 0.85f, 0, 0, 1, 4.25f, 3.9f, -CLOSE, -MOVE_TO, 8, 4, -R_H_LINE_TO, 6, +MOVE_TO, 14, 5.75f, +R_V_LINE_TO, -1.5f, +H_LINE_TO, 8.5f, R_V_LINE_TO, 1.5f, -H_LINE_TO, 8, +H_LINE_TO, 14, CLOSE, -MOVE_TO, 11.75f, 9, -R_CUBIC_TO, -1.24f, 0, -2.25f, 1.01f, -2.25f, 2.25f, -R_CUBIC_TO, 0, 1.24f, 1.01f, 2.25f, 2.25f, 2.25f, -CUBIC_TO_SHORTHAND, 14, 12.49f, 14, 11.25f, -CUBIC_TO_SHORTHAND, 12.99f, 9, 11.75f, 9, -CLOSE, -R_MOVE_TO, 0, 3.1f, -R_ARC_TO, 0.85f, 0.85f, 0, 1, 1, 0, -1.7f, -R_ARC_TO, 0.85f, 0.85f, 0, 0, 1, 0, 1.7f, -CLOSE, -MOVE_TO, 2, 10.5f, -R_H_LINE_TO, 6, -V_LINE_TO, 12, +R_MOVE_TO, -12, 4.5f, +R_V_LINE_TO, 1.5f, +R_H_LINE_TO, 5.5f, +R_V_LINE_TO, -1.5f, H_LINE_TO, 2, -CLOSE +CLOSE, +MOVE_TO, 4.5f, 4, +R_CUBIC_TO, 0.55f, 0, 1, 0.45f, 1, 1, +R_CUBIC_TO, 0, 0.55f, -0.45f, 1, -1, 1, +R_CUBIC_TO, -0.55f, 0, -1, -0.45f, -1, -1, +R_CUBIC_TO, 0, -0.55f, 0.45f, -1, 1, -1, +CLOSE, +R_MOVE_TO, 0, -1.5f, +R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, +R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, -5, +CLOSE, +R_MOVE_TO, 7, 7.5f, +R_CUBIC_TO, 0.55f, 0, 1, 0.45f, 1, 1, +R_CUBIC_TO, 0, 0.55f, -0.45f, 1, -1, 1, +R_CUBIC_TO, -0.55f, 0, -1, -0.45f, -1, -1, +R_CUBIC_TO, 0, -0.55f, 0.45f, -1, 1, -1, +CLOSE, +R_MOVE_TO, 0, -1.5f, +R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, +R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, -5, +CLOSE \ No newline at end of file
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc index 32f37e7..bc88b051 100644 --- a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
@@ -389,6 +389,10 @@ "WillRedirectRequestAfterWillProcessResponse", will_process_response_count_ > 0); + safe_browsing::scheme_logger::LogScheme( + original_url_, + "SafeBrowsing.BrowserThrottle.RedirectedOriginalUrlScheme"); + if (blocked_) { // OnCheckUrlResult() has set |blocked_| to true and called // |delegate_->CancelWithError|, but this method is called before the
diff --git a/components/services/storage/dom_storage/local_storage_impl.cc b/components/services/storage/dom_storage/local_storage_impl.cc index 3782ff4e..819a718 100644 --- a/components/services/storage/dom_storage/local_storage_impl.cc +++ b/components/services/storage/dom_storage/local_storage_impl.cc
@@ -751,10 +751,17 @@ std::vector<blink::StorageKey> storage_keys_to_delete; for (const auto& info : usage) { const blink::StorageKey& storage_key = info->storage_key; - if (storage_key.IsFirstPartyContext()) { - const url::Origin& origin = storage_key.origin(); - if (base::Contains(origins_to_purge_on_shutdown_, origin)) { + const url::Origin& key_origin = storage_key.origin(); + // Delete the storage if its origin matches one of the origins to purge, or + // if it is third-party and the top-level site is same-site with one of + // those origins. + for (const auto& origin_to_purge : origins_to_purge_on_shutdown_) { + if (key_origin == origin_to_purge || + (storage_key.IsThirdPartyContext() && + net::SchemefulSite(origin_to_purge) == + storage_key.top_level_site())) { storage_keys_to_delete.push_back(storage_key); + break; } } }
diff --git a/components/services/storage/dom_storage/local_storage_impl_unittest.cc b/components/services/storage/dom_storage/local_storage_impl_unittest.cc index ee40564..db13bb9 100644 --- a/components/services/storage/dom_storage/local_storage_impl_unittest.cc +++ b/components/services/storage/dom_storage/local_storage_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "build/build_config.h" #include "components/services/storage/dom_storage/storage_area_test_util.h" @@ -25,6 +26,7 @@ #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" #include "mojo/public/cpp/bindings/remote.h" +#include "net/base/features.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/env_chromium.h" @@ -706,10 +708,17 @@ } TEST_F(LocalStorageImplTest, ShutdownClearsData) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + net::features::kThirdPartyStoragePartitioning); blink::StorageKey storage_key1 = blink::StorageKey::CreateFromStringForTesting("http://foobar.com"); blink::StorageKey storage_key2 = blink::StorageKey::CreateFromStringForTesting("http://example.com"); + blink::StorageKey storage_key1_third_party = blink::StorageKey::Create( + url::Origin::Create(GURL("http://example1.com")), + net::SchemefulSite(GURL("http://foobar.com")), + blink::mojom::AncestorChainBit::kCrossSite); auto key1 = StdStringToUint8Vector("key1"); auto key2 = StdStringToUint8Vector("key"); auto value = StdStringToUint8Vector("value"); @@ -725,6 +734,10 @@ area->Put(key2, value, absl::nullopt, "source", base::DoNothing()); area.reset(); + context()->BindStorageArea(storage_key1_third_party, + area.BindNewPipeAndPassReceiver()); + area->Put(key1, value, absl::nullopt, "source", base::DoNothing()); + // Make sure all data gets committed to the DB. RunUntilIdle(); @@ -735,6 +748,9 @@ // Data from storage_key2 should exist, including meta-data, but nothing // should exist for storage_key1. + // Data from storage_key1_third_party should also be erased, since it is + // a third party storage key, and its top_level_site matches the origin + // of storage_key1, which is set to purge on shutdown. ResetStorage(storage_path()); auto contents = GetDatabaseContents(); EXPECT_EQ(3u, contents.size()); @@ -743,6 +759,8 @@ continue; EXPECT_EQ(std::string::npos, entry.first.find(storage_key1.origin().Serialize())); + EXPECT_EQ(std::string::npos, + entry.first.find(storage_key1_third_party.origin().Serialize())); EXPECT_NE(std::string::npos, entry.first.find(storage_key2.origin().Serialize())); }
diff --git a/components/supervised_user/core/browser/web_content_handler.h b/components/supervised_user/core/browser/web_content_handler.h index c014f4c..558be42 100644 --- a/components/supervised_user/core/browser/web_content_handler.h +++ b/components/supervised_user/core/browser/web_content_handler.h
@@ -43,6 +43,8 @@ virtual ~WebContentHandler(); // Initiates the OS specific local approval flow for a given `url`. + // Not all platforms with supervised users support this operation, + // and they must throw an error when implementing this method. virtual void RequestLocalApproval( const GURL& url, const std::u16string& child_display_name, @@ -69,8 +71,8 @@ protected: // Processes the outcome of the local approval request. - // Shared between the platforms. Should be called by platform specific - // completion callback. + // Should be called by platform specific completion callback. + // TODO(b/278079069): Refactor and convert the class to an interface. void OnLocalApprovalRequestCompleted( supervised_user::SupervisedUserSettingsService& settings_service, const GURL& url,
diff --git a/components/supervised_user/core/common/features.cc b/components/supervised_user/core/common/features.cc index a8c58ff0..4e7742416 100644 --- a/components/supervised_user/core/common/features.cc +++ b/components/supervised_user/core/common/features.cc
@@ -20,7 +20,19 @@ BASE_FEATURE(kWebFilterInterstitialRefresh, "WebFilterInterstitialRefresh", base::FEATURE_DISABLED_BY_DEFAULT); -#else +#elif BUILDFLAG(IS_IOS) +BASE_FEATURE(kWebFilterInterstitialRefresh, + "WebFilterInterstitialRefresh", + base::FEATURE_ENABLED_BY_DEFAULT); +#elif BUILDFLAG(IS_CHROMEOS_ASH) +BASE_FEATURE(kWebFilterInterstitialRefresh, + "WebFilterInterstitialRefresh", + base::FEATURE_ENABLED_BY_DEFAULT); +#elif BUILDFLAG(IS_CHROMEOS_LACROS) +BASE_FEATURE(kWebFilterInterstitialRefresh, + "WebFilterInterstitialRefresh", + base::FEATURE_ENABLED_BY_DEFAULT); +#else // Desktop BASE_FEATURE(kWebFilterInterstitialRefresh, "WebFilterInterstitialRefresh", base::FEATURE_ENABLED_BY_DEFAULT); @@ -33,12 +45,24 @@ // // The feature includes one experiment parameter: "preferred_button", which // determines which button is displayed as the preferred option in the -// interstitial UI (i.e. dark blue button). -#if BUILDFLAG(IS_CHROMEOS) +// interstitial UI (i.e. dark blue button).#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) +BASE_FEATURE(kLocalWebApprovals, + "LocalWebApprovals", + base::FEATURE_DISABLED_BY_DEFAULT); +#elif BUILDFLAG(IS_IOS) +BASE_FEATURE(kLocalWebApprovals, + "LocalWebApprovals", + base::FEATURE_DISABLED_BY_DEFAULT); +#elif BUILDFLAG(IS_CHROMEOS_ASH) BASE_FEATURE(kLocalWebApprovals, "LocalWebApprovals", base::FEATURE_ENABLED_BY_DEFAULT); -#else +#elif BUILDFLAG(IS_CHROMEOS_LACROS) +BASE_FEATURE(kLocalWebApprovals, + "LocalWebApprovals", + base::FEATURE_DISABLED_BY_DEFAULT); +#else // Desktop BASE_FEATURE(kLocalWebApprovals, "LocalWebApprovals", base::FEATURE_DISABLED_BY_DEFAULT); @@ -90,8 +114,8 @@ base::FEATURE_DISABLED_BY_DEFAULT); bool IsWebFilterInterstitialRefreshEnabled() { - DCHECK(base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh) || - !base::FeatureList::IsEnabled(kLocalWebApprovals)); + CHECK(base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh) || + !base::FeatureList::IsEnabled(kLocalWebApprovals)); return base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh); }
diff --git a/components/supervised_user/core/common/features_unittest.cc b/components/supervised_user/core/common/features_unittest.cc index 2137c15..e70a52e8 100644 --- a/components/supervised_user/core/common/features_unittest.cc +++ b/components/supervised_user/core/common/features_unittest.cc
@@ -66,9 +66,8 @@ EXPECT_FALSE(IsLocalWebApprovalsEnabled()); } -// Tests that DCHECK is triggered when local web approval feature is enabled +// Tests that CHECK is triggered when local web approval feature is enabled // without the refreshed web filter interstitial layout feature. -#if DCHECK_IS_ON() TEST_F(LocalWebApprovalsFeatureTest, InterstitialRefreshDisableAndLocalApprovalsEnabled) { scoped_feature_list_.InitWithFeatures( @@ -77,6 +76,5 @@ EXPECT_DEATH_IF_SUPPORTED(IsWebFilterInterstitialRefreshEnabled(), ""); EXPECT_DEATH_IF_SUPPORTED(IsLocalWebApprovalsEnabled(), ""); } -#endif } // namespace supervised_user
diff --git a/components/sync/driver/resources/about.ts b/components/sync/driver/resources/about.ts index 5f865fb..e15f3e7 100644 --- a/components/sync/driver/resources/about.ts +++ b/components/sync/driver/resources/about.ts
@@ -7,7 +7,7 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; import {addWebUiListener, removeWebUiListener, WebUiListener} from 'chrome://resources/js/cr.js'; -import {requestDataAndRegisterForUpdates, requestStart, requestStopClearData, requestStopKeepData, setIncludeSpecifics, triggerRefresh} from './chrome_sync.js'; +import {requestDataAndRegisterForUpdates, requestStart, requestStopClearData, setIncludeSpecifics, triggerRefresh} from './chrome_sync.js'; import {ProtocolEvent} from './traffic_log.js'; // Contains the latest snapshot of sync about info. @@ -266,10 +266,6 @@ const requestStartEl = document.querySelector<HTMLElement>('#request-start'); assert(requestStartEl); requestStartEl.addEventListener('click', requestStart); - const requestStopKeepDataEl = - document.querySelector<HTMLElement>('#request-stop-keep-data'); - assert(requestStopKeepDataEl); - requestStopKeepDataEl.addEventListener('click', requestStopKeepData); const requestStopClearDataEl = document.querySelector<HTMLElement>('#request-stop-clear-data'); assert(requestStopClearDataEl);
diff --git a/components/sync/driver/resources/chrome_sync.ts b/components/sync/driver/resources/chrome_sync.ts index 72030e6d..20e7a10 100644 --- a/components/sync/driver/resources/chrome_sync.ts +++ b/components/sync/driver/resources/chrome_sync.ts
@@ -78,13 +78,6 @@ } /** - * Stops the SyncService while keeping the sync data around. - */ -export function requestStopKeepData() { - chrome.send('requestStopKeepData'); -} - -/** * Stops the SyncService and clears the sync data. */ export function requestStopClearData() {
diff --git a/components/sync/driver/resources/index.html b/components/sync/driver/resources/index.html index 1d73f27a..444fdc4b9 100644 --- a/components/sync/driver/resources/index.html +++ b/components/sync/driver/resources/index.html
@@ -68,8 +68,7 @@ <div id="request-start-stop-wrapper" jsskip="true"> <button id="request-start">Request Start</button> - <button id="request-stop-keep-data">Stop Sync (Keep Data)</button> - <button id="request-stop-clear-data">Disable Sync (Clear Data)</button> + <button id="request-stop-clear-data">Disable Sync</button> </div> <div id="traffic-event-container-wrapper" jsskip="true">
diff --git a/components/sync/driver/sync_internals_util.h b/components/sync/driver/sync_internals_util.h index cc53ff6a..0b54df95 100644 --- a/components/sync/driver/sync_internals_util.h +++ b/components/sync/driver/sync_internals_util.h
@@ -47,7 +47,6 @@ "requestIncludeSpecificsInitialState"; inline constexpr char kRequestListOfTypes[] = "requestListOfTypes"; inline constexpr char kRequestStart[] = "requestStart"; -inline constexpr char kRequestStopKeepData[] = "requestStopKeepData"; inline constexpr char kRequestStopClearData[] = "requestStopClearData"; inline constexpr char kSetIncludeSpecifics[] = "setIncludeSpecifics"; inline constexpr char kTriggerRefresh[] = "triggerRefresh";
diff --git a/components/version_ui_strings.grdp b/components/version_ui_strings.grdp index cc5f082..6a643c6 100644 --- a/components/version_ui_strings.grdp +++ b/components/version_ui_strings.grdp
@@ -22,10 +22,20 @@ <message name="IDS_VERSION_UI_64BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit x86 processor, but being run on an Arm processor. Do not translate 'x86_64' as that is a technical term. The 'translated' in this string refers to the fact that these two processors use different languages, so the sense of 'translated' for this string is as in a language translation."> (x86_64 translated) </message> + </if> + <if expr="is_macosx or is_win"> <message name="IDS_VERSION_UI_64BIT_ARM" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit Arm processor. Translation is not needed; this is a technical term."> (arm64) </message> </if> + <if expr="is_win"> + <message name="IDS_VERSION_UI_32BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 32-bit x86 processor, but being run on an Arm processor. Do not translate."> + (32-bit emulated) + </message> + <message name="IDS_VERSION_UI_64BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit x86 processor, but being run on an Arm processor. Do not translate."> + (64-bit emulated) + </message> + </if> <message name="IDS_VERSION_UI_REVISION" desc="label for the revision on the about:version page"> Revision </message>
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index 292c7aa..829b6fd 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -154,14 +154,22 @@ base::FEATURE_DISABLED_BY_DEFAULT); #if BUILDFLAG(IS_APPLE) -BASE_FEATURE(kMacCAOverlayQuad, - "MacCAOverlayQuads", - base::FEATURE_ENABLED_BY_DEFAULT); -// The maximum supported overlay quad number on Mac CALayerOverlay. -// The default is set to -1. When MaxNum is < 0, the default in CALayerOverlay -// will be used instead. -const base::FeatureParam<int> kMacCAOverlayQuadMaxNum{ - &kMacCAOverlayQuad, "MacCAOverlayQuadMaxNum", -1}; +// Increase the max CALayer number allowed for CoreAnimation. +// * If this feature is disabled, then the default limit is 128 quads, +// unless there are 5 or more video elements present, in which case +// the limit is 300. +// * If this feature is enabled, then these limits are 512 and 300 quads +// respectively, and can be overridden by the "default" and "many-videos" +// feature parameters. +BASE_FEATURE(kCALayerNewLimit, + "CALayerNewLimit", + base::FEATURE_DISABLED_BY_DEFAULT); +// Set FeatureParam default to -1. CALayerOverlayProcessor choose the default in +// ca_layer_overlay.cc When it's < 0. +const base::FeatureParam<int> kCALayerNewLimitDefault{&kCALayerNewLimit, + "default", -1}; +const base::FeatureParam<int> kCALayerNewLimitManyVideos{&kCALayerNewLimit, + "many-videos", -1}; #endif #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OZONE)
diff --git a/components/viz/common/features.h b/components/viz/common/features.h index 9687e2ee..eeec9b4 100644 --- a/components/viz/common/features.h +++ b/components/viz/common/features.h
@@ -45,8 +45,10 @@ VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDynamicSchedulerForDraw); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDynamicSchedulerForClients); #if BUILDFLAG(IS_APPLE) -VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kMacCAOverlayQuad); -VIZ_COMMON_EXPORT extern const base::FeatureParam<int> kMacCAOverlayQuadMaxNum; +VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kCALayerNewLimit); +VIZ_COMMON_EXPORT extern const base::FeatureParam<int> kCALayerNewLimitDefault; +VIZ_COMMON_EXPORT extern const base::FeatureParam<int> + kCALayerNewLimitManyVideos; #endif #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OZONE)
diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc index 6ec52f95..855261e 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.cc +++ b/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -15,6 +15,7 @@ #include "base/check_op.h" #include "base/containers/contains.h" #include "base/location.h" +#include "base/metrics/histogram_macros.h" #include "base/notreached.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" @@ -166,14 +167,20 @@ is_gpu_busy_ = busy; if (is_gpu_busy_) { DCHECK_EQ(gpu_busy_response_state_, GpuBusyThrottlingState::kIdle); + gpu_busy_start_time_ = base::TimeTicks::Now(); return; } const bool was_throttled = gpu_busy_response_state_ == GpuBusyThrottlingState::kThrottled; gpu_busy_response_state_ = GpuBusyThrottlingState::kIdle; - if (was_throttled) + if (was_throttled) { + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Viz.FrameSink.GpuBusyDuration", + base::TimeTicks::Now() - gpu_busy_start_time_, base::Microseconds(1), + base::Seconds(5), /*bucket_count=*/100); OnGpuNoLongerBusy(); + } } bool BeginFrameSource::RequestCallbackOnGpuAvailable() {
diff --git a/components/viz/common/frame_sinks/begin_frame_source.h b/components/viz/common/frame_sinks/begin_frame_source.h index d270a96..89dd9a2c 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.h +++ b/components/viz/common/frame_sinks/begin_frame_source.h
@@ -244,6 +244,7 @@ // The BeginFrameSource should not send the begin-frame messages to clients if // gpu is busy. bool is_gpu_busy_ = false; + base::TimeTicks gpu_busy_start_time_; // Keeps track of whether a begin-frame was paused, and whether // OnGpuNoLongerBusy() should be invoked when the gpu is no longer busy.
diff --git a/components/viz/service/display/ca_layer_overlay.cc b/components/viz/service/display/ca_layer_overlay.cc index 6780495..3cac8b41 100644 --- a/components/viz/service/display/ca_layer_overlay.cc +++ b/components/viz/service/display/ca_layer_overlay.cc
@@ -30,10 +30,18 @@ // quads are promoted to CALayers. At extremes, corruption can occur. // https://crbug.com/1022116 -constexpr size_t kTooManyQuads = 128; -// |kTooManyQuadsWithVideos| can be re-assigned by kMacCAOverlayQuadMaxNum when -// feature kMacCAOverlayQuad is enabled. -constexpr size_t kTooManyQuadsWithVideos = 300; +// The default CALayer number allowed for CoreAnimation when kCALayerNewLimit is +// disabled. +constexpr size_t kLayerLimitDefault = 128; + +// The default CALayer number allowed with many videos (video conferencing). It +// can be overriden by the "many-videos" feature parameters if kCALayerNewLimit +// is enabled. +constexpr size_t kLayerLimitWithManyVideos = 300; + +// The new limit if kCALayerNewLimit is enabled. It can be overriden by the +// "default" feature parameters. +constexpr size_t kLayerNewLimitDefault = 512; // If there are too many RenderPassDrawQuads, we shouldn't use Core // Animation to present them as individual layers, since that potentially @@ -368,16 +376,22 @@ : overlays_allowed_(ui::RemoteLayerAPISupported()), enable_ca_renderer_(base::FeatureList::IsEnabled(kCARenderer)), enable_hdr_underlays_(base::FeatureList::IsEnabled(kHDRUnderlays)) { - if (base::FeatureList::IsEnabled(features::kMacCAOverlayQuad)) { - max_quad_list_size_for_videos_ = kTooManyQuadsWithVideos; - const int max_num = features::kMacCAOverlayQuadMaxNum.Get(); - if (max_num > 0) - max_quad_list_size_for_videos_ = max_num; - } else { - max_quad_list_size_for_videos_ = kTooManyQuads; - } + layer_limit_default_ = kLayerLimitDefault; + layer_limit_with_many_videos_ = kLayerLimitWithManyVideos; + if (base::FeatureList::IsEnabled(features::kCALayerNewLimit)) { + layer_limit_default_ = kLayerNewLimitDefault; + const int layer_limit_default_field_trial = + features::kCALayerNewLimitDefault.Get(); + if (layer_limit_default_field_trial > 0) { + layer_limit_default_ = layer_limit_default_field_trial; + } - DCHECK_GE(max_quad_list_size_for_videos_, kTooManyQuads); + const int layer_limit_with_many_videos_field_trial = + features::kCALayerNewLimitManyVideos.Get(); + if (layer_limit_with_many_videos_field_trial > 0) { + layer_limit_with_many_videos_ = layer_limit_with_many_videos_field_trial; + } + } } bool CALayerOverlayProcessor::AreClipSettingsValid( @@ -478,8 +492,6 @@ result = gfx::kCALayerFailedVideoCaptureEnabled; } else if (!render_pass->copy_requests.empty()) { result = gfx::kCALayerFailedCopyRequests; - } else if (num_visible_quads > max_quad_list_size_for_videos_) { - result = gfx::kCALayerFailedTooManyQuads; } if (result != gfx::kCALayerSuccess) { @@ -527,12 +539,11 @@ ca_layer_overlays->push_back(ca_layer); } - // Apply Feature kMacCAOverlayQuad to non-video-conferencing mode only. - // In the case of |max_quad_list_size_for_videos_| > |num_visible_quads| > - // kTooManyQuads, accept OverlayCandidate only if it's in a video conferencing - // mode. (video count >= kMaxNumVideos(5)) Otherwise, fail OverlayCandidate. - if (num_visible_quads > kTooManyQuads && - yuv_draw_quad_count < kMaxNumVideos) { + // Fails if there are more draw quads than allowed for CoreAnimation. + size_t max_number = (yuv_draw_quad_count < kMaxNumVideos) + ? layer_limit_default_ + : layer_limit_with_many_videos_; + if (num_visible_quads > max_number) { result = gfx::kCALayerFailedTooManyQuads; }
diff --git a/components/viz/service/display/ca_layer_overlay.h b/components/viz/service/display/ca_layer_overlay.h index f4d87b6d..c1febf09 100644 --- a/components/viz/service/display/ca_layer_overlay.h +++ b/components/viz/service/display/ca_layer_overlay.h
@@ -97,7 +97,8 @@ // https://crbug.com/836351, https://crbug.com/1290384 bool video_capture_enabled_ = false; - size_t max_quad_list_size_for_videos_ = 0; + size_t layer_limit_with_many_videos_ = 0; + size_t layer_limit_default_ = 0; // The error code in ProcessForCALayerOverlays() gfx::CALayerResult ca_layer_result_ = gfx::kCALayerSuccess;
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 7f20730..9268c51 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -943,6 +943,9 @@ scheduler_->DidSwapBuffers(); pending_swaps_++; + UMA_HISTOGRAM_COUNTS_100("Compositing.Display.PendingSwaps", + pending_swaps_); + renderer_->SwapBuffers(std::move(swap_frame_data)); } else { TRACE_EVENT_INSTANT0("viz", "Swap skipped.", TRACE_EVENT_SCOPE_THREAD);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 10c7edd..f4845f6c 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -111,8 +111,8 @@ } // namespace SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( - SkDeferredDisplayListRecorder* root_recorder) - : recorder_(root_recorder) {} + SkDeferredDisplayListRecorder* root_ddl_recorder) + : ddl_recorder_(root_ddl_recorder) {} SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( SkSurfaceCharacterization characterization) @@ -122,8 +122,8 @@ SkSurfaceCharacterization characterization, gpu::Mailbox mailbox) : mailbox_(mailbox) { - recorder_storage_.emplace(characterization); - recorder_ = &recorder_storage_.value(); + ddl_recorder_storage_.emplace(characterization); + ddl_recorder_ = &ddl_recorder_storage_.value(); } SkiaOutputSurfaceImpl::ScopedPaint::~ScopedPaint() = default; @@ -233,7 +233,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); TRACE_EVENT0("viz", __PRETTY_FUNCTION__); current_paint_.reset(); - root_recorder_.reset(); + root_ddl_recorder_.reset(); if (!render_pass_image_cache_.empty()) { std::vector<AggregatedRenderPassId> render_pass_ids; @@ -311,12 +311,12 @@ gpu_task_scheduler_->ScheduleOrRetainGpuTask(std::move(callback), {}); } -void SkiaOutputSurfaceImpl::RecreateRootRecorder() { +void SkiaOutputSurfaceImpl::RecreateRootDDLRecorder() { DCHECK(characterization_.isValid()); - root_recorder_.emplace(characterization_); + root_ddl_recorder_.emplace(characterization_); // This will trigger the lazy initialization of the recorder - std::ignore = root_recorder_->getCanvas(); - reset_recorder_on_swap_ = false; + std::ignore = root_ddl_recorder_->getCanvas(); + reset_ddl_recorder_on_swap_ = false; } void SkiaOutputSurfaceImpl::Reshape(const ReshapeParams& params) { @@ -367,7 +367,7 @@ size_ = params.size; format_ = params.format; - RecreateRootRecorder(); + RecreateRootDDLRecorder(); } void SkiaOutputSurfaceImpl::SetUpdateVSyncParametersCallback( @@ -409,10 +409,10 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Make sure there is no unsubmitted PaintFrame or PaintRenderPass. DCHECK(!current_paint_); - DCHECK(root_recorder_); - reset_recorder_on_swap_ = true; - current_paint_.emplace(&root_recorder_.value()); - return current_paint_->recorder()->getCanvas(); + DCHECK(root_ddl_recorder_); + reset_ddl_recorder_on_swap_ = true; + current_paint_.emplace(&root_ddl_recorder_.value()); + return current_paint_->ddl_recorder()->getCanvas(); } void SkiaOutputSurfaceImpl::MakePromiseSkImage( @@ -606,11 +606,11 @@ /*make_current=*/true, /*need_framebuffer=*/!dependency_->IsOffscreen()); - // Recreate |root_recorder_| after SwapBuffers has been scheduled on GPU + // Recreate |root_ddl_recorder_| after SwapBuffers has been scheduled on GPU // thread to save some time in BeginPaintCurrentFrame // Recreating recorder is expensive. Avoid recreation if there was no paint. - if (reset_recorder_on_swap_) { - RecreateRootRecorder(); + if (reset_ddl_recorder_on_swap_) { + RecreateRootDDLRecorder(); } } @@ -635,8 +635,8 @@ /*make_current=*/true, /*need_framebuffer=*/false); // Recreating recorder is expensive. Avoid recreation if there was no paint. - if (reset_recorder_on_swap_) { - RecreateRootRecorder(); + if (reset_ddl_recorder_on_swap_) { + RecreateRootDDLRecorder(); } } @@ -686,7 +686,7 @@ } current_paint_.emplace(characterization, mailbox); - return current_paint_->recorder()->getCanvas(); + return current_paint_->ddl_recorder()->getCanvas(); } SkCanvas* SkiaOutputSurfaceImpl::RecordOverdrawForCurrentPaint() { @@ -694,10 +694,10 @@ DCHECK(debug_settings_->show_overdraw_feedback); DCHECK(current_paint_); - DCHECK(!overdraw_surface_recorder_); + DCHECK(!overdraw_surface_ddl_recorder_); nway_canvas_.emplace(characterization_.width(), characterization_.height()); - nway_canvas_->addCanvas(current_paint_->recorder()->getCanvas()); + nway_canvas_->addCanvas(current_paint_->ddl_recorder()->getCanvas()); // Overdraw feedback uses |SkOverdrawCanvas|, which relies on a buffer with an // 8-bit unorm alpha channel to work. RGBA8 is always supported, so we use it. @@ -710,8 +710,8 @@ /*mipmap=*/false, characterization_.refColorSpace(), /*is_overlay=*/false, /*scanout_dcomp_surface=*/false); if (characterization.isValid()) { - overdraw_surface_recorder_.emplace(characterization); - overdraw_canvas_.emplace((overdraw_surface_recorder_->getCanvas())); + overdraw_surface_ddl_recorder_.emplace(characterization); + overdraw_canvas_.emplace((overdraw_surface_ddl_recorder_->getCanvas())); nway_canvas_->addCanvas(&overdraw_canvas_.value()); } @@ -725,14 +725,14 @@ bool is_overlay) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_paint_); - auto ddl = current_paint_->recorder()->detach(); + auto ddl = current_paint_->ddl_recorder()->detach(); sk_sp<SkDeferredDisplayList> overdraw_ddl; - if (overdraw_surface_recorder_) { - overdraw_ddl = overdraw_surface_recorder_->detach(); + if (overdraw_surface_ddl_recorder_) { + overdraw_ddl = overdraw_surface_ddl_recorder_->detach(); DCHECK(overdraw_ddl); overdraw_canvas_.reset(); - overdraw_surface_recorder_.reset(); + overdraw_surface_ddl_recorder_.reset(); nway_canvas_.reset(); } @@ -966,12 +966,18 @@ std::move(add_child_window_to_browser_callback)); if (!impl_on_gpu_) { *result = false; - } else { - capabilities_ = impl_on_gpu_->capabilities(); - is_displayed_as_overlay_ = impl_on_gpu_->IsDisplayedAsOverlay(); - gr_context_thread_safe_ = impl_on_gpu_->GetGrContextThreadSafeProxy(); - *result = true; + return; } + capabilities_ = impl_on_gpu_->capabilities(); + is_displayed_as_overlay_ = impl_on_gpu_->IsDisplayedAsOverlay(); + + if (auto* gr_context = dependency_->GetSharedContextState()->gr_context()) { + gr_context_thread_safe_ = gr_context->threadSafeProxy(); + } + graphite_recorder_ = + dependency_->GetSharedContextState()->viz_compositor_graphite_recorder(); + + *result = true; } SkSurfaceCharacterization
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index 148fb4bf..f343b46 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -43,6 +43,10 @@ struct SwapBuffersCompleteParams; } // namespace gpu +namespace skgpu::graphite { +class Recorder; +} // namespace skgpu::graphite + namespace viz { class ImageContextImpl; @@ -239,7 +243,7 @@ const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info); void ContextLost(); - void RecreateRootRecorder(); + void RecreateRootDDLRecorder(); raw_ptr<OutputSurfaceClient> client_ = nullptr; bool needs_swap_size_notifications_ = false; @@ -263,28 +267,28 @@ gfx::BufferFormat format_; int sample_count_ = 1; SkSurfaceCharacterization characterization_; - bool reset_recorder_on_swap_ = false; - absl::optional<SkDeferredDisplayListRecorder> root_recorder_; + bool reset_ddl_recorder_on_swap_ = false; + absl::optional<SkDeferredDisplayListRecorder> root_ddl_recorder_; class ScopedPaint { public: - explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder); + explicit ScopedPaint(SkDeferredDisplayListRecorder* root_ddl_recorder); explicit ScopedPaint(SkSurfaceCharacterization characterization); ScopedPaint(SkSurfaceCharacterization characterization, gpu::Mailbox mailbox); ~ScopedPaint(); - SkDeferredDisplayListRecorder* recorder() { return recorder_; } + SkDeferredDisplayListRecorder* ddl_recorder() { return ddl_recorder_; } gpu::Mailbox mailbox() { return mailbox_; } private: // This is recorder being used for current paint // This field is not a raw_ptr<> because it was filtered by the rewriter // for: #union - RAW_PTR_EXCLUSION SkDeferredDisplayListRecorder* recorder_; + RAW_PTR_EXCLUSION SkDeferredDisplayListRecorder* ddl_recorder_; // If we need new recorder for this Paint (i.e. it's not root render pass), // it's stored here - absl::optional<SkDeferredDisplayListRecorder> recorder_storage_; + absl::optional<SkDeferredDisplayListRecorder> ddl_recorder_storage_; const gpu::Mailbox mailbox_; }; @@ -322,7 +326,7 @@ // The SkDDL recorder is used for overdraw feedback. It is created by // BeginPaintOverdraw, and FinishPaintCurrentFrame will turn it into a SkDDL // and play the SkDDL back on the GPU thread. - absl::optional<SkDeferredDisplayListRecorder> overdraw_surface_recorder_; + absl::optional<SkDeferredDisplayListRecorder> overdraw_surface_ddl_recorder_; // |overdraw_canvas_| is used to record draw counts. absl::optional<SkOverdrawCanvas> overdraw_canvas_; @@ -376,6 +380,7 @@ std::unique_ptr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu_; sk_sp<GrContextThreadSafeProxy> gr_context_thread_safe_; + raw_ptr<skgpu::graphite::Recorder> graphite_recorder_ = nullptr; bool has_set_draw_rectangle_for_frame_ = false; absl::optional<gfx::Rect> draw_rectangle_;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 76ae090..2802fe1 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -1618,11 +1618,6 @@ context->EndAccessIfNecessary(); } -sk_sp<GrContextThreadSafeProxy> -SkiaOutputSurfaceImplOnGpu::GetGrContextThreadSafeProxy() { - return gr_context() ? gr_context()->threadSafeProxy() : nullptr; -} - void SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts( std::vector<std::unique_ptr<ExternalUseClient::ImageContext>> image_contexts) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index c539eb7..fc9af64 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -201,7 +201,6 @@ void ResetStateOfImages(); void EndAccessImages(const base::flat_set<ImageContextImpl*>& image_contexts); - sk_sp<GrContextThreadSafeProxy> GetGrContextThreadSafeProxy(); size_t max_resource_cache_bytes() const { return max_resource_cache_bytes_; } void ReleaseImageContexts( std::vector<std::unique_ptr<ExternalUseClient::ImageContext>>
diff --git a/components/webauthn/android/fido2credentialrequest_native_android.cc b/components/webauthn/android/fido2credentialrequest_native_android.cc index 063a0bf..2690b85 100644 --- a/components/webauthn/android/fido2credentialrequest_native_android.cc +++ b/components/webauthn/android/fido2credentialrequest_native_android.cc
@@ -74,3 +74,19 @@ return MojoClassFromJSON<blink::mojom::MakeCredentialAuthenticatorResponse>( env, webauthn::MakeCredentialResponseFromValue, jjson); } + +static base::android::ScopedJavaLocalRef<jstring> +JNI_Fido2CredentialRequest_GetOptionsToJson( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& byte_buffer) { + return MojoClassToJSON<blink::mojom::PublicKeyCredentialRequestOptions>( + env, byte_buffer); +} + +static base::android::ScopedJavaLocalRef<jbyteArray> +JNI_Fido2CredentialRequest_GetCredentialResponseFromJson( + JNIEnv* env, + const base::android::JavaParamRef<jstring>& jjson) { + return MojoClassFromJSON<blink::mojom::GetAssertionAuthenticatorResponse>( + env, webauthn::GetAssertionResponseFromValue, jjson); +}
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java index 5d325057..45b3c4d 100644 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -203,6 +203,7 @@ returnErrorAndResetCallback(AuthenticatorStatus.NOT_ALLOWED_ERROR); } + @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class) public void handleGetAssertionRequest(PublicKeyCredentialRequestOptions options, RenderFrameHost frameHost, Origin callerOrigin, PaymentOptions payment, GetAssertionResponseCallback callback, FidoErrorResponseCallback errorCallback) { @@ -213,12 +214,6 @@ mWebContents = WebContentsStatics.fromRenderFrameHost(frameHost); } - if (!apiAvailable()) { - Log.e(TAG, "Google Play Services' Fido2PrivilegedApi is not available."); - returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); - return; - } - WebAuthSecurityChecksResults webAuthSecurityChecksResults = frameHost.performGetAssertionWebAuthSecurityChecks( options.relyingPartyId, callerOrigin, payment != null); @@ -242,6 +237,19 @@ String callerOriginString = convertOriginToString(callerOrigin); byte[] clientDataHash = null; + // Conditional requests and payments should still go through Google Play Services. + if (!options.isConditional && payment == null && isCredManEnabled() + && BuildCompat.isAtLeastU()) { + getCredentialViaCredMan(options, callerOrigin, frameHost); + return; + } + + if (!apiAvailable()) { + Log.e(TAG, "Google Play Services' Fido2PrivilegedApi is not available."); + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + return; + } + if (payment != null && PaymentFeatureList.isEnabled(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION)) { assert options.challenge != null; @@ -649,8 +657,11 @@ mWebContents = webContents; } - /** Create a credential using the Android 14 CredMan API. */ - @RequiresApi(Build.VERSION_CODES.S) + /** + * Create a credential using the Android 14 CredMan API. + * TODO: update the version code to U when Chromium builds with Android 14 SDK. + */ + @RequiresApi(Build.VERSION_CODES.TIRAMISU) @SuppressWarnings("WrongConstant") private void makeCredentialViaCredMan( PublicKeyCredentialCreationOptions options, Origin origin, RenderFrameHost frameHost) { @@ -742,9 +753,143 @@ } } + /** + * Gets the credential using the Android 14 CredMan API. + * TODO: update the version code to U when Chromium builds with Android 14 SDK. + */ + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + @SuppressWarnings("WrongConstant") + private void getCredentialViaCredMan( + PublicKeyCredentialRequestOptions options, Origin origin, RenderFrameHost frameHost) { + final String requestAsJson = + Fido2CredentialRequestJni.get().getOptionsToJson(options.serialize()); + final Context context = ContextUtils.getApplicationContext(); + + final Bundle publicKeyCredentialOptionBundle = new Bundle(); + publicKeyCredentialOptionBundle.putString(CRED_MAN_PREFIX + "BUNDLE_KEY_SUBTYPE", + CRED_MAN_PREFIX + "BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"); + publicKeyCredentialOptionBundle.putString( + CRED_MAN_PREFIX + "BUNDLE_KEY_REQUEST_JSON", requestAsJson); + publicKeyCredentialOptionBundle.putString( + CRED_MAN_PREFIX + "BUNDLE_KEY_CLIENT_DATA_HASH", null); + publicKeyCredentialOptionBundle.putBoolean( + CRED_MAN_PREFIX + "BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS", false); + + // The Android 14 APIs have to be called via reflection until Chromium + // builds with the Android 14 SDK by default. + OutcomeReceiver<Object, Throwable> receiver = new OutcomeReceiver<>() { + @Override + public void onError(Throwable getCredentialException) { + try { + Log.e(TAG, "CredMan call failed", getCredentialException); + Class<?> getCredentialExceptionClass = getCredentialException.getClass(); + String errorType = + (String) getCredentialExceptionClass.getMethod("getType").invoke( + getCredentialException); + if (((String) getCredentialExceptionClass.getField("TYPE_USER_CANCELED") + .get(getCredentialException)) + .equals(errorType)) { + returnErrorAndResetCallback(AuthenticatorStatus.NOT_ALLOWED_ERROR); + return; + } + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + } catch (ReflectiveOperationException e) { + Log.e(TAG, "Reflection failed; are you running on Android 14?", + getCredentialException); + returnErrorAndResetCallback(AuthenticatorStatus.ANDROID_NOT_SUPPORTED_ERROR); + } + } + + @Override + public void onResult(Object getCredentialResponse) { + Bundle data; + try { + Object credential = getCredentialResponse.getClass() + .getMethod("getCredential") + .invoke(getCredentialResponse); + data = (Bundle) credential.getClass().getMethod("getData").invoke(credential); + + } catch (ReflectiveOperationException e) { + Log.e(TAG, "Reflection failed; are you running on Android 14?", e); + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + return; + } + + String json = + data.getString(CRED_MAN_PREFIX + "BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"); + byte[] responseSerialized = + Fido2CredentialRequestJni.get().getCredentialResponseFromJson(json); + if (responseSerialized == null) { + Log.e(TAG, "Failed to convert response from CredMan to Mojo object"); + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + return; + } + + GetAssertionAuthenticatorResponse response = + GetAssertionAuthenticatorResponse.deserialize( + ByteBuffer.wrap(responseSerialized)); + if (response == null) { + Log.e(TAG, "Failed to parse Mojo object"); + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + return; + } + if (mAppIdExtensionUsed) { + response.echoAppidExtension = mAppIdExtensionUsed; + } + mGetAssertionCallback.onSignResponse(AuthenticatorStatus.SUCCESS, response); + mGetAssertionCallback = null; + } + }; + + try { + // Build the CredentialOption: + final Class<?> credentialOptionBuilderClass = + Class.forName("android.credentials.CredentialOption$Builder"); + final Object credentialOptionBuilder = + credentialOptionBuilderClass + .getConstructor(String.class, Bundle.class, Bundle.class) + .newInstance(CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL", + publicKeyCredentialOptionBundle, + publicKeyCredentialOptionBundle); + final Object credentialOption = + credentialOptionBuilderClass.getMethod("build").invoke(credentialOptionBuilder); + + // Build the GetCredentialRequest: + final Class<?> getCredentialRequestBuilderClass = + Class.forName("android.credentials.GetCredentialRequest$Builder"); + final Object getCredentialRequestBuilderObject = + getCredentialRequestBuilderClass.getConstructor(Bundle.class) + .newInstance(new Bundle()); + getCredentialRequestBuilderClass + .getMethod("addCredentialOption", credentialOption.getClass()) + .invoke(getCredentialRequestBuilderObject, credentialOption); + getCredentialRequestBuilderClass.getMethod("setOrigin", String.class) + .invoke(getCredentialRequestBuilderObject, convertOriginToString(origin)); + final Object getCredentialRequest = + getCredentialRequestBuilderClass.getMethod("build").invoke( + getCredentialRequestBuilderObject); + + // TODO: switch "credential" to `Context.CREDENTIAL_SERVICE` and remove the + // `@SuppressWarnings` when the Android U SDK is available. + final Object manager = context.getSystemService("credential"); + manager.getClass() + .getMethod("getCredential", Context.class, getCredentialRequest.getClass(), + android.os.CancellationSignal.class, + java.util.concurrent.Executor.class, OutcomeReceiver.class) + .invoke(manager, context, getCredentialRequest, null, context.getMainExecutor(), + receiver); + } catch (ReflectiveOperationException e) { + Log.e(TAG, "Reflection failed; are you running on Android 14?", e); + returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); + return; + } + } + @NativeMethods interface Natives { String createOptionsToJson(ByteBuffer serializedOptions); byte[] makeCredentialResponseFromJson(String json); + String getOptionsToJson(ByteBuffer serializedOptions); + byte[] getCredentialResponseFromJson(String json); } }
diff --git a/components/webauthn/json/value_conversions_unittest.cc b/components/webauthn/json/value_conversions_unittest.cc index fc162b0..0d07aff45 100644 --- a/components/webauthn/json/value_conversions_unittest.cc +++ b/components/webauthn/json/value_conversions_unittest.cc
@@ -90,7 +90,7 @@ device::ResidentKeyRequirement::kRequired, device::UserVerificationRequirement::kRequired), device::AttestationConveyancePreference::kDirect, - /*cable_registration_data=*/nullptr, /*hmac_create_secret=*/true, + /*hmac_create_secret=*/true, /*prf_enable=*/false, blink::mojom::ProtectionPolicy::UV_REQUIRED, /*enforce_protection_policy=*/true, /*appid_exclude=*/kAppId,
diff --git a/components/zucchini/equivalence_map.cc b/components/zucchini/equivalence_map.cc index 26baf368..edc19ec 100644 --- a/components/zucchini/equivalence_map.cc +++ b/components/zucchini/equivalence_map.cc
@@ -325,6 +325,7 @@ if (current->length == 0) { continue; } + offset_t current_src_end = current->src_end(); // A "reaper" is an equivalence after |current| that overlaps with it, but // is longer, and so truncates |current|. For example: @@ -342,12 +343,13 @@ auto next = current + 1; for (; next != equivalences->end(); ++next) { DCHECK_GE(next->src_offset, current->src_offset); - if (next->src_offset >= current->src_end()) + if (next->src_offset >= current_src_end) { break; // No more overlap. + } if (current->length < next->length) { // |next| is better: So it is a reaper that shrinks |current|. - offset_t delta = current->src_end() - next->src_offset; + offset_t delta = current_src_end - next->src_offset; current->length -= delta; next_is_reaper = true; break; @@ -363,20 +365,17 @@ // Shrink all equivalences that overlap with |current|. These are all // worse (same length or shorter), since no reaper is found. for (auto reduced = current + 1; reduced != next; ++reduced) { - // Clipping Case 1: Clipping Case 2: - // |current| cccccccc cccccccc - // |reduced| rrrrr rrrr - // New |reduced| rr (empty) - // |delta| 3 6 - // |capped_delta| 3 4 - offset_t delta = current->src_end() - reduced->src_offset; + offset_t delta = current_src_end - reduced->src_offset; offset_t capped_delta = std::min(reduced->length, delta); + // Use |capped_delta| so length is >= 0 always. reduced->length -= capped_delta; - // For Case 1, below is same as adding |delta|. For Case 2, offsets - // become irrelevant. However, |dst_offset + delta| may create an offset - // outside the file, or even overflow. So for robustness, - // |capped_delta| is used. - reduced->src_offset += capped_delta; + // Truncate while preserving sort order re. |src_offset|. This is same + // as |reduced->src_offset += delta|. + reduced->src_offset = current_src_end; + // If the range becomes empty, |+= delta| may cause new |dst_offset| to + // overflow (although the value won't get used). To prevent this (for + // robustness), use |+= capped_delta|, which is identical to |+= delta| + // if the range remains non-empty. reduced->dst_offset += capped_delta; } }
diff --git a/components/zucchini/equivalence_map_unittest.cc b/components/zucchini/equivalence_map_unittest.cc index 78179e98..2d37be9e 100644 --- a/components/zucchini/equivalence_map_unittest.cc +++ b/components/zucchini/equivalence_map_unittest.cc
@@ -276,6 +276,10 @@ EXPECT_EQ(std::deque<Equivalence>({{0, 10, 3}, {3, 16, 2}}), PruneEquivalencesAndSortBySourceTest( {{0, 10, 3}, {1, 13, 3}, {3, 16, 2}})); // Pruning is greedy + // Test for crbug.com/1432457. + EXPECT_EQ(std::deque<Equivalence>({{0, 10, +6}, {6, 23, +2}}), + PruneEquivalencesAndSortBySourceTest( + {{0, 10, +6}, {3, 20, +5}, {3, 30, +1}})); // Consider following pattern that may cause O(n^2) behavior if not handled // properly.
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm index 299e3e8..f14cd49b 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm +++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
@@ -4,6 +4,9 @@ #import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h" +#include <Foundation/Foundation.h> + +#include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" #include "components/remote_cocoa/app_shim/ns_view_ids.h" @@ -262,9 +265,12 @@ void RenderWidgetHostNSViewBridge::ShowDictionaryOverlay( ui::mojom::AttributedStringPtr attributed_string, const gfx::Point& baseline_point) { - NSAttributedString* string = attributed_string.To<NSAttributedString*>(); - if ([string length] == 0) + CFAttributedStringRef cf_string = + attributed_string.To<CFAttributedStringRef>(); + NSAttributedString* string = base::mac::CFToNSCast(cf_string); + if ([string length] == 0) { return; + } NSPoint flipped_baseline_point = { static_cast<CGFloat>(baseline_point.x()), [cocoa_view_ frame].size.height - baseline_point.y(),
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 3ac97b6..64545f6 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2287,6 +2287,8 @@ "webui/web_ui_impl.h", "webui/web_ui_main_frame_observer.cc", "webui/web_ui_main_frame_observer.h", + "webui/web_ui_managed_interface.cc", + "webui/web_ui_managed_interface.h", "webui/web_ui_message_handler.cc", "webui/web_ui_url_loader_factory.cc", "worker_host/dedicated_worker_host.cc",
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index 1a297b4..b485fd06 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -330,6 +330,30 @@ return deprecation_issue; } +std::unique_ptr<protocol::Audits::InspectorIssue> BuildBounceTrackingIssue( + const blink::mojom::BounceTrackingIssueDetailsPtr& issue_details) { + auto bounce_tracking_issue_details = + protocol::Audits::BounceTrackingIssueDetails::Create() + .SetTrackingSites(std::make_unique<protocol::Array<protocol::String>>( + issue_details->tracking_sites)) + .Build(); + + auto protocol_issue_details = + protocol::Audits::InspectorIssueDetails::Create() + .SetBounceTrackingIssueDetails( + std::move(bounce_tracking_issue_details)) + .Build(); + + auto issue = + protocol::Audits::InspectorIssue::Create() + .SetCode( + protocol::Audits::InspectorIssueCodeEnum::BounceTrackingIssue) + .SetDetails(std::move(protocol_issue_details)) + .Build(); + + return issue; +} + void UpdateChildFrameTrees(FrameTreeNode* ftn, bool update_target_info) { if (auto* agent_host = WebContentsDevToolsAgentHost::GetFor( WebContentsImpl::FromFrameTreeNode(ftn))) { @@ -1501,6 +1525,10 @@ } else if (info->code == blink::mojom::InspectorIssueCode::kDeprecationIssue) { issue = BuildDeprecationIssue(info->details->deprecation_issue_details); + } else if (info->code == + blink::mojom::InspectorIssueCode::kBounceTrackingIssue) { + issue = + BuildBounceTrackingIssue(info->details->bounce_tracking_issue_details); } else { NOTREACHED() << "Unsupported type of browser-initiated issue"; }
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 2dfdb62..18ba841 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -293,8 +293,9 @@ if (gpu_feature_data.name == "multiple_raster_threads") { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(blink::switches::kNumRasterThreads)) + if (command_line.HasSwitch(cc::switches::kNumRasterThreads)) { status += "_force"; + } status += "_on"; } if (gpu_feature_data.name == "opengl" || @@ -431,13 +432,12 @@ const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(blink::switches::kNumRasterThreads)) { + if (command_line.HasSwitch(cc::switches::kNumRasterThreads)) { std::string string_value = - command_line.GetSwitchValueASCII(blink::switches::kNumRasterThreads); + command_line.GetSwitchValueASCII(cc::switches::kNumRasterThreads); if (!base::StringToInt(string_value, &num_raster_threads)) { DLOG(WARNING) << "Failed to parse switch " - << blink::switches::kNumRasterThreads << ": " - << string_value; + << cc::switches::kNumRasterThreads << ": " << string_value; } }
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index 068ca95..84fc60d 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -1021,7 +1021,8 @@ auto delete_bucket = origins_to_purge_on_shutdown_.find( bucket_locator.storage_key.origin()) != origins_to_purge_on_shutdown_.end(); - if (!delete_bucket) { + + if (!delete_bucket && bucket_locator.storage_key.IsThirdPartyContext()) { auto& bucket_site = bucket_locator.storage_key.top_level_site(); for (const auto& origin_to_purge : origins_to_purge_on_shutdown_) { if (net::SchemefulSite(origin_to_purge) == bucket_site) {
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index 204c05d8..ae95398a 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -361,19 +361,10 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(base::DirectoryExists(normal_path_first_party)); - // TODO(https://crbug.com/1429467): This directory shouldn't be deleted - // because it's a first-party context, which we only want to delete data for - // based on origin. - EXPECT_FALSE(base::DirectoryExists(session_only_path_first_party)); + EXPECT_TRUE(base::DirectoryExists(session_only_path_first_party)); EXPECT_FALSE(base::DirectoryExists(session_only_subdomain_path_first_party)); EXPECT_TRUE(base::DirectoryExists(normal_path_third_party)); - // TODO(https://crbug.com/1429467): Delete this conditional and always - // EXPECT_TRUE once this issue is fixed. - if (IsThirdPartyStoragePartitioningEnabled()) { - EXPECT_TRUE(base::DirectoryExists(session_only_path_third_party)); - } else { - EXPECT_FALSE(base::DirectoryExists(session_only_path_third_party)); - } + EXPECT_TRUE(base::DirectoryExists(session_only_path_third_party)); EXPECT_FALSE(base::DirectoryExists(session_only_subdomain_path_third_party)); EXPECT_TRUE(base::DirectoryExists(inverted_normal_path_third_party)); // When storage partitioning is enabled these will be deleted because they
diff --git a/content/browser/per_web_ui_browser_interface_broker.cc b/content/browser/per_web_ui_browser_interface_broker.cc index d85e17e..dd32a42 100644 --- a/content/browser/per_web_ui_browser_interface_broker.cc +++ b/content/browser/per_web_ui_browser_interface_broker.cc
@@ -15,7 +15,7 @@ namespace { void ShutdownWebUIRenderer(WebUIController& controller) { auto* webui_impl = static_cast<WebUIImpl*>(controller.web_ui()); - webui_impl->frame_host()->GetProcess()->ShutdownForBadMessage( + webui_impl->GetRenderFrameHost()->GetProcess()->ShutdownForBadMessage( RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP); } } // namespace
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc index 4c490cb..e6c3cfea 100644 --- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
@@ -24,6 +24,7 @@ #include "content/browser/preloading/prefetch/prefetch_type.h" #include "content/browser/preloading/prefetch/prefetch_url_loader_helper.h" #include "content/browser/preloading/preloading.h" +#include "content/browser/preloading/preloading_config.h" #include "content/browser/preloading/preloading_data_impl.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/renderer_host/navigation_request.h" @@ -254,10 +255,13 @@ std::make_unique<base::ScopedMockElapsedTimersForTest>(); scoped_feature_list_.InitAndDisableFeature(::features::kPreloadingConfig); + PreloadingConfig::GetInstance().ParseConfig(); } void TearDown() override { interceptor_.release(); + scoped_feature_list_.Reset(); + PreloadingConfig::GetInstance().ParseConfig(); RenderViewHostTestHarness::TearDown(); }
diff --git a/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc b/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc index 84bc0fc9..0ca688b02 100644 --- a/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc +++ b/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc
@@ -45,6 +45,7 @@ void TearDown() override { web_contents_.reset(); browser_context_.reset(); + mojo::SetDefaultProcessErrorHandler(base::NullCallback()); RenderViewHostImplTestHarness::TearDown(); }
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc index e5bed3fe..ca78b76a 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -790,7 +790,7 @@ ui::EventTimeForNow()); followup_event.touches_length = 1; followup_event.touches[0].id = 0; - followup_event.unique_touch_event_id = 100; + followup_event.unique_touch_event_id = ui::GetNextTouchEventId(); followup_event.touches[0].state = WebTouchPoint::State::kStateMoved; SetFollowupEvent(followup_event); SetSyncAckResult(blink::mojom::InputEventResultState::kConsumed); @@ -801,7 +801,8 @@ EXPECT_EQ(0U, queued_event_count()); EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(3U, GetAndResetAckedEventCount()); - EXPECT_EQ(100U, acked_event().unique_touch_event_id); + EXPECT_EQ(followup_event.unique_touch_event_id, + acked_event().unique_touch_event_id); } // Tests that followup events triggered by an immediate ack from
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 2c42f43..bf4edfb 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -51,8 +51,9 @@ RenderFrameHost* render_frame_host = RenderFrameHost::FromID(render_process_id, render_frame_id); - if (render_frame_host && render_frame_host->IsRenderFrameLive()) + if (render_frame_host && render_frame_host->IsRenderFrameLive()) { render_frame_host->GetRemoteInterfaces()->GetInterface(std::move(receiver)); + } } std::unique_ptr<MediaStreamWebContentsObserver, BrowserThread::DeleteOnUIThread> @@ -345,8 +346,9 @@ RenderFrameHostImpl* render_frame_host = RenderFrameHostImpl::FromID(render_process_id, render_frame_id); - if (!render_frame_host) + if (!render_frame_host) { return false; + } ContentBrowserClient* browser_client = GetContentClient()->browser(); return browser_client->IsGetDisplayMediaSetSelectAllScreensAllowed( render_frame_host->GetBrowserContext(), @@ -377,8 +379,9 @@ MediaStreamDispatcherHost::GetMediaStreamDeviceObserver() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (media_stream_device_observer_) + if (media_stream_device_observer_) { return media_stream_device_observer_; + } auto dispatcher_receiver = media_stream_device_observer_.BindNewPipeAndPassReceiver();
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index 07a63a6..61ca5243c 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -260,12 +260,14 @@ void OnDeviceStoppedInternal(const std::string& label, const blink::MediaStreamDevice& device) { - if (blink::IsVideoInputMediaType(device.type)) + if (blink::IsVideoInputMediaType(device.type)) { EXPECT_TRUE(device.IsSameDevice( stream_devices_set_->stream_devices[0]->video_device.value())); - if (blink::IsAudioInputMediaType(device.type)) + } + if (blink::IsAudioInputMediaType(device.type)) { EXPECT_TRUE(device.IsSameDevice( stream_devices_set_->stream_devices[0]->audio_device.value())); + } OnDeviceStopSuccess(); } @@ -407,8 +409,9 @@ std::unique_ptr<MockMediaStreamUIProxy> fake_ui = std::make_unique<MockMediaStreamUIProxy>(); - if (expect_started) + if (expect_started) { EXPECT_CALL(*fake_ui, MockOnStarted(_)); + } return fake_ui; } @@ -481,19 +484,22 @@ bool DoesContainRawIds( const absl::optional<blink::MediaStreamDevice>& optional_device) { - if (!optional_device.has_value()) + if (!optional_device.has_value()) { return false; + } const blink::MediaStreamDevice& device = optional_device.value(); if (device.id != media::AudioDeviceDescription::kDefaultDeviceId && device.id != media::AudioDeviceDescription::kCommunicationsDeviceId) { for (const auto& audio_device : audio_device_descriptions_) { - if (audio_device.unique_id == device.id) + if (audio_device.unique_id == device.id) { return true; + } } } for (const std::string& device_id : stub_video_device_ids_) { - if (device_id == device.id) + if (device_id == device.id) { return true; + } } return false; } @@ -501,8 +507,9 @@ bool DoesEveryDeviceMapToRawId( const absl::optional<blink::MediaStreamDevice>& optional_device, const url::Origin& origin) { - if (!optional_device.has_value()) + if (!optional_device.has_value()) { return true; + } const blink::MediaStreamDevice& device = optional_device.value(); if (device.type != blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE && device.type != blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE) { @@ -1153,8 +1160,9 @@ // Create first group of streams. size_t generated_streams = 3; - for (size_t i = 0; i < generated_streams; ++i) + for (size_t i = 0; i < generated_streams; ++i) { GenerateStreamAndWaitForResult(kPageRequestId + i, controls, expectation); + } media_stream_manager_->CancelAllRequests(kProcessId, kRenderId, kRequesterId); base::RunLoop().RunUntilIdle();
diff --git a/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc b/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc new file mode 100644 index 0000000..20f6fda4 --- /dev/null +++ b/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc
@@ -0,0 +1,1425 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/scoped_feature_list.h" +#include "content/browser/renderer_host/frame_tree.h" +#include "content/browser/renderer_host/navigation_controller_impl.h" +#include "content/browser/renderer_host/navigation_request.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/features.h" +#include "content/public/test/back_forward_cache_util.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "content/shell/browser/shell.h" +#include "content/shell/common/shell_switches.h" +#include "content/test/content_browser_test_utils_internal.h" +#include "content/test/render_document_feature.h" +#include "net/dns/mock_host_resolver.h" + +namespace content { + +namespace { + +// Does a renderer-initiated location.replace navigation to |url|, replacing the +// current entry. +bool RendererLocationReplace(Shell* shell, const GURL& url) { + WebContents* web_contents = shell->web_contents(); + WaitForLoadStop(web_contents); + TestNavigationManager navigation_manager(web_contents, url); + const GURL& current_url = + web_contents->GetPrimaryMainFrame()->GetLastCommittedURL(); + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. + EXPECT_TRUE(ExecJs(shell, JsReplace("window.location.replace($1)", url), + EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); + // Observe pending entry if it's not a same-document navigation. We can't + // observe same-document navigations because it might finish in the renderer, + // only telling the browser side at the end. + if (!current_url.EqualsIgnoringRef(url)) { + EXPECT_TRUE(navigation_manager.WaitForRequestStart()); + EXPECT_TRUE( + NavigationRequest::From(navigation_manager.GetNavigationHandle()) + ->common_params() + .should_replace_current_entry); + } + EXPECT_TRUE(navigation_manager.WaitForNavigationFinished()); + if (!IsLastCommittedEntryOfPageType(web_contents, PAGE_TYPE_NORMAL)) { + return false; + } + return web_contents->GetLastCommittedURL() == url; +} + +} // namespace + +class NavigationControllerHistoryInterventionBrowserTest + : public ContentBrowserTest, + public ::testing::WithParamInterface< + std::tuple<std::string /* render_document_level */, + bool /* enable_back_forward_cache*/>> { + public: + NavigationControllerHistoryInterventionBrowserTest() { + feature_list_.InitWithFeaturesAndParameters( + {{kQueueNavigationsWhileWaitingForCommit, {{"level", "full"}}}}, {}); + InitAndEnableRenderDocumentFeature(&feature_list_for_render_document_, + std::get<0>(GetParam())); + InitBackForwardCacheFeature(&feature_list_for_back_forward_cache_, + std::get<1>(GetParam())); + } + + // Provides meaningful param names instead of /0, /1, ... + static std::string DescribeParams( + const testing::TestParamInfo<ParamType>& info) { + auto [render_document_level, enable_back_forward_cache] = info.param; + return base::StringPrintf( + "%s_%s", + GetRenderDocumentLevelNameForTestParams(render_document_level).c_str(), + enable_back_forward_cache ? "BFCacheEnabled" : "BFCacheDisabled"); + } + + protected: + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + content::SetupCrossSiteRedirector(embedded_test_server()); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + ContentBrowserTest::SetUpCommandLine(command_line); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kExposeInternalsForTesting); + } + + private: + base::test::ScopedFeatureList feature_list_; + base::test::ScopedFeatureList feature_list_for_render_document_; + base::test::ScopedFeatureList feature_list_for_back_forward_cache_; +}; + +// Tests that the navigation entry is marked as skippable on back/forward button +// if it does a renderer initiated navigation without ever getting a user +// activation. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkipOnBackForward) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + EXPECT_TRUE(controller.CanGoBack()); + // Attempt to go back or forward to the skippable entry should log the + // corresponding histogram and skip the corresponding entry. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Same as the above test except the navigation is cross-site in this case. +// Tests that the navigation entry is marked as skippable on back/forward button +// if it does a renderer initiated cross-site navigation without ever getting a +// user activation. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkipOnBackForwardCrossSite) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new cross-site document from the renderer with a user + // gesture. + GURL redirected_url( + embedded_test_server()->GetURL("foo.com", "/title1.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + EXPECT_TRUE(controller.CanGoBack()); + // Attempt to go back or forward to the skippable entry should log the + // corresponding histogram and skip the corresponding entry. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Tests that when a navigation entry is not marked as skippable the first time +// it redirects because of user activation, that entry will be marked skippable +// if it does another redirect without user activation after the user has come +// back to that document again. This implies that a single user activation does +// not mean that the user can be infintely trapped. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationAfterReturningSetsSkippable) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL initially_non_skippable_url( + embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), initially_non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Get a user activation and navigate to a new same-site document from the + // renderer with a user gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE(NavigateToURLFromRenderer(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have not been marked as skippable. + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Navigate back to the earlier document's entry. + { + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + } + EXPECT_EQ(initially_non_skippable_url, + controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable due to the lack of + // activation on this visit, despite not being marked skippable last time. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Going back now should skip the entry at [1]. + ASSERT_TRUE(controller.CanGoBack()); + { + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + } + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Tests that the navigation entry is marked as skippable on back button if it +// does a renderer initiated navigation without ever getting a user activation. +// Also tests this for an entry added using history.pushState. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkippableMultipleGoBack) { + GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + // Use the pushState API to add another entry without user gesture. + GURL push_state_url(embedded_test_server()->GetURL("/title2.html")); + std::string script("history.pushState('', '','" + push_state_url.spec() + + "');"); + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last 2 entries should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // CanGoBack should return false since all previous entries are skippable. + EXPECT_FALSE(controller.CanGoBack()); +} + +// Same as above but tests the metrics on going forward. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkippableMultipleGoForward) { + GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + // Use the pushState API to add another entry without user gesture. + GURL push_state_url(embedded_test_server()->GetURL("/title2.html")); + std::string script("history.pushState('', '','" + push_state_url.spec() + + "');"); + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last 2 entries should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); +} + +// Tests that if an entry is marked as skippable, it will not be reset if there +// is a navigation to this entry again (crbug.com/112129). +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + DoNotResetSkipOnBackForward) { + GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Go back to the last entry. + TestNavigationObserver back_nav_load_observer(shell()->web_contents()); + controller.GoToIndex(0); + back_nav_load_observer.Wait(); + + // Going back again to an entry should not reset its skippable flag. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + + // Navigating away from this with a browser initiated navigation should log a + // histogram with skippable as true. + GURL url1(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE(NavigateToURL(shell(), url1)); +} + +// Tests that if an entry is marked as skippable, it will not be reset if there +// is a navigation to this entry again (crbug.com/1121293) using history.back/ +// forward. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + DoNotResetSkipOnHistoryBackAPI) { + GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Go back to the last entry using history.back. + EXPECT_TRUE( + ExecJs(shell(), "history.back();", EXECUTE_SCRIPT_NO_USER_GESTURE)); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + + // Going back again to an entry should not reset its skippable flag. + EXPECT_TRUE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Tests that if a navigation entry is marked as skippable due to pushState then +// the flag should be reset if there is a user gesture on this document. All of +// the adjacent entries belonging to the same document will have their skippable +// bits reset. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + OnUserGestureResetSameDocumentEntriesSkipFlag) { + GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + + // Redirect to another page without a user gesture. + GURL redirected_url(embedded_test_server()->GetURL("/empty.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + + // Use the pushState API to add another entry without user gesture. + GURL push_state_url1(embedded_test_server()->GetURL("/title1.html")); + std::string script("history.pushState('', '','" + push_state_url1.spec() + + "');"); + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + // Use the pushState API to add another entry without user gesture. + GURL push_state_url2(embedded_test_server()->GetURL("/title2.html")); + script = "history.pushState('', '','" + push_state_url2.spec() + "');"; + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + EXPECT_EQ(3, controller.GetCurrentEntryIndex()); + EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); + + // We now have + // [skippable_url(skip), redirected_url(skip), push_state_url1(skip), + // push_state_url2*] + // Last 2 entries should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL()); + EXPECT_EQ(push_state_url2, controller.GetEntryAtIndex(3)->GetURL()); + + // Do another pushState so push_state_url2's entry also becomes skippable. + GURL push_state_url3(embedded_test_server()->GetURL("/title3.html")); + script = "history.pushState('', '','" + push_state_url3.spec() + "');"; + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + // We now have + // [skippable_url(skip), redirected_url(skip), push_state_url1(skip), + // push_state_url2(skip), push_state_url3*] + + // Go to index 2. + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoToIndex(2); + load_observer.Wait(); + EXPECT_EQ(push_state_url1, controller.GetLastCommittedEntry()->GetURL()); + + // We now have (Before user gesture) + // [skippable_url(skip), redirected_url(skip), push_state_url1(skip)*, + // push_state_url2(skip), push_state_url3] + // Note the entry at index 2 retains its skippable flag. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + + // Simulate a user gesture. ExecuteScript internally also sends a user + // gesture. + script = "a=5"; + EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script)); + + // We now have (After user gesture) + // [skippable_url(skip), redirected_url, push_state_url1*, push_state_url2, + // push_state_url3] + // All the navigations that refer to the same document should have their + // skippable bit reset. + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + // The first entry is not the same document and its bit should not be reset. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + + // goBack should now navigate to entry at index 1. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL()); + + // Do another pushState without user gesture. + GURL push_state_url4(embedded_test_server()->GetURL("/title3.html")); + script = "history.pushState('', '','" + push_state_url3.spec() + "');"; + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + // We now have + // [skippable_url(skip), redirected_url, push_state_url4*] + EXPECT_EQ(3, controller.GetEntryCount()); + EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_EQ(push_state_url4, controller.GetEntryAtIndex(2)->GetURL()); + // The skippable flag will still be unset since this page has seen a user + // gesture once. + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); +} + +class NavigationControllerDebugHistoryInterventionNoUserActivation + : public NavigationControllerHistoryInterventionBrowserTest { + protected: + void SetUp() override { + feature_list_.InitAndEnableFeature( + features::kDebugHistoryInterventionNoUserActivation); + NavigationControllerHistoryInterventionBrowserTest::SetUp(); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Tests that if a navigation entry is marked as skippable due to pushState then +// the flag is not reset even if there is a user gesture on this document, when +// the debug flag is enabled. This is to check the case where there wasn't +// actually a user gesture but one is being reported somehow. +// (See crbug.com/1201355) +IN_PROC_BROWSER_TEST_P( + NavigationControllerDebugHistoryInterventionNoUserActivation, + OnUserGestureDoNotResetSameDocumentEntriesSkipFlag) { + GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + + // Redirect to another page without a user gesture. + GURL redirected_url(embedded_test_server()->GetURL("/empty.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + + // Use the pushState API to add another entry without user gesture. + GURL push_state_url1(embedded_test_server()->GetURL("/title1.html")); + std::string script("history.pushState('', '','" + push_state_url1.spec() + + "');"); + EXPECT_TRUE( + ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // We now have + // [skippable_url(skip), redirected_url(skip), push_state_url1*] + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL()); + + // Simulate a user gesture. ExecuteScript internally also sends a user + // gesture. The skippable bit for [1] should not have changed because of the + // DebugHistoryInterventionNoUserActivation flag. + script = "a=5"; + EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script)); + + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); +} + +// Tests that if a navigation entry is marked as skippable due to redirect to a +// new document then the flag should not be reset if there is a user gesture on +// the new document. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + OnUserGestureDoNotResetDifferentDocumentEntrySkipFlag) { + GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Simulate a user gesture. + root->UpdateUserActivationState( + blink::mojom::UserActivationUpdateType::kNotifyActivation, + blink::mojom::UserActivationNotificationType::kTest); + + // Since the last navigations refer to a different document, a user gesture + // here should not reset the skippable bit in the previous entries. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); +} + +// Tests that the navigation entry is not marked as skippable on back/forward +// button if it does a renderer initiated navigation after getting a user +// activation. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + UserActivationDoNotSkipOnBackForward) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer. + // Note that NavigateToURLFromRenderer also simulates a user gesture. + GURL user_gesture_redirected_url( + embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURLFromRenderer(shell(), user_gesture_redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + // Last entry should not have been marked as skippable. + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Nothing should get skipped when back button is clicked. + TestNavigationObserver back_nav_load_observer(shell()->web_contents()); + controller.GoBack(); + back_nav_load_observer.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Tests that the navigation entry should not be marked as skippable on +// back/forward button if it is navigated away using a browser initiated +// navigation. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + BrowserInitiatedNavigationDoNotSkipOnBackForward) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + GURL url(embedded_test_server()->GetURL("/title1.html")); + + // Note that NavigateToURL simulates a browser initiated navigation. + EXPECT_TRUE(NavigateToURL(shell(), url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + + // Last entry should not have been marked as skippable. + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Nothing should get skipped when back button is clicked. + TestNavigationObserver back_nav_load_observer(shell()->web_contents()); + controller.GoBack(); + back_nav_load_observer.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); +} + +// Tests that the navigation entry that is marked as skippable on back/forward +// button does not get skipped for history.back API calls. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + SetSkipOnBackDoNotSkipForHistoryBackAPI) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // Attempt to go back to the skippable entry using the History API should + // not skip the corresponding entry. + TestNavigationObserver frame_observer(shell()->web_contents()); + EXPECT_TRUE(ExecJs(root, "window.history.back()")); + frame_observer.Wait(); + + EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); +} + +#if BUILDFLAG(IS_ANDROID) +// Test GoToOffset with enable history intervention. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + GoToOffsetWithSkippingEnableHistoryIntervention) { + base::HistogramTester histograms; + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); + + // CanGoToOffset should visit the skippable entries while + // CanGoToOffsetWithSKipping will skip the skippable entries. + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_TRUE(controller.CanGoToOffset(-3)); + EXPECT_TRUE(controller.CanGoToOffset(-4)); + EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3)); + + TestNavigationObserver nav_observer(shell()->web_contents()); + controller.GoToOffset(-4); + nav_observer.Wait(); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); +} +#endif // BUILDFLAG(IS_ANDROID) + +// Tests that the navigation entry that is marked as skippable on back/forward +// button does not get skipped for GoToOffset calls. +// This covers actions in the following scenario: +// [non_skippable_url, skippable_url, redirected_url, skippable_url2, +// redirected_url2] +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + SetSkipOnBackForwardDoNotSkipForGoToOffset) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + + EXPECT_TRUE(controller.CanGoToOffset(-3)); + + // GoToOffset should visit the skippable entries. + TestNavigationObserver nav_observer1(shell()->web_contents()); + controller.GoToOffset(-1); + nav_observer1.Wait(); + EXPECT_EQ(3, controller.GetCurrentEntryIndex()); + EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(skippable_url2, controller.GetLastCommittedEntry()->GetURL()); + + TestNavigationObserver nav_observer2(shell()->web_contents()); + controller.GoToOffset(1); + nav_observer2.Wait(); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); + + TestNavigationObserver nav_observer3(shell()->web_contents()); + controller.GoToOffset(-4); + nav_observer3.Wait(); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + + EXPECT_TRUE(controller.CanGoToOffset(4)); + + TestNavigationObserver nav_observer4(shell()->web_contents()); + controller.GoToOffset(4); + nav_observer4.Wait(); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); +} + +// Tests that the navigation entry that is marked as skippable on back/forward +// button is skipped for GoToOffset calls. +// This covers actions in the following scenario: +// [non_skippable_url, skippable_url, redirected_url, skippable_url2, +// redirected_url2] +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + SetSkipOnBackForwardDoSkipForGoToOffsetWithSkipping) { +#if BUILDFLAG(IS_ANDROID) + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + + EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3)); + EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(-2)); + + // GoToOffset should skip the skippable entries. + TestNavigationObserver nav_observer1(shell()->web_contents()); + controller.GoToOffsetWithSkipping(-1); + nav_observer1.Wait(); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL()); + + TestNavigationObserver nav_observer2(shell()->web_contents()); + controller.GoToOffsetWithSkipping(1); + nav_observer2.Wait(); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); + + TestNavigationObserver nav_observer3(shell()->web_contents()); + controller.GoToOffsetWithSkipping(-2); + nav_observer3.Wait(); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + + EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(3)); + EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(2)); + + TestNavigationObserver nav_observer4(shell()->web_contents()); + controller.GoToOffsetWithSkipping(2); + nav_observer4.Wait(); + EXPECT_EQ(4, controller.GetCurrentEntryIndex()); + EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); +#endif // BUILDFLAG(IS_ANDROID) +} + +// Tests that the navigation entry that is marked as skippable on back/forward +// button does not get skipped for history.forward API calls. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + SetSkipOnBackDoNotSkipForHistoryForwardAPI) { + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + // Last entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + TestNavigationObserver nav_observer1(shell()->web_contents()); + controller.GoToIndex(0); + nav_observer1.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + + // Attempt to go forward to the skippable entry using the History API should + // not skip the corresponding entry. + TestNavigationObserver nav_observer2(shell()->web_contents()); + EXPECT_TRUE(ExecJs(root, "window.history.forward()")); + nav_observer2.Wait(); + + EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); +} + +// Tests that the oldest navigation entry that is marked as skippable is the one +// that is pruned if max entry count is reached. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + PruneOldestSkippableEntry) { + // Set the max entry count as 3. + NavigationControllerImpl::set_max_entry_count_for_testing(3); + + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(3, controller.GetEntryCount()); + EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(2)->GetURL()); + + // |skippable_url| entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); + + // A new navigation should lead to |skippable_url| to be pruned. + GURL new_navigation_url(embedded_test_server()->GetURL("/title3.html")); + EXPECT_TRUE(NavigateToURL(shell(), new_navigation_url)); + // Should still have 3 entries. + EXPECT_EQ(3, controller.GetEntryCount()); + EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_EQ(new_navigation_url, controller.GetEntryAtIndex(2)->GetURL()); +} + +// Tests that we fallback to pruning the oldest entry if the last committed +// entry is the oldest skippable navigation entry. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + PruneOldestWhenLastCommittedIsSkippable) { + // Set the max entry count as 2. + NavigationControllerImpl::set_max_entry_count_for_testing(2); + + GURL non_skippable_url( + embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Navigate to a new same-site document from the renderer without a user + // gesture. This will mark |skippable_url| as skippable but since that is also + // the last committed entry, it will not be pruned. Instead the oldest entry + // will be removed. + GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); + EXPECT_TRUE( + NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(2, controller.GetEntryCount()); + EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); + + // |skippable_url| entry should have been marked as skippable. + EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE( + controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); +} + +// Tests that the navigation entry is marked as skippable on back/forward +// button if a subframe does a push state without ever getting a user +// activation. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkipOnBackForwardSubframe) { + GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + GURL skippable_url( + embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Invoke pushstate from a subframe. + std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')"; + EXPECT_TRUE( + ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + + EXPECT_TRUE(controller.CanGoBack()); + + // Attempt to go back or forward to the skippable entry should log the + // corresponding histogram and skip the corresponding entry. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + + // Go forward to the 3rd entry. + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoToIndex(2); + load_observer.Wait(); + + // A user gesture in the main frame now will lead to all same document + // entries to be marked as non-skippable. + root->UpdateUserActivationState( + blink::mojom::UserActivationUpdateType::kNotifyActivation, + blink::mojom::UserActivationNotificationType::kTest); + EXPECT_TRUE(root->HasStickyUserActivation()); + EXPECT_TRUE(root->HasTransientUserActivation()); + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); +} + +// Tests that the navigation entry is not marked as skippable on back/forward +// button if a subframe does a push state without ever getting a user +// activation on itself but there was a user gesture on the main frame. +IN_PROC_BROWSER_TEST_P( + NavigationControllerHistoryInterventionBrowserTest, + UserActivationMainFrameDoNotSetSkipOnBackForwardSubframe) { + GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + GURL url_with_frames( + embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); + EXPECT_TRUE(NavigateToURL(shell(), url_with_frames)); + + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Simulate user gesture in the main frame. Subframes creating entries without + // user gesture will not lead to the last committed entry being marked as + // skippable. + root->UpdateUserActivationState( + blink::mojom::UserActivationUpdateType::kNotifyActivation, + blink::mojom::UserActivationNotificationType::kTest); + EXPECT_TRUE(root->HasStickyUserActivation()); + EXPECT_TRUE(root->HasTransientUserActivation()); + + // Invoke pushstate from a subframe. + std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')"; + EXPECT_TRUE( + ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); +} + +// Tests that all same document entries are marked as skippable together. +IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, + SetSkipOnBackForwardSameDocumentEntries) { + // Consider the case: + // 1. [Z, A, (click), A#1, A#2, A#3, A#4, B] + // At this time all of A and A#1 through A#4 are non-skippable due to the + // click. + // 2. Let A#3 do a location.replace to another document + // [Z, A, A#1, A#2, Y, A#4, B] + // 3. Go to A#4, which is now the "current entry". All As are still + // non-skippable. + // 4. Let it now redirect without any user gesture to C. + // [Z, A, A#1, A#2, Y, A#4, C] + // At this time all of A entries should be marked as skippable. + // 5. Go back should skip A's and go to Z. + + GURL z_url(embedded_test_server()->GetURL("/empty.html")); + EXPECT_TRUE(NavigateToURL(shell(), z_url)); + + GURL a_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), a_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + EXPECT_FALSE(root->HasStickyUserActivation()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + + // Add the 2 pushstate entries. Note that ExecuteScript also sends a user + // gesture. + GURL a1_url(embedded_test_server()->GetURL("/title2.html")); + GURL a2_url(embedded_test_server()->GetURL("/title3.html")); + GURL a3_url(embedded_test_server()->GetURL( + "/navigation_controller/simple_page_1.html")); + GURL a4_url(embedded_test_server()->GetURL( + "/navigation_controller/simple_page_2.html")); + std::string script("history.pushState('', '','" + a1_url.spec() + "');"); + ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); + script = "history.pushState('', '','" + a2_url.spec() + "');"; + ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); + script = "history.pushState('', '','" + a3_url.spec() + "');"; + ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); + script = "history.pushState('', '','" + a4_url.spec() + "');"; + ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); + + EXPECT_TRUE(root->HasStickyUserActivation()); + EXPECT_TRUE(root->HasTransientUserActivation()); + + // None of the entries should be skippable. + EXPECT_EQ(6, controller.GetEntryCount()); + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); + + // Navigate to B. + GURL b_url(embedded_test_server()->GetURL("/empty.html")); + EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url)); + + // Go back to a3_url and do location.replace. + { + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoToOffset(-2); + load_observer.Wait(); + } + EXPECT_EQ(a3_url, controller.GetLastCommittedEntry()->GetURL()); + GURL y_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + ASSERT_TRUE(RendererLocationReplace(shell(), y_url)); + + EXPECT_EQ(7, controller.GetEntryCount()); + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui()); + + // Go forward to a4_url. + { + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoForward(); + load_observer.Wait(); + } + EXPECT_EQ(a4_url, controller.GetLastCommittedEntry()->GetURL()); + + // Redirect without user gesture to C. + GURL c_url(embedded_test_server()->GetURL("/frame_tree/top.html")); + EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), c_url)); + + // All entries belonging to A should be marked skippable. + EXPECT_EQ(7, controller.GetEntryCount()); + EXPECT_EQ(a_url, controller.GetEntryAtIndex(1)->GetURL()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + + EXPECT_EQ(a1_url, controller.GetEntryAtIndex(2)->GetURL()); + EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + + EXPECT_EQ(a2_url, controller.GetEntryAtIndex(3)->GetURL()); + EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); + + EXPECT_EQ(y_url, controller.GetEntryAtIndex(4)->GetURL()); + EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); + + EXPECT_EQ(a4_url, controller.GetEntryAtIndex(5)->GetURL()); + EXPECT_TRUE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); + + EXPECT_EQ(c_url, controller.GetEntryAtIndex(6)->GetURL()); + EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui()); + + // Go back should skip all A entries and go to Y. + { + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoBack(); + load_observer.Wait(); + } + EXPECT_EQ(y_url, controller.GetLastCommittedEntry()->GetURL()); + + // Going back again should skip all A entries and go to Z. + { + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoBack(); + load_observer.Wait(); + } + EXPECT_EQ(z_url, controller.GetLastCommittedEntry()->GetURL()); +} + +INSTANTIATE_TEST_SUITE_P( + All, + NavigationControllerHistoryInterventionBrowserTest, + testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()), + testing::Bool()), + NavigationControllerHistoryInterventionBrowserTest::DescribeParams); +INSTANTIATE_TEST_SUITE_P( + All, + NavigationControllerDebugHistoryInterventionNoUserActivation, + testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()), + testing::Bool()), + NavigationControllerHistoryInterventionBrowserTest::DescribeParams); + +} // namespace content
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index 8d1b3bf..b5c2b4e78 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -163,19 +163,6 @@ base::test::ScopedFeatureList feature_list_; }; -void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list, - bool enable_back_forward_cache) { - if (enable_back_forward_cache) { - feature_list->InitWithFeaturesAndParameters( - GetBasicBackForwardCacheFeatureForTesting( - {{kBackForwardCacheNoTimeEviction, {}}, - {features::kBackForwardCacheMemoryControls, {}}}), - {}); - } else { - feature_list->InitAndDisableFeature(features::kBackForwardCache); - } -} - class NavigationControllerBrowserTest : public NavigationControllerBrowserTestBase, public ::testing::WithParamInterface< @@ -17383,9 +17370,6 @@ EXPECT_EQ(url3, contents()->GetLastCommittedURL()); } -using NavigationControllerHistoryInterventionBrowserTest = - NavigationControllerBrowserTest; - // Test to verify that after loading a post-commit error page, back is treated // as navigating to the entry prior to the page that was active when the // post-commit error page was triggered. @@ -17518,1316 +17502,6 @@ EXPECT_EQ(1, new_controller.GetEntryCount()); } -// Tests that the navigation entry is marked as skippable on back/forward button -// if it does a renderer initiated navigation without ever getting a user -// activation. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationSetSkipOnBackForward) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - EXPECT_TRUE(controller.CanGoBack()); - // Attempt to go back or forward to the skippable entry should log the - // corresponding histogram and skip the corresponding entry. - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Same as the above test except the navigation is cross-site in this case. -// Tests that the navigation entry is marked as skippable on back/forward button -// if it does a renderer initiated cross-site navigation without ever getting a -// user activation. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationSetSkipOnBackForwardCrossSite) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new cross-site document from the renderer with a user - // gesture. - GURL redirected_url( - embedded_test_server()->GetURL("foo.com", "/title1.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - EXPECT_TRUE(controller.CanGoBack()); - // Attempt to go back or forward to the skippable entry should log the - // corresponding histogram and skip the corresponding entry. - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Tests that when a navigation entry is not marked as skippable the first time -// it redirects because of user activation, that entry will be marked skippable -// if it does another redirect without user activation after the user has come -// back to that document again. This implies that a single user activation does -// not mean that the user can be infintely trapped. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationAfterReturningSetsSkippable) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL initially_non_skippable_url( - embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), initially_non_skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Get a user activation and navigate to a new same-site document from the - // renderer with a user gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE(NavigateToURLFromRenderer(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have not been marked as skippable. - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Navigate back to the earlier document's entry. - { - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - } - EXPECT_EQ(initially_non_skippable_url, - controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable due to the lack of - // activation on this visit, despite not being marked skippable last time. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Going back now should skip the entry at [1]. - ASSERT_TRUE(controller.CanGoBack()); - { - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - } - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Tests that the navigation entry is marked as skippable on back button if it -// does a renderer initiated navigation without ever getting a user activation. -// Also tests this for an entry added using history.pushState. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationSetSkippableMultipleGoBack) { - GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - // Use the pushState API to add another entry without user gesture. - GURL push_state_url(embedded_test_server()->GetURL("/title2.html")); - std::string script("history.pushState('', '','" + push_state_url.spec() + - "');"); - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last 2 entries should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // CanGoBack should return false since all previous entries are skippable. - EXPECT_FALSE(controller.CanGoBack()); -} - -// Same as above but tests the metrics on going forward. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationSetSkippableMultipleGoForward) { - GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - // Use the pushState API to add another entry without user gesture. - GURL push_state_url(embedded_test_server()->GetURL("/title2.html")); - std::string script("history.pushState('', '','" + push_state_url.spec() + - "');"); - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last 2 entries should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); -} - -// Tests that if an entry is marked as skippable, it will not be reset if there -// is a navigation to this entry again (crbug.com/112129). -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - DoNotResetSkipOnBackForward) { - GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Go back to the last entry. - TestNavigationObserver back_nav_load_observer(shell()->web_contents()); - controller.GoToIndex(0); - back_nav_load_observer.Wait(); - - // Going back again to an entry should not reset its skippable flag. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - - // Navigating away from this with a browser initiated navigation should log a - // histogram with skippable as true. - GURL url1(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE(NavigateToURL(shell(), url1)); -} - -// Tests that if an entry is marked as skippable, it will not be reset if there -// is a navigation to this entry again (crbug.com/1121293) using history.back/ -// forward. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - DoNotResetSkipOnHistoryBackAPI) { - GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Go back to the last entry using history.back. - EXPECT_TRUE( - ExecJs(shell(), "history.back();", EXECUTE_SCRIPT_NO_USER_GESTURE)); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); - - // Going back again to an entry should not reset its skippable flag. - EXPECT_TRUE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Tests that if a navigation entry is marked as skippable due to pushState then -// the flag should be reset if there is a user gesture on this document. All of -// the adjacent entries belonging to the same document will have their skippable -// bits reset. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - OnUserGestureResetSameDocumentEntriesSkipFlag) { - GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - - // Redirect to another page without a user gesture. - GURL redirected_url(embedded_test_server()->GetURL("/empty.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - - // Use the pushState API to add another entry without user gesture. - GURL push_state_url1(embedded_test_server()->GetURL("/title1.html")); - std::string script("history.pushState('', '','" + push_state_url1.spec() + - "');"); - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - // Use the pushState API to add another entry without user gesture. - GURL push_state_url2(embedded_test_server()->GetURL("/title2.html")); - script = "history.pushState('', '','" + push_state_url2.spec() + "');"; - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - EXPECT_EQ(3, controller.GetCurrentEntryIndex()); - EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); - - // We now have - // [skippable_url(skip), redirected_url(skip), push_state_url1(skip), - // push_state_url2*] - // Last 2 entries should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL()); - EXPECT_EQ(push_state_url2, controller.GetEntryAtIndex(3)->GetURL()); - - // Do another pushState so push_state_url2's entry also becomes skippable. - GURL push_state_url3(embedded_test_server()->GetURL("/title3.html")); - script = "history.pushState('', '','" + push_state_url3.spec() + "');"; - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - // We now have - // [skippable_url(skip), redirected_url(skip), push_state_url1(skip), - // push_state_url2(skip), push_state_url3*] - - // Go to index 2. - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoToIndex(2); - load_observer.Wait(); - EXPECT_EQ(push_state_url1, controller.GetLastCommittedEntry()->GetURL()); - - // We now have (Before user gesture) - // [skippable_url(skip), redirected_url(skip), push_state_url1(skip)*, - // push_state_url2(skip), push_state_url3] - // Note the entry at index 2 retains its skippable flag. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - - // Simulate a user gesture. ExecuteScript internally also sends a user - // gesture. - script = "a=5"; - EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script)); - - // We now have (After user gesture) - // [skippable_url(skip), redirected_url, push_state_url1*, push_state_url2, - // push_state_url3] - // All the navigations that refer to the same document should have their - // skippable bit reset. - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - // The first entry is not the same document and its bit should not be reset. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - - // goBack should now navigate to entry at index 1. - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL()); - - // Do another pushState without user gesture. - GURL push_state_url4(embedded_test_server()->GetURL("/title3.html")); - script = "history.pushState('', '','" + push_state_url3.spec() + "');"; - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - // We now have - // [skippable_url(skip), redirected_url, push_state_url4*] - EXPECT_EQ(3, controller.GetEntryCount()); - EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_EQ(push_state_url4, controller.GetEntryAtIndex(2)->GetURL()); - // The skippable flag will still be unset since this page has seen a user - // gesture once. - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); -} - -class NavigationControllerDebugHistoryInterventionNoUserActivation - : public NavigationControllerBrowserTest { - protected: - void SetUp() override { - feature_list_.InitAndEnableFeature( - features::kDebugHistoryInterventionNoUserActivation); - NavigationControllerBrowserTest::SetUp(); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -// Tests that if a navigation entry is marked as skippable due to pushState then -// the flag is not reset even if there is a user gesture on this document, when -// the debug flag is enabled. This is to check the case where there wasn't -// actually a user gesture but one is being reported somehow. -// (See crbug.com/1201355) -IN_PROC_BROWSER_TEST_P( - NavigationControllerDebugHistoryInterventionNoUserActivation, - OnUserGestureDoNotResetSameDocumentEntriesSkipFlag) { - GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - - // Redirect to another page without a user gesture. - GURL redirected_url(embedded_test_server()->GetURL("/empty.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - - // Use the pushState API to add another entry without user gesture. - GURL push_state_url1(embedded_test_server()->GetURL("/title1.html")); - std::string script("history.pushState('', '','" + push_state_url1.spec() + - "');"); - EXPECT_TRUE( - ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // We now have - // [skippable_url(skip), redirected_url(skip), push_state_url1*] - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL()); - - // Simulate a user gesture. ExecuteScript internally also sends a user - // gesture. The skippable bit for [1] should not have changed because of the - // DebugHistoryInterventionNoUserActivation flag. - script = "a=5"; - EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script)); - - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); -} - -// Tests that if a navigation entry is marked as skippable due to redirect to a -// new document then the flag should not be reset if there is a user gesture on -// the new document. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - OnUserGestureDoNotResetDifferentDocumentEntrySkipFlag) { - GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Simulate a user gesture. - root->UpdateUserActivationState( - blink::mojom::UserActivationUpdateType::kNotifyActivation, - blink::mojom::UserActivationNotificationType::kTest); - - // Since the last navigations refer to a different document, a user gesture - // here should not reset the skippable bit in the previous entries. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); -} - -// Tests that the navigation entry is not marked as skippable on back/forward -// button if it does a renderer initiated navigation after getting a user -// activation. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - UserActivationDoNotSkipOnBackForward) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer. - // Note that NavigateToURLFromRenderer also simulates a user gesture. - GURL user_gesture_redirected_url( - embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURLFromRenderer(shell(), user_gesture_redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - // Last entry should not have been marked as skippable. - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Nothing should get skipped when back button is clicked. - TestNavigationObserver back_nav_load_observer(shell()->web_contents()); - controller.GoBack(); - back_nav_load_observer.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Tests that the navigation entry should not be marked as skippable on -// back/forward button if it is navigated away using a browser initiated -// navigation. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - BrowserInitiatedNavigationDoNotSkipOnBackForward) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - GURL url(embedded_test_server()->GetURL("/title1.html")); - - // Note that NavigateToURL simulates a browser initiated navigation. - EXPECT_TRUE(NavigateToURL(shell(), url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - - // Last entry should not have been marked as skippable. - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Nothing should get skipped when back button is clicked. - TestNavigationObserver back_nav_load_observer(shell()->web_contents()); - controller.GoBack(); - back_nav_load_observer.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); -} - -// Tests that the navigation entry that is marked as skippable on back/forward -// button does not get skipped for history.back API calls. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - SetSkipOnBackDoNotSkipForHistoryBackAPI) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // Attempt to go back to the skippable entry using the History API should - // not skip the corresponding entry. - TestNavigationObserver frame_observer(shell()->web_contents()); - EXPECT_TRUE(ExecJs(root, "window.history.back()")); - frame_observer.Wait(); - - EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); -} - -#if BUILDFLAG(IS_ANDROID) -// Test GoToOffset with enable history intervention. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - GoToOffsetWithSkippingEnableHistoryIntervention) { - base::HistogramTester histograms; - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); - - // CanGoToOffset should visit the skippable entries while - // CanGoToOffsetWithSKipping will skip the skippable entries. - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_TRUE(controller.CanGoToOffset(-3)); - EXPECT_TRUE(controller.CanGoToOffset(-4)); - EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3)); - - TestNavigationObserver nav_observer(shell()->web_contents()); - controller.GoToOffset(-4); - nav_observer.Wait(); - EXPECT_EQ(0, controller.GetCurrentEntryIndex()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); -} -#endif // BUILDFLAG(IS_ANDROID) - -// Tests that the navigation entry that is marked as skippable on back/forward -// button does not get skipped for GoToOffset calls. -// This covers actions in the following scenario: -// [non_skippable_url, skippable_url, redirected_url, skippable_url2, -// redirected_url2] -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - SetSkipOnBackForwardDoNotSkipForGoToOffset) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - - EXPECT_TRUE(controller.CanGoToOffset(-3)); - - // GoToOffset should visit the skippable entries. - TestNavigationObserver nav_observer1(shell()->web_contents()); - controller.GoToOffset(-1); - nav_observer1.Wait(); - EXPECT_EQ(3, controller.GetCurrentEntryIndex()); - EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(skippable_url2, controller.GetLastCommittedEntry()->GetURL()); - - TestNavigationObserver nav_observer2(shell()->web_contents()); - controller.GoToOffset(1); - nav_observer2.Wait(); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); - - TestNavigationObserver nav_observer3(shell()->web_contents()); - controller.GoToOffset(-4); - nav_observer3.Wait(); - EXPECT_EQ(0, controller.GetCurrentEntryIndex()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - - EXPECT_TRUE(controller.CanGoToOffset(4)); - - TestNavigationObserver nav_observer4(shell()->web_contents()); - controller.GoToOffset(4); - nav_observer4.Wait(); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); -} - -// Tests that the navigation entry that is marked as skippable on back/forward -// button is skipped for GoToOffset calls. -// This covers actions in the following scenario: -// [non_skippable_url, skippable_url, redirected_url, skippable_url2, -// redirected_url2] -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - SetSkipOnBackForwardDoSkipForGoToOffsetWithSkipping) { -#if BUILDFLAG(IS_ANDROID) - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - GURL skippable_url2(embedded_test_server()->GetURL("/title3.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url2)); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url2(embedded_test_server()->GetURL("/title4.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - - EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3)); - EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(-2)); - - // GoToOffset should skip the skippable entries. - TestNavigationObserver nav_observer1(shell()->web_contents()); - controller.GoToOffsetWithSkipping(-1); - nav_observer1.Wait(); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL()); - - TestNavigationObserver nav_observer2(shell()->web_contents()); - controller.GoToOffsetWithSkipping(1); - nav_observer2.Wait(); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); - - TestNavigationObserver nav_observer3(shell()->web_contents()); - controller.GoToOffsetWithSkipping(-2); - nav_observer3.Wait(); - EXPECT_EQ(0, controller.GetCurrentEntryIndex()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - - EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(3)); - EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(2)); - - TestNavigationObserver nav_observer4(shell()->web_contents()); - controller.GoToOffsetWithSkipping(2); - nav_observer4.Wait(); - EXPECT_EQ(4, controller.GetCurrentEntryIndex()); - EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL()); -#endif // BUILDFLAG(IS_ANDROID) -} - -// Tests that the navigation entry that is marked as skippable on back/forward -// button does not get skipped for history.forward API calls. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - SetSkipOnBackDoNotSkipForHistoryForwardAPI) { - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - // Last entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - TestNavigationObserver nav_observer1(shell()->web_contents()); - controller.GoToIndex(0); - nav_observer1.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - - // Attempt to go forward to the skippable entry using the History API should - // not skip the corresponding entry. - TestNavigationObserver nav_observer2(shell()->web_contents()); - EXPECT_TRUE(ExecJs(root, "window.history.forward()")); - nav_observer2.Wait(); - - EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); -} - -// Tests that the oldest navigation entry that is marked as skippable is the one -// that is pruned if max entry count is reached. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - PruneOldestSkippableEntry) { - // Set the max entry count as 3. - NavigationControllerImpl::set_max_entry_count_for_testing(3); - - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(3, controller.GetEntryCount()); - EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(2)->GetURL()); - - // |skippable_url| entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); - - // A new navigation should lead to |skippable_url| to be pruned. - GURL new_navigation_url(embedded_test_server()->GetURL("/title3.html")); - EXPECT_TRUE(NavigateToURL(shell(), new_navigation_url)); - // Should still have 3 entries. - EXPECT_EQ(3, controller.GetEntryCount()); - EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_EQ(new_navigation_url, controller.GetEntryAtIndex(2)->GetURL()); -} - -// Tests that we fallback to pruning the oldest entry if the last committed -// entry is the oldest skippable navigation entry. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - PruneOldestWhenLastCommittedIsSkippable) { - // Set the max entry count as 2. - NavigationControllerImpl::set_max_entry_count_for_testing(2); - - GURL non_skippable_url( - embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - GURL skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Navigate to a new same-site document from the renderer without a user - // gesture. This will mark |skippable_url| as skippable but since that is also - // the last committed entry, it will not be pruned. Instead the oldest entry - // will be removed. - GURL redirected_url(embedded_test_server()->GetURL("/title2.html")); - EXPECT_TRUE( - NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); - EXPECT_EQ(2, controller.GetEntryCount()); - EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL()); - - // |skippable_url| entry should have been marked as skippable. - EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE( - controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui()); -} - -// Tests that the navigation entry is marked as skippable on back/forward -// button if a subframe does a push state without ever getting a user -// activation. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - NoUserActivationSetSkipOnBackForwardSubframe) { - GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - GURL skippable_url( - embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); - EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Invoke pushstate from a subframe. - std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')"; - EXPECT_TRUE( - ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - - EXPECT_TRUE(controller.CanGoBack()); - - // Attempt to go back or forward to the skippable entry should log the - // corresponding histogram and skip the corresponding entry. - TestNavigationObserver back_load_observer(shell()->web_contents()); - controller.GoBack(); - back_load_observer.Wait(); - EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); - EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); - - // Go forward to the 3rd entry. - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoToIndex(2); - load_observer.Wait(); - - // A user gesture in the main frame now will lead to all same document - // entries to be marked as non-skippable. - root->UpdateUserActivationState( - blink::mojom::UserActivationUpdateType::kNotifyActivation, - blink::mojom::UserActivationNotificationType::kTest); - EXPECT_TRUE(root->HasStickyUserActivation()); - EXPECT_TRUE(root->HasTransientUserActivation()); - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); -} - -// Tests that the navigation entry is not marked as skippable on back/forward -// button if a subframe does a push state without ever getting a user -// activation on itself but there was a user gesture on the main frame. -IN_PROC_BROWSER_TEST_P( - NavigationControllerHistoryInterventionBrowserTest, - UserActivationMainFrameDoNotSetSkipOnBackForwardSubframe) { - GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - - GURL url_with_frames( - embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); - EXPECT_TRUE(NavigateToURL(shell(), url_with_frames)); - - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - // Simulate user gesture in the main frame. Subframes creating entries without - // user gesture will not lead to the last committed entry being marked as - // skippable. - root->UpdateUserActivationState( - blink::mojom::UserActivationUpdateType::kNotifyActivation, - blink::mojom::UserActivationNotificationType::kTest); - EXPECT_TRUE(root->HasStickyUserActivation()); - EXPECT_TRUE(root->HasTransientUserActivation()); - - // Invoke pushstate from a subframe. - std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')"; - EXPECT_TRUE( - ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE)); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - EXPECT_EQ(2, controller.GetCurrentEntryIndex()); - EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); - - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); -} - -// Tests that all same document entries are marked as skippable together. -IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest, - SetSkipOnBackForwardSameDocumentEntries) { - // Consider the case: - // 1. [Z, A, (click), A#1, A#2, A#3, A#4, B] - // At this time all of A and A#1 through A#4 are non-skippable due to the - // click. - // 2. Let A#3 do a location.replace to another document - // [Z, A, A#1, A#2, Y, A#4, B] - // 3. Go to A#4, which is now the "current entry". All As are still - // non-skippable. - // 4. Let it now redirect without any user gesture to C. - // [Z, A, A#1, A#2, Y, A#4, C] - // At this time all of A entries should be marked as skippable. - // 5. Go back should skip A's and go to Z. - - GURL z_url(embedded_test_server()->GetURL("/empty.html")); - EXPECT_TRUE(NavigateToURL(shell(), z_url)); - - GURL a_url(embedded_test_server()->GetURL("/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), a_url)); - - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - EXPECT_FALSE(root->HasStickyUserActivation()); - EXPECT_FALSE(root->HasTransientUserActivation()); - - NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - - // Add the 2 pushstate entries. Note that ExecuteScript also sends a user - // gesture. - GURL a1_url(embedded_test_server()->GetURL("/title2.html")); - GURL a2_url(embedded_test_server()->GetURL("/title3.html")); - GURL a3_url(embedded_test_server()->GetURL( - "/navigation_controller/simple_page_1.html")); - GURL a4_url(embedded_test_server()->GetURL( - "/navigation_controller/simple_page_2.html")); - std::string script("history.pushState('', '','" + a1_url.spec() + "');"); - ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); - script = "history.pushState('', '','" + a2_url.spec() + "');"; - ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); - script = "history.pushState('', '','" + a3_url.spec() + "');"; - ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); - script = "history.pushState('', '','" + a4_url.spec() + "');"; - ASSERT_TRUE(ExecJs(shell()->web_contents(), script)); - - EXPECT_TRUE(root->HasStickyUserActivation()); - EXPECT_TRUE(root->HasTransientUserActivation()); - - // None of the entries should be skippable. - EXPECT_EQ(6, controller.GetEntryCount()); - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); - - // Navigate to B. - GURL b_url(embedded_test_server()->GetURL("/empty.html")); - EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url)); - - // Go back to a3_url and do location.replace. - { - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoToOffset(-2); - load_observer.Wait(); - } - EXPECT_EQ(a3_url, controller.GetLastCommittedEntry()->GetURL()); - GURL y_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - ASSERT_TRUE(RendererLocationReplace(shell(), y_url)); - - EXPECT_EQ(7, controller.GetEntryCount()); - EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); - EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui()); - - // Go forward to a4_url. - { - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoForward(); - load_observer.Wait(); - } - EXPECT_EQ(a4_url, controller.GetLastCommittedEntry()->GetURL()); - - // Redirect without user gesture to C. - GURL c_url(embedded_test_server()->GetURL("/frame_tree/top.html")); - EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), c_url)); - - // All entries belonging to A should be marked skippable. - EXPECT_EQ(7, controller.GetEntryCount()); - EXPECT_EQ(a_url, controller.GetEntryAtIndex(1)->GetURL()); - EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); - - EXPECT_EQ(a1_url, controller.GetEntryAtIndex(2)->GetURL()); - EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); - - EXPECT_EQ(a2_url, controller.GetEntryAtIndex(3)->GetURL()); - EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui()); - - EXPECT_EQ(y_url, controller.GetEntryAtIndex(4)->GetURL()); - EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui()); - - EXPECT_EQ(a4_url, controller.GetEntryAtIndex(5)->GetURL()); - EXPECT_TRUE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui()); - - EXPECT_EQ(c_url, controller.GetEntryAtIndex(6)->GetURL()); - EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui()); - - // Go back should skip all A entries and go to Y. - { - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoBack(); - load_observer.Wait(); - } - EXPECT_EQ(y_url, controller.GetLastCommittedEntry()->GetURL()); - - // Going back again should skip all A entries and go to Z. - { - TestNavigationObserver load_observer(shell()->web_contents()); - controller.GoBack(); - load_observer.Wait(); - } - EXPECT_EQ(z_url, controller.GetLastCommittedEntry()->GetURL()); -} - // Tests that a same document navigation followed by a client redirect // do not add any more session history entries and going to previous entry // works. @@ -18876,7 +17550,6 @@ class SandboxedNavigationControllerBrowserTest : public NavigationControllerBrowserTest { protected: - void SetupNavigation() { NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( @@ -19036,7 +17709,6 @@ class SandboxedNavigationControllerPopupBrowserTest : public NavigationControllerBrowserTest { protected: - void SetupNavigation() { EXPECT_EQ(1u, Shell::windows().size()); NavigationControllerImpl& controller = @@ -23113,7 +21785,7 @@ EXPECT_FALSE(webui_nav->HasRenderFrameHost()); EXPECT_TRUE(webui_nav->HasWebUI()); created_webui = webui_nav->web_ui(); - EXPECT_FALSE(created_webui->has_frame_host()); + EXPECT_FALSE(created_webui->HasRenderFrameHost()); // The pending commit RenderFrameHost for `url_2` is still around and // doesn't have a WebUI Object. @@ -23151,8 +21823,9 @@ EXPECT_TRUE(webui_nav->HasRenderFrameHost()); EXPECT_FALSE(webui_nav->HasWebUI()); EXPECT_EQ(created_webui, webui_nav->GetRenderFrameHost()->web_ui()); - EXPECT_TRUE(created_webui->has_frame_host()); - EXPECT_EQ(created_webui->frame_host(), webui_nav->GetRenderFrameHost()); + EXPECT_TRUE(created_webui->HasRenderFrameHost()); + EXPECT_EQ(created_webui->GetRenderFrameHost(), + webui_nav->GetRenderFrameHost()); EXPECT_EQ(webui_nav->GetRenderFrameHost(), root->render_manager()->speculative_frame_host()); @@ -23162,7 +21835,7 @@ EXPECT_TRUE(webui_nav_manager.was_successful()); EXPECT_EQ(url_webui, contents()->GetLastCommittedURL()); EXPECT_EQ(created_webui, current_main_frame_host()->web_ui()); - EXPECT_EQ(created_webui->frame_host(), current_main_frame_host()); + EXPECT_EQ(created_webui->GetRenderFrameHost(), current_main_frame_host()); } INSTANTIATE_TEST_SUITE_P( @@ -23185,18 +21858,6 @@ NavigationControllerBrowserTest::DescribeParams); INSTANTIATE_TEST_SUITE_P( All, - NavigationControllerDebugHistoryInterventionNoUserActivation, - testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()), - testing::Bool()), - NavigationControllerBrowserTest::DescribeParams); -INSTANTIATE_TEST_SUITE_P( - All, - NavigationControllerHistoryInterventionBrowserTest, - testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()), - testing::Bool()), - NavigationControllerBrowserTest::DescribeParams); -INSTANTIATE_TEST_SUITE_P( - All, NavigationControllerMainDocumentSequenceNumberBrowserTest, testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()), testing::Bool()),
diff --git a/content/browser/renderer_host/navigation_entry_impl.cc b/content/browser/renderer_host/navigation_entry_impl.cc index 1e15ec2..ab6e19a 100644 --- a/content/browser/renderer_host/navigation_entry_impl.cc +++ b/content/browser/renderer_host/navigation_entry_impl.cc
@@ -89,9 +89,16 @@ if (!entry) { absl::optional<GURL> initiator_base_url; - if (state.initiator_base_url_string) { - initiator_base_url = + if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled() && + state.initiator_base_url_string) { + GURL initiator_base_url_from_state = GURL(UTF16ToUTF8(state.initiator_base_url_string.value())); + if (!initiator_base_url_from_state.is_empty()) { + // TODO(crbug.com/1356658): refactor the uses of + // `state.initiator_base_url_string` so they store nullopt instead of + // empty strings. + initiator_base_url = initiator_base_url_from_state; + } } entry = base::MakeRefCounted<FrameNavigationEntry>( UTF16ToUTF8(state.target.value_or(std::u16string())),
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index 33467ce..b51154d 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -1547,7 +1547,7 @@ // It's possible for the navigation to already have a WebUI associated with // it if this function is called from OnResponseStarted. CHECK_GE(request->state(), NavigationRequest::WILL_PROCESS_RESPONSE); - CHECK(!request->web_ui()->has_frame_host()); + CHECK(!request->web_ui()->HasRenderFrameHost()); return; }
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc index 035df5f..2a39143 100644 --- a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc +++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -12,6 +12,11 @@ #include "build/build_config.h" #include "content/browser/renderer_host/frame_token_message_queue.h" +#if BUILDFLAG(IS_ANDROID) +#include "base/android/jni_android.h" +#include "content/public/android/content_jni_headers/RenderFrameMetadataProviderImpl_jni.h" +#endif + namespace content { RenderFrameMetadataProviderImpl::RenderFrameMetadataProviderImpl( @@ -21,7 +26,12 @@ frame_token_message_queue_(frame_token_message_queue) {} RenderFrameMetadataProviderImpl::~RenderFrameMetadataProviderImpl() { - CHECK(!inside_metadata_changed_); + if (inside_metadata_changed_) { +#if BUILDFLAG(IS_ANDROID) + JNIEnv* env = base::android::AttachCurrentThread(); + android::Java_RenderFrameMetadataProviderImpl_reportRecursiveDelete(env); +#endif + } } void RenderFrameMetadataProviderImpl::AddObserver(Observer* observer) { @@ -113,13 +123,26 @@ const cc::RenderFrameMetadata& metadata) { base::AutoReset<bool> auto_reset(&inside_metadata_changed_, true); - for (Observer& observer : observers_) + // Guard for this being recursively deleted from one of the observer + // callbacks. + base::WeakPtr<RenderFrameMetadataProviderImpl> self = + weak_factory_.GetWeakPtr(); + + for (Observer& observer : observers_) { observer.OnRenderFrameMetadataChangedBeforeActivation(metadata); + if (!self) { + return; + } + } if (metadata.local_surface_id != last_local_surface_id_) { last_local_surface_id_ = metadata.local_surface_id; - for (Observer& observer : observers_) + for (Observer& observer : observers_) { observer.OnLocalSurfaceIdChanged(metadata); + if (!self) { + return; + } + } } if (!frame_token)
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 44fecf2..a2d47ff 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3224,7 +3224,7 @@ static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { command_line->AppendSwitchASCII( - blink::switches::kNumRasterThreads, + cc::switches::kNumRasterThreads, base::NumberToString(NumberOfRendererRasterThreads())); int msaa_sample_count = GpuRasterizationMSAASampleCount();
diff --git a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc index 07042f3..32763fe 100644 --- a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc +++ b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
@@ -60,22 +60,7 @@ namespace content { namespace { - const std::string kEmptySchemeForTesting = "empty-scheme"; - -void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list, - bool enable_back_forward_cache) { - if (enable_back_forward_cache) { - feature_list->InitWithFeaturesAndParameters( - GetBasicBackForwardCacheFeatureForTesting( - {{kBackForwardCacheNoTimeEviction, {}}, - {features::kBackForwardCacheMemoryControls, {}}}), - {}); - } else { - feature_list->InitAndDisableFeature(features::kBackForwardCache); - } -} - } // namespace // Note that this test suite is parametrized for RenderDocument and
diff --git a/content/browser/shared_storage/shared_storage_document_service_impl.cc b/content/browser/shared_storage/shared_storage_document_service_impl.cc index 41e05c6e..2e67d12 100644 --- a/content/browser/shared_storage/shared_storage_document_service_impl.cc +++ b/content/browser/shared_storage/shared_storage_document_service_impl.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/content_client.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/shared_storage/shared_storage_utils.h" #include "url/url_constants.h" @@ -23,6 +24,18 @@ namespace { +// TODO(yaoxia): This should be function in FrameTreeNode. +bool IsSecureFrame(RenderFrameHost* frame) { + while (frame) { + if (!network::IsOriginPotentiallyTrustworthy( + frame->GetLastCommittedOrigin())) { + return false; + } + frame = frame->GetParent(); + } + return true; +} + using AccessType = SharedStorageWorkletHostManager::SharedStorageObserverInterface::AccessType; @@ -69,6 +82,14 @@ CHECK(!receiver_) << "Multiple attempts to bind the SharedStorageDocumentService receiver"; + if (!IsSecureFrame(&render_frame_host())) { + // This could indicate a compromised renderer, so let's terminate it. + mojo::ReportBadMessage( + "Attempted to request SharedStorageDocumentService from an insecure " + "context"); + return; + } + receiver_.Bind(std::move(receiver)); }
diff --git a/content/browser/webui/test_webui_js_bridge_ui.h b/content/browser/webui/test_webui_js_bridge_ui.h index 77cc0ecf..2eca36ae 100644 --- a/content/browser/webui/test_webui_js_bridge_ui.h +++ b/content/browser/webui/test_webui_js_bridge_ui.h
@@ -12,7 +12,7 @@ // WebUIController for WebUIJsBridge unittests. class TestWebUIJsBridgeUI : public WebUIController { public: - explicit TestWebUIJsBridgeUI() : WebUIController(nullptr) {} + explicit TestWebUIJsBridgeUI(WebUI* web_ui) : WebUIController(web_ui) {} ~TestWebUIJsBridgeUI() override = default; TestWebUIJsBridgeUI(const TestWebUIJsBridgeUI&) = delete; @@ -24,7 +24,8 @@ // WebUIController for WebUIJsBridge unittests. class TestWebUIJsBridgeIncorrectUI : public WebUIController { public: - explicit TestWebUIJsBridgeIncorrectUI() : WebUIController(nullptr) {} + explicit TestWebUIJsBridgeIncorrectUI(WebUI* web_ui) + : WebUIController(web_ui) {} ~TestWebUIJsBridgeIncorrectUI() override = default; TestWebUIJsBridgeIncorrectUI(const TestWebUIJsBridgeIncorrectUI&) = delete;
diff --git a/content/browser/webui/web_ui_browsertest.cc b/content/browser/webui/web_ui_browsertest.cc index 8c0d9aa..f9f895ec4 100644 --- a/content/browser/webui/web_ui_browsertest.cc +++ b/content/browser/webui/web_ui_browsertest.cc
@@ -420,10 +420,10 @@ web_contents->GetWebUI()->AddMessageHandler(base::WrapUnique(test_handler)); auto* webui = static_cast<WebUIImpl*>(web_contents->GetWebUI()); - EXPECT_EQ(web_contents->GetPrimaryMainFrame(), webui->frame_host()); + EXPECT_EQ(web_contents->GetPrimaryMainFrame(), webui->GetRenderFrameHost()); test_handler->set_finish_closure(base::BindLambdaForTesting([&]() { - EXPECT_NE(web_contents->GetPrimaryMainFrame(), webui->frame_host()); + EXPECT_NE(web_contents->GetPrimaryMainFrame(), webui->GetRenderFrameHost()); })); bool received_send_message = false;
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc index b1c20e87..ab3aad4 100644 --- a/content/browser/webui/web_ui_impl.cc +++ b/content/browser/webui/web_ui_impl.cc
@@ -116,7 +116,8 @@ } void WebUIImpl::SetRenderFrameHost(RenderFrameHost* render_frame_host) { - frame_host_ = static_cast<RenderFrameHostImpl*>(render_frame_host); + frame_host_ = + static_cast<RenderFrameHostImpl*>(render_frame_host)->GetWeakPtr(); // Assert that we can only open WebUI for the active or speculative pages. DCHECK(frame_host_->lifecycle_state() == RenderFrameHostImpl::LifecycleStateImpl::kActive || @@ -201,6 +202,14 @@ return controller_.get(); } +RenderFrameHost* WebUIImpl::GetRenderFrameHost() { + return frame_host_.get(); +} + +bool WebUIImpl::HasRenderFrameHost() const { + return !!frame_host_; +} + void WebUIImpl::SetController(std::unique_ptr<WebUIController> controller) { DCHECK(controller); controller_ = std::move(controller);
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h index fd831f7..2cabbca 100644 --- a/content/browser/webui/web_ui_impl.h +++ b/content/browser/webui/web_ui_impl.h
@@ -70,6 +70,7 @@ // WebUI implementation: WebContents* GetWebContents() override; WebUIController* GetController() override; + RenderFrameHost* GetRenderFrameHost() override; void SetController(std::unique_ptr<WebUIController> controller) override; float GetDeviceScaleFactor() override; const std::u16string& GetOverriddenTitle() override; @@ -99,12 +100,7 @@ return web_contents_observer_.get(); } - RenderFrameHostImpl* frame_host() const { - CHECK(frame_host_); - return frame_host_; - } - - bool has_frame_host() const { return !!frame_host_; } + bool HasRenderFrameHost() const; private: friend class WebUIMainFrameObserver; @@ -140,13 +136,17 @@ // See regression test: // `WebUIImplBrowserTest::SynchronousWebContentDeletionInUnload` raw_ptr<WebContents, DisableDanglingPtrDetection> web_contents_; - // `frame_host_` might stay unset for a while, as the WebUIImpl object is - // created early in a navigation, and a RenderFrameHost for the navigation - // might not be created until the final response for the navigation is - // received in some cases (after `NavigationRequest::OnResponseStarted()`). - // See also `SetRenderFrameHost()` for more details. - raw_ptr<RenderFrameHostImpl, DisableDanglingPtrDetection> frame_host_ = - nullptr; + + // During WebUI construction, `frame_host_` might stay unset for a while, + // as the WebUIImpl object is created early in a navigation, and a + // RenderFrameHost for the navigation might not be created until the final + // response for the navigation is received in some cases + // (after `NavigationRequest::OnResponseStarted()`). + // During WebUI destruction, `frame_host_` is always valid except + // if the WebContents is destroyed by the WebUIController subclass. + // See regression test: + // `WebUIImplBrowserTest::SynchronousWebContentDeletionInUnload` + base::WeakPtr<RenderFrameHostImpl> frame_host_; // The WebUIMessageHandlers we own. std::vector<std::unique_ptr<WebUIMessageHandler>> handlers_;
diff --git a/content/browser/webui/web_ui_main_frame_observer.cc b/content/browser/webui/web_ui_main_frame_observer.cc index 7731427..5d2bbc18 100644 --- a/content/browser/webui/web_ui_main_frame_observer.cc +++ b/content/browser/webui/web_ui_main_frame_observer.cc
@@ -82,7 +82,7 @@ // Some WebUI pages have another WebUI page in an <iframe>. Both // WebUIMainFrameObservers will get a callback when either page gets an error. // To avoid duplicates, only report on errors from this page's frame. - if (source_frame != web_ui_->frame_host()) { + if (source_frame != web_ui_->GetRenderFrameHost()) { DVLOG(3) << "Message not reported, different frame"; return; } @@ -145,7 +145,8 @@ // https://crbug.com/1154866). if (error_reporting_enabled_) { DVLOG(3) << "Enabled"; - web_ui_->frame_host()->SetWantErrorMessageStackTrace(); + static_cast<content::RenderFrameHostImpl*>(web_ui_->GetRenderFrameHost()) + ->SetWantErrorMessageStackTrace(); } else { DVLOG(3) << "Error reporting disabled for this page"; } @@ -156,10 +157,13 @@ void WebUIMainFrameObserver::ReadyToCommitNavigation( NavigationHandle* navigation_handle) { // Navigation didn't occur in the frame associated with this WebUI. - if (navigation_handle->GetRenderFrameHost() != web_ui_->frame_host()) + if (navigation_handle->GetRenderFrameHost() != + web_ui_->GetRenderFrameHost()) { return; + } - web_ui_->GetController()->WebUIReadyToCommitNavigation(web_ui_->frame_host()); + web_ui_->GetController()->WebUIReadyToCommitNavigation( + web_ui_->GetRenderFrameHost()); // TODO(crbug.com/1129544) This is currently disabled due to Windows DLL // thunking issues. Fix & re-enable.
diff --git a/content/browser/webui/web_ui_main_frame_observer_unittest.cc b/content/browser/webui/web_ui_main_frame_observer_unittest.cc index 2b547db..7acfab6 100644 --- a/content/browser/webui/web_ui_main_frame_observer_unittest.cc +++ b/content/browser/webui/web_ui_main_frame_observer_unittest.cc
@@ -183,7 +183,7 @@ TEST_F(WebUIMainFrameObserverTest, ErrorReported) { NavigateToPage(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, kSourceURL16, kStackTrace16); task_environment()->RunUntilIdle(); @@ -206,7 +206,7 @@ TEST_F(WebUIMainFrameObserverTest, NoStackTrace) { NavigateToPage(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, kSourceURL16, absl::nullopt); task_environment()->RunUntilIdle(); @@ -216,13 +216,13 @@ TEST_F(WebUIMainFrameObserverTest, NonErrorsIgnored) { NavigateToPage(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kWarning, kMessage16, 5, kSourceURL16, kStackTrace16); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kInfo, kMessage16, 5, kSourceURL16, kStackTrace16); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kVerbose, kMessage16, 5, kSourceURL16, kStackTrace16); task_environment()->RunUntilIdle(); @@ -232,7 +232,7 @@ TEST_F(WebUIMainFrameObserverTest, NoProcessorDoesntCrash) { NavigateToPage(); FakeJsErrorReportProcessor::SetDefault(nullptr); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, kSourceURL16, kStackTrace16); task_environment()->RunUntilIdle(); @@ -240,7 +240,7 @@ TEST_F(WebUIMainFrameObserverTest, NotSentIfInvalidURL) { NavigateToPage(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, u"invalid URL", kStackTrace16); task_environment()->RunUntilIdle(); @@ -251,7 +251,7 @@ static_cast<MockWebUIController*>(web_ui_->GetController()) ->enable_javascript_error_reporting(false); NavigateToPage(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, kSourceURL16, kStackTrace16); task_environment()->RunUntilIdle(); @@ -290,7 +290,7 @@ for (const URLTest& test : kTests) { int previous_count = processor_->error_report_count(); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, test.input, kStackTrace16); task_environment()->RunUntilIdle(); @@ -306,7 +306,7 @@ "chrome://bookmarks/add?q=chromium#code"; NavigationSimulator::NavigateAndCommitFromBrowser( web_contents(), GURL(kPageWithQueryAndFragment)); - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, kSourceURL16, kStackTrace16); task_environment()->RunUntilIdle(); @@ -336,7 +336,7 @@ }; for (const auto* url : kNonChromeSourceURLs) { - CallOnDidAddMessageToConsole(web_ui_->frame_host(), + CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(), blink::mojom::ConsoleMessageLevel::kError, kMessage16, 5, url, kStackTrace16); task_environment()->RunUntilIdle();
diff --git a/content/browser/webui/web_ui_managed_interface.cc b/content/browser/webui/web_ui_managed_interface.cc new file mode 100644 index 0000000..e27baf8 --- /dev/null +++ b/content/browser/webui/web_ui_managed_interface.cc
@@ -0,0 +1,58 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/webui/web_ui_managed_interface.h" + +#include <vector> + +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/webui/web_ui_impl.h" +#include "content/public/browser/document_user_data.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_ui.h" + +namespace content { + +namespace internal { + +class WebUIManagedInterfaceStorage + : public DocumentUserData<WebUIManagedInterfaceStorage> { + public: + ~WebUIManagedInterfaceStorage() override = default; + + void AddInterfaceImpl(std::unique_ptr<WebUIManagedInterfaceBase> impl) { + impls_.push_back(std::move(impl)); + } + + private: + explicit WebUIManagedInterfaceStorage(RenderFrameHost* render_frame_host) + : DocumentUserData<WebUIManagedInterfaceStorage>(render_frame_host) {} + + friend DocumentUserData; + DOCUMENT_USER_DATA_KEY_DECL(); + + std::vector<std::unique_ptr<WebUIManagedInterfaceBase>> impls_; +}; + +DOCUMENT_USER_DATA_KEY_IMPL(WebUIManagedInterfaceStorage); + +void SaveWebUIManagedInterfaceInDocument( + WebUIController* controller, + std::unique_ptr<WebUIManagedInterfaceBase> data) { + auto* storage = WebUIManagedInterfaceStorage::GetOrCreateForCurrentDocument( + controller->web_ui()->GetRenderFrameHost()); + storage->AddInterfaceImpl(std::move(data)); +} + +} // namespace internal + +void RemoveWebUIManagedInterfaces(WebUIController* webui_controller) { + RenderFrameHost* rfh = webui_controller->web_ui()->GetRenderFrameHost(); + if (rfh && + internal::WebUIManagedInterfaceStorage::GetForCurrentDocument(rfh)) { + internal::WebUIManagedInterfaceStorage::DeleteForCurrentDocument(rfh); + } +} + +} // namespace content
diff --git a/content/browser/webui/web_ui_managed_interface.h b/content/browser/webui/web_ui_managed_interface.h new file mode 100644 index 0000000..7f01e7ca --- /dev/null +++ b/content/browser/webui/web_ui_managed_interface.h
@@ -0,0 +1,202 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_WEBUI_WEB_UI_MANAGED_INTERFACE_H_ +#define CONTENT_BROWSER_WEBUI_WEB_UI_MANAGED_INTERFACE_H_ + +#include <memory> +#include <utility> + +#include "base/memory/raw_ptr.h" +#include "base/supports_user_data.h" +#include "content/common/content_export.h" +#include "content/public/browser/web_ui_controller.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace content { + +CONTENT_EXPORT void RemoveWebUIManagedInterfaces( + WebUIController* webui_controller); + +namespace internal { + +class CONTENT_EXPORT WebUIManagedInterfaceBase { + public: + virtual ~WebUIManagedInterfaceBase() = default; +}; + +// Stores an interface implementation instance in the WebUI host Document. +// This is called when constructing an implementation instance in +// WebUIManagedInterface::Create(). +void CONTENT_EXPORT +SaveWebUIManagedInterfaceInDocument(content::WebUIController*, + std::unique_ptr<WebUIManagedInterfaceBase>); + +} // namespace internal + +// WebUIManagedInterface is an optional base class for implementing classes +// that interact with Mojo endpoints e.g. implement a Mojo interface or +// communicate with a Mojo Remote. +// +// This class provides automated handling of Mojo endpoint bindings and +// lifetime management. The subclass object is created when Create() is +// called and destroyed when the associated WebUI document is removed or +// navigates away. +// +// To implement interface Foo, use the following code: +// class FooImpl : public WebUIManagedInterface<FooImpl, Foo> { ... } +// +// Additionally, to communiate with remote interface Bar: +// class FooBarImpl : public WebUIManagedInterface<FooBarImpl, Foo, Bar> { ... +// } +// +// To implement no interface but only communicate with a remote interface: +// class Baz : public WebUIManagedInterface< +// Baz, +// WebUIManagedInterfaceNoPageHandler, +// BarObserver> { ... } +// +// TODO(crbug.com/1417272): provide helpers to retrieve InterfaceImpl objects. +template <typename InterfaceImpl, typename... Interfaces> +class WebUIManagedInterface; + +template <typename InterfaceImpl, typename PageHandler, typename Page> +class WebUIManagedInterface<InterfaceImpl, PageHandler, Page> + : public PageHandler, public internal::WebUIManagedInterfaceBase { + public: + static void Create(content::WebUIController*, + mojo::PendingReceiver<PageHandler>, + mojo::PendingRemote<Page>); + + // Invoked when Mojo endpoints are bound and ready to use. + // TODO(crbug.com/1417260): Remove this by saving endpoints in an external + // storage before constructing `InterfaceImpl`. + virtual void OnReady() {} + + mojo::Receiver<PageHandler>& receiver() { + CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady()."; + return page_handler_receiver_; + } + mojo::Remote<Page>& remote() { + CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady()."; + return page_remote_; + } + content::WebUIController* webui_controller() { + CHECK(ready_) << "webui_controller() is not ready. Please use OnReady()."; + return webui_controller_; + } + + private: + bool ready_ = false; + mojo::Receiver<PageHandler> page_handler_receiver_{this}; + mojo::Remote<Page> page_remote_; + raw_ptr<content::WebUIController> webui_controller_; +}; + +template <typename InterfaceImpl, typename PageHandler> +class WebUIManagedInterface<InterfaceImpl, PageHandler> + : public PageHandler, public internal::WebUIManagedInterfaceBase { + public: + static void Create(content::WebUIController*, + mojo::PendingReceiver<PageHandler>); + + // Invoked when Mojo endpoints are bound and ready to use. + // TODO(crbug.com/1417260): Remove this by saving endpoints in an external + // storage before constructing `InterfaceImpl`. + virtual void OnReady() {} + + mojo::Receiver<PageHandler>& receiver() { + CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady()."; + return page_handler_receiver_; + } + content::WebUIController* webui_controller() { + CHECK(ready_) << "webui_controller() is not ready. Please use OnReady()."; + return webui_controller_; + } + + private: + bool ready_ = false; + mojo::Receiver<PageHandler> page_handler_receiver_{this}; + raw_ptr<content::WebUIController> webui_controller_; +}; + +using WebUIManagedInterfaceNoPageHandler = void; + +template <typename InterfaceImpl, typename Page> +class WebUIManagedInterface<InterfaceImpl, + WebUIManagedInterfaceNoPageHandler, + Page> : public internal::WebUIManagedInterfaceBase { + public: + static void Create(content::WebUIController*, mojo::PendingRemote<Page>); + + // Invoked when Mojo endpoints are bound and ready to use. + // TODO(crbug.com/1417260): Remove this by saving endpoints in an external + // storage before constructing `InterfaceImpl`. + virtual void OnReady() {} + + mojo::Remote<Page>& remote() { + CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady()."; + return page_remote_; + } + content::WebUIController* webui_controller() { + CHECK(ready_) << "webui_controller() is not ready. Please use OnReady()."; + return webui_controller_; + } + + private: + bool ready_ = false; + mojo::Remote<Page> page_remote_; + raw_ptr<content::WebUIController> webui_controller_; +}; + +template <typename InterfaceImpl, typename PageHandler, typename Page> +void WebUIManagedInterface<InterfaceImpl, PageHandler, Page>::Create( + content::WebUIController* webui_controller, + mojo::PendingReceiver<PageHandler> pending_receiver, + mojo::PendingRemote<Page> pending_remote) { + auto interface_impl = std::make_unique<InterfaceImpl>(); + auto* interface_impl_ptr = interface_impl.get(); + interface_impl->webui_controller_ = webui_controller; + interface_impl->page_handler_receiver_.Bind(std::move(pending_receiver)); + interface_impl->page_remote_.Bind(std::move(pending_remote)); + internal::SaveWebUIManagedInterfaceInDocument(webui_controller, + std::move(interface_impl)); + interface_impl_ptr->ready_ = true; + interface_impl_ptr->OnReady(); +} + +template <typename InterfaceImpl, typename PageHandler> +void WebUIManagedInterface<InterfaceImpl, PageHandler>::Create( + content::WebUIController* webui_controller, + mojo::PendingReceiver<PageHandler> pending_receiver) { + auto interface_impl = std::make_unique<InterfaceImpl>(); + auto* interface_impl_ptr = interface_impl.get(); + interface_impl->webui_controller_ = webui_controller; + interface_impl->page_handler_receiver_.Bind(std::move(pending_receiver)); + internal::SaveWebUIManagedInterfaceInDocument(webui_controller, + std::move(interface_impl)); + interface_impl_ptr->ready_ = true; + interface_impl_ptr->OnReady(); +} + +template <typename InterfaceImpl, typename Page> +void WebUIManagedInterface<InterfaceImpl, void, Page>::Create( + content::WebUIController* webui_controller, + mojo::PendingRemote<Page> pending_remote) { + auto interface_impl = std::make_unique<InterfaceImpl>(); + auto* interface_impl_ptr = interface_impl.get(); + interface_impl->webui_controller_ = webui_controller; + interface_impl->page_remote_.Bind(std::move(pending_remote)); + internal::SaveWebUIManagedInterfaceInDocument(webui_controller, + std::move(interface_impl)); + interface_impl_ptr->ready_ = true; + interface_impl_ptr->OnReady(); +} + +} // namespace content + +#endif // CONTENT_BROWSER_WEBUI_WEB_UI_MANAGED_INTERFACE_H_
diff --git a/content/browser/webui/web_ui_managed_interface_browsertest.cc b/content/browser/webui/web_ui_managed_interface_browsertest.cc new file mode 100644 index 0000000..3451834 --- /dev/null +++ b/content/browser/webui/web_ui_managed_interface_browsertest.cc
@@ -0,0 +1,443 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#include "base/functional/callback_forward.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/strings/strcat.h" +#include "base/test/bind.h" +#include "content/browser/webui/web_ui_managed_interface.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_process_host_observer.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui_browser_interface_broker_registry.h" +#include "content/public/browser/web_ui_controller_factory.h" +#include "content/public/browser/web_ui_data_source.h" +#include "content/public/browser/webui_config_map.h" +#include "content/public/common/content_client.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/url_constants.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_content_browser_client.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "content/public/test/test_utils.h" +#include "content/shell/browser/shell.h" +#include "content/test/data/web_ui_managed_interface_test.test-mojom.h" +#include "content/test/grit/web_ui_mojo_test_resources.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/webui/untrusted_web_ui_browsertest_util.h" +#include "url/gurl.h" + +namespace content { + +namespace { + +static constexpr char kFooURL[] = "chrome://foo/"; +static constexpr char kFooInIframeURL[] = "chrome-untrusted://foo/"; + +static constexpr char kBindFooJs[] = + "(async () => {" + " let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();" + " let fooRemote = new FooRemote();" + " jsBridgeRemote.bindFoo(fooRemote.$.bindNewPipeAndPassReceiver());" + " return (await fooRemote.getFoo()).value;" + "})()"; + +// A helper class for counting alive instances of a specific class. +template <typename Type> +class InstanceCounter { + public: + static void Increment() { count_++; } + static void Decrement() { count_--; } + static int count() { return count_; } + + private: + static int count_; +}; + +template <typename Type> +int InstanceCounter<Type>::count_ = 0; + +// FooImpl implements Foo. +class FooImpl : public WebUIManagedInterface<FooImpl, mojom::Foo> { + public: + FooImpl() { InstanceCounter<FooImpl>::Increment(); } + + ~FooImpl() override { InstanceCounter<FooImpl>::Decrement(); } + + // mojom::Foo: + void GetFoo(GetFooCallback callback) override { + std::move(callback).Run("foo-success"); + } +}; + +// FooImpl implements Foo and talks to a Bar remote. +class FooBarImpl + : public WebUIManagedInterface<FooBarImpl, mojom::Foo, mojom::Bar> { + public: + FooBarImpl() { InstanceCounter<FooBarImpl>::Increment(); } + + ~FooBarImpl() override { InstanceCounter<FooBarImpl>::Decrement(); } + + // WebUIManagedInterface: + void OnReady() override { + remote()->GetBar(base::BindRepeating( + [](const std::string& value) { EXPECT_EQ("bar-success", value); })); + } + + // mojom::Foo: + void GetFoo(GetFooCallback callback) override { + std::move(callback).Run("foo-success"); + } +}; + +// Baz talks to a mojom::Baz remote. It does not implement any interfaces. +class Baz : public WebUIManagedInterface<Baz, + WebUIManagedInterfaceNoPageHandler, + mojom::Baz> { + public: + Baz() { InstanceCounter<Baz>::Increment(); } + + ~Baz() override { InstanceCounter<Baz>::Decrement(); } + + // WebUIManagedInterface: + void OnReady() override { + remote()->GetBaz(base::BindRepeating( + [](const std::string& value) { EXPECT_EQ("baz-success", value); })); + } +}; + +class WebUIManagedInterfaceTestUI : public WebUIController, + public mojom::TestWebUIJsBridge { + public: + explicit WebUIManagedInterfaceTestUI(WebUI* web_ui) + : WebUIController(web_ui) { + // Allow resources to be loaded for both top-level and embedded WebUIs. + // Due to the behavior of URLDataManagerBackend::GetDataSourceFromURL(), + // WebUIDataSource::CreateAndAdd() expects "host" as the `source_name` arg + // for trusted hosts and "chrome-untrusted://host" for untrusted hosts. + for (const auto& host : + {GURL(kFooURL).host(), std::string(kFooInIframeURL)}) { + WebUIDataSource* data_source = WebUIDataSource::CreateAndAdd( + web_ui->GetWebContents()->GetBrowserContext(), host); + data_source->SetDefaultResource(IDR_WEB_UI_MANAGED_INTERFACE_TEST_HTML); + data_source->AddResourcePath( + "web_ui_managed_interface_test.test-mojom-webui.js", + IDR_WEB_UI_MANAGED_INTERFACE_TEST_TEST_MOJOM_WEBUI_JS); + data_source->AddResourcePath("web_ui_managed_interface_test.js", + IDR_WEB_UI_MANAGED_INTERFACE_TEST_JS); + + // Allow WebUI to be embedded in an iframe under + // chrome-untrusted://test-host. + if (host == kFooInIframeURL) { + data_source->AddFrameAncestor(GURL("chrome-untrusted://test-host")); + } + } + } + + void BindInterface(mojo::PendingReceiver<mojom::TestWebUIJsBridge> receiver) { + js_bridge_receiver_.reset(); + js_bridge_receiver_.Bind(std::move(receiver)); + } + + // mojom::TestWebUIJsBridge: + void BindFoo(mojo::PendingReceiver<mojom::Foo> foo_receiver) override { + FooImpl::Create(this, std::move(foo_receiver)); + } + + void BindFooBar(mojo::PendingReceiver<mojom::Foo> foo_receiver, + mojo::PendingRemote<mojom::Bar> bar_remote) override { + FooBarImpl::Create(this, std::move(foo_receiver), std::move(bar_remote)); + } + + void BindBaz(mojo::PendingRemote<mojom::Baz> baz_remote) override { + Baz::Create(this, std::move(baz_remote)); + } + + WEB_UI_CONTROLLER_TYPE_DECL(); + + private: + mojo::Receiver<mojom::TestWebUIJsBridge> js_bridge_receiver_{this}; +}; + +WEB_UI_CONTROLLER_TYPE_IMPL(WebUIManagedInterfaceTestUI) + +// WebUIControllerFactory that serves our TestWebUIController. +class TestFooWebUIControllerFactory : public WebUIControllerFactory { + public: + TestFooWebUIControllerFactory() = default; + + std::unique_ptr<WebUIController> CreateWebUIControllerForURL( + WebUI* web_ui, + const GURL& url) override { + if (url::IsSameOriginWith(url, GURL(kFooURL)) || + url::IsSameOriginWith(url, GURL(kFooInIframeURL))) { + return std::make_unique<WebUIManagedInterfaceTestUI>(web_ui); + } + + return nullptr; + } + + WebUI::TypeID GetWebUIType(BrowserContext* browser_context, + const GURL& url) override { + if (url::IsSameOriginWith(url, GURL(kFooURL))) { + return &kFooURL; + } + + if (url::IsSameOriginWith(url, GURL(kFooInIframeURL))) { + return &kFooInIframeURL; + } + + return WebUI::kNoWebUI; + } + + bool UseWebUIForURL(BrowserContext* browser_context, + const GURL& url) override { + return GetWebUIType(browser_context, url) != WebUI::kNoWebUI; + } +}; + +} // namespace + +class WebUIManagedInterfaceBrowserTest : public ContentBrowserTest { + public: + WebUIManagedInterfaceBrowserTest() { + factory_ = std::make_unique<TestFooWebUIControllerFactory>(); + WebUIControllerFactory::RegisterFactory(factory_.get()); + } + + void SetUpOnMainThread() override { + ContentBrowserTest::SetUpOnMainThread(); + test_content_browser_client_ = std::make_unique<TestContentBrowserClient>(); + } + + void TearDownOnMainThread() override { test_content_browser_client_.reset(); } + + // Evaluate `statement` in frame (defaults to main frame), and returns its + // result. For convenience, `script` should evaluate to a string, or a promise + // that resolves to a string. + std::string EvalStatement(const std::string& statement, + content::RenderFrameHost* frame = nullptr) { + RenderFrameHost* eval_frame = + frame ? frame : ConvertToRenderFrameHost(shell()); + + // Use EvalJs to execute the statement + auto result = + EvalJs(eval_frame, statement, content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, + content::ISOLATED_WORLD_ID_GLOBAL); + + EXPECT_TRUE(result.error.empty()); + return result.value.GetString(); + } + + void Reload(RenderFrameHost* frame = nullptr) { + RenderFrameHost* eval_frame = + frame ? frame : ConvertToRenderFrameHost(shell()); + TestNavigationObserver observer(shell()->web_contents(), 1); + EXPECT_TRUE(ExecuteScript(eval_frame, "location.reload()")); + observer.Wait(); + } + + private: + class TestContentBrowserClient + : public ContentBrowserTestContentBrowserClient { + public: + TestContentBrowserClient() = default; + TestContentBrowserClient(const TestContentBrowserClient&) = delete; + TestContentBrowserClient& operator=(const TestContentBrowserClient&) = + delete; + ~TestContentBrowserClient() override = default; + + void RegisterWebUIInterfaceBrokers( + WebUIBrowserInterfaceBrokerRegistry& registry) override { + registry.ForWebUI<WebUIManagedInterfaceTestUI>() + .Add<mojom::TestWebUIJsBridge>(); + } + }; + + std::unique_ptr<TestFooWebUIControllerFactory> factory_; + std::unique_ptr<TestContentBrowserClient> test_content_browser_client_; +}; + +// Test FooImpl that implements Foo is constructed properly and destroyed on +// navigation. +IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, Foo) { + WebContents* web_contents = shell()->web_contents(); + + ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL))); + + EXPECT_EQ("foo-success", EvalStatement(kBindFooJs)); + EXPECT_EQ(1, InstanceCounter<FooImpl>::count()); + + // Navigation will destroy interface impls. + Reload(); + EXPECT_EQ(0, InstanceCounter<FooImpl>::count()); +} + +// Test FooBarImpl that implements Foo and talks to the Bar remote is +// constructed properly and destroyed on navigation. +IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, FooBar) { + WebContents* web_contents = shell()->web_contents(); + + ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL))); + + EXPECT_EQ("foo-success", + EvalStatement( + "(async () => {" + " let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();" + " let fooRemote = new FooRemote();" + " let barCallbackRouter = new BarCallbackRouter();" + " let listenerPromise = new Promise(resolve => {" + " barCallbackRouter.getBar.addListener(() => {" + " /* Resolve the promise after the response is sent. */" + " setTimeout(resolve, 0);" + " return { value: 'bar-success' };" + " });" + " });" + "" + " jsBridgeRemote.bindFooBar(" + " fooRemote.$.bindNewPipeAndPassReceiver()," + " barCallbackRouter.$.bindNewPipeAndPassRemote());" + "" + " /* Wait for the listener to be called. */" + " await listenerPromise;" + " /* Wait for the response to get to the browser. */" + " await barCallbackRouter.$.flush();" + "" + " return (await fooRemote.getFoo()).value;" + "})()")); + EXPECT_EQ(1, InstanceCounter<FooBarImpl>::count()); + + // Navigation will destroy interface impls. + Reload(); + EXPECT_EQ(0, InstanceCounter<FooBarImpl>::count()); +} + +// Test Baz that talks to the Baz remote is constructed properly and +// destroyed on navigation. +IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, Baz) { + WebContents* web_contents = shell()->web_contents(); + + ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL))); + + EXPECT_EQ("success", + EvalStatement( + "(async () => {" + " let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();" + " let bazCallbackRouter = new BazCallbackRouter();" + " let listenerPromise = new Promise(resolve => {" + " bazCallbackRouter.getBaz.addListener(() => {" + " /* Resolve the promise after the response is sent. */" + " setTimeout(resolve, 0);" + " return { value: 'baz-success' };" + " });" + " });" + "" + " jsBridgeRemote.bindBaz(" + " bazCallbackRouter.$.bindNewPipeAndPassRemote());" + "" + " /* Wait for the listener to be called. */" + " await listenerPromise;" + " /* Wait for the response to get to the browser. */" + " await bazCallbackRouter.$.flush();" + "" + " return 'success';" + "})()")); + EXPECT_EQ(1, InstanceCounter<Baz>::count()); + + // Navigation will destroy interface impls. + Reload(); + EXPECT_EQ(0, InstanceCounter<Baz>::count()); +} + +// Test that interface impls of an iframe WebUI are destroyed on iframe reload. +IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, WebUIInIframe) { + WebContents* web_contents = shell()->web_contents(); + // Allow adding chrome-untrusted://foo in an iframe. + TestUntrustedDataSourceHeaders headers; + headers.child_src = "child-src *;"; + // Use a test host WebUI. We intentionally don't use chrome://foo as the host + // WebUI, otherwise there will be two instances of WebUIManagedInterfaceTestUI + // while we only care about the embedded one. + content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig( + std::make_unique<ui::TestUntrustedWebUIConfig>("test-host", headers)); + + // Load host page. + ASSERT_TRUE(NavigateToURL(web_contents, + GetChromeUntrustedUIURL("test-host/title1.html"))); + + // Append an iframe that opens chrome-untrusted://foo. + EXPECT_EQ(true, + EvalJs(web_contents->GetPrimaryMainFrame(), + JsReplace("let frame = document.createElement('iframe');" + "frame.src=$1;" + "!!document.body.appendChild(frame);", + GURL(kFooInIframeURL).spec()), + EXECUTE_SCRIPT_DEFAULT_OPTIONS, 1 /* world_id */)); + EXPECT_TRUE(WaitForLoadStop(web_contents)); + + RenderFrameHost* foo_frame = + ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); + ASSERT_EQ(GURL(kFooInIframeURL), foo_frame->GetLastCommittedURL()); + + EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame)); + EXPECT_EQ(1, InstanceCounter<FooImpl>::count()); + + // Iframe navigation will destroy interface impls. + Reload(foo_frame); + EXPECT_EQ(0, InstanceCounter<FooImpl>::count()); + + // Interface impls can be created after reload. + EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame)); + EXPECT_EQ(1, InstanceCounter<FooImpl>::count()); +} + +// Test that interface impls of an iframe WebUI are destroyed on iframe removal. +IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, RemoveIframe) { + WebContents* web_contents = shell()->web_contents(); + // Allow adding chrome-untrusted://foo in an iframe. + TestUntrustedDataSourceHeaders headers; + headers.child_src = "child-src *;"; + // Use a test host WebUI. We intentionally don't use chrome://foo as the host + // WebUI, otherwise there will be two instances of WebUIManagedInterfaceTestUI + // while we only care about the embedded one. + content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig( + std::make_unique<ui::TestUntrustedWebUIConfig>("test-host", headers)); + + // Load host page. + ASSERT_TRUE(NavigateToURL(web_contents, + GetChromeUntrustedUIURL("test-host/title1.html"))); + + // Append an iframe that opens chrome-untrusted://foo. + EXPECT_EQ(true, + EvalJs(web_contents->GetPrimaryMainFrame(), + JsReplace("let frame = document.createElement('iframe');" + "frame.src=$1;frame.id='untrusted-webui';" + "!!document.body.appendChild(frame);", + GURL(kFooInIframeURL).spec()), + EXECUTE_SCRIPT_DEFAULT_OPTIONS, 1 /* world_id */)); + EXPECT_TRUE(WaitForLoadStop(web_contents)); + + RenderFrameHost* foo_frame = + ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); + ASSERT_EQ(GURL(kFooInIframeURL), foo_frame->GetLastCommittedURL()); + + EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame)); + EXPECT_EQ(1, InstanceCounter<FooImpl>::count()); + + // Iframe removal will destroy interface impls. + RenderFrameDeletedObserver frame_deleted_observer(foo_frame); + EXPECT_TRUE(ExecuteScript( + shell(), "document.getElementById('untrusted-webui').remove()")); + frame_deleted_observer.WaitUntilDeleted(); + EXPECT_EQ(0, InstanceCounter<FooImpl>::count()); +} + +} // namespace content
diff --git a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc index 2618d01..71f23146 100644 --- a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc +++ b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc
@@ -5,6 +5,7 @@ #include "base/test/bind.h" #include "base/test/task_environment.h" #include "content/browser/webui/test_webui_js_bridge_ui.h" +#include "content/public/test/test_web_ui.h" #include "content/test/web_ui/webui_js_bridge_unittest.test-mojom-webui-js-bridge-impl.h" #include "content/test/web_ui/webui_js_bridge_unittest2.test-mojom-webui-js-bridge-impl.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -84,8 +85,11 @@ WebUIJsBridgeTest() = default; ~WebUIJsBridgeTest() override = default; + TestWebUI* web_ui() { return &test_web_ui; } + private: base::test::TaskEnvironment task_environment_; + TestWebUI test_web_ui; }; // Tests binder methods are overridden and can be called. Calling them does @@ -100,7 +104,7 @@ }); Bar bar; - TestWebUIJsBridgeUI controller; + TestWebUIJsBridgeUI controller(web_ui()); mojom::FooWebUIJsBridgeImpl bridge( &controller, page_handler_binder, base::BindRepeating(&Bar::BindBar, base::Unretained(&bar)), @@ -129,7 +133,7 @@ // Tests we correctly generate a WebUIJsBridgeImpl for a interface that // binds interfaces in a separate mojom. TEST_F(WebUIJsBridgeTest, CrossModule) { - TestWebUIJsBridgeUI controller; + TestWebUIJsBridgeUI controller(web_ui()); mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing()); bridge.BindSecondaryInterface(mojo::NullReceiver()); } @@ -137,7 +141,7 @@ // Tests that we crash if the wrong WebUIController is passed to the // WebUIJsBridge. TEST_F(WebUIJsBridgeTest, IncorrectWebUIControllerCrash) { - TestWebUIJsBridgeIncorrectUI controller; + TestWebUIJsBridgeIncorrectUI controller(web_ui()); EXPECT_DEATH_IF_SUPPORTED( mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing()), ""); }
diff --git a/content/common/mac/attributed_string_type_converters.h b/content/common/mac/attributed_string_type_converters.h index f29d965..fbb5670 100644 --- a/content/common/mac/attributed_string_type_converters.h +++ b/content/common/mac/attributed_string_type_converters.h
@@ -9,26 +9,22 @@ #include "ui/base/mojom/attributed_string.mojom.h" #include "ui/gfx/range/range.h" -#if __OBJC__ -@class NSAttributedString; -#else -class NSAttributedString; -#endif +#include <CoreFoundation/CoreFoundation.h> namespace mojo { template <> struct CONTENT_EXPORT - TypeConverter<NSAttributedString*, ui::mojom::AttributedStringPtr> { - static NSAttributedString* Convert( + TypeConverter<CFAttributedStringRef, ui::mojom::AttributedStringPtr> { + static CFAttributedStringRef Convert( const ui::mojom::AttributedStringPtr& mojo_attributed_string); }; template <> struct CONTENT_EXPORT - TypeConverter<ui::mojom::AttributedStringPtr, NSAttributedString*> { + TypeConverter<ui::mojom::AttributedStringPtr, CFAttributedStringRef> { static ui::mojom::AttributedStringPtr Convert( - const NSAttributedString* ns_attributed_string); + const CFAttributedStringRef cf_attributed_string); }; } // namespace mojo
diff --git a/content/common/mac/attributed_string_type_converters.mm b/content/common/mac/attributed_string_type_converters.mm index 920ba766..8103f185 100644 --- a/content/common/mac/attributed_string_type_converters.mm +++ b/content/common/mac/attributed_string_type_converters.mm
@@ -7,6 +7,7 @@ #include <AppKit/AppKit.h> #include "base/check.h" +#include "base/mac/foundation_util.h" #include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -33,8 +34,8 @@ } // namespace -NSAttributedString* -TypeConverter<NSAttributedString*, ui::mojom::AttributedStringPtr>::Convert( +CFAttributedStringRef +TypeConverter<CFAttributedStringRef, ui::mojom::AttributedStringPtr>::Convert( const ui::mojom::AttributedStringPtr& mojo_attributed_string) { // Create the return value. NSString* plain_text = @@ -47,8 +48,8 @@ for (const auto& attribute : attributes) { // Protect against ranges that are outside the range of the string. const gfx::Range& range = attribute.get()->effective_range; - if (range.GetMin() > [plain_text length] || - range.GetMax() > [plain_text length]) { + if (range.GetMin() > plain_text.length || + range.GetMax() > plain_text.length) { continue; } [decoded_string @@ -56,20 +57,23 @@ attribute.get()->font_point_size) range:range.ToNSRange()]; } - return decoded_string.autorelease(); + return base::mac::NSToCFCast(decoded_string.autorelease()); } ui::mojom::AttributedStringPtr -TypeConverter<ui::mojom::AttributedStringPtr, NSAttributedString*>::Convert( - const NSAttributedString* ns_attributed_string) { +TypeConverter<ui::mojom::AttributedStringPtr, CFAttributedStringRef>::Convert( + const CFAttributedStringRef cf_attributed_string) { + NSAttributedString* ns_attributed_string = + base::mac::CFToNSCast(cf_attributed_string); + // Create the return value. ui::mojom::AttributedStringPtr attributed_string = ui::mojom::AttributedString::New(); attributed_string->string = - base::SysNSStringToUTF16([ns_attributed_string string]); + base::SysNSStringToUTF16(ns_attributed_string.string); // Iterate over all the attributes in the string. - NSUInteger length = [ns_attributed_string length]; + NSUInteger length = ns_attributed_string.length; for (NSUInteger i = 0; i < length;) { NSRange effective_range; NSDictionary* ns_attributes = @@ -81,8 +85,8 @@ float font_point_size; // Only encode the attributes if the filtered set contains font information. if (font) { - font_name = base::SysNSStringToUTF16([font fontName]); - font_point_size = [font pointSize]; + font_name = base::SysNSStringToUTF16(font.fontName); + font_point_size = font.pointSize; if (!font_name.empty()) { // Convert the attributes. ui::mojom::FontAttributePtr attrs = ui::mojom::FontAttribute::New(
diff --git a/content/common/mac/attributed_string_type_converters_unittest.mm b/content/common/mac/attributed_string_type_converters_unittest.mm index 17738e0..5ea0982d 100644 --- a/content/common/mac/attributed_string_type_converters_unittest.mm +++ b/content/common/mac/attributed_string_type_converters_unittest.mm
@@ -8,7 +8,7 @@ #include <memory> -#include "base/mac/scoped_nsobject.h" +#include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" @@ -16,100 +16,99 @@ class AttributedStringConverterTest : public testing::Test { public: - NSMutableAttributedString* NewAttrString() { + NSMutableAttributedString* AttributedString() { NSString* str = @"The quick brown fox jumped over the lazy dog."; - return [[NSMutableAttributedString alloc] initWithString:str]; + return [[[NSMutableAttributedString alloc] initWithString:str] autorelease]; } - NSDictionary* FontAttribute(NSString* name, CGFloat size) { + NSDictionary* FontAttributeDictionary(NSString* name, CGFloat size) { NSFont* font = [NSFont fontWithName:name size:size]; - return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + return @{NSFontAttributeName : font}; } NSAttributedString* ConvertAndRestore(NSAttributedString* str) { ui::mojom::AttributedStringPtr attributed_str = - ui::mojom::AttributedString::From(str); - return attributed_str.To<NSAttributedString*>(); + ui::mojom::AttributedString::From(base::mac::NSToCFCast(str)); + return base::mac::CFToNSCast(attributed_str.To<CFAttributedStringRef>()); } }; TEST_F(AttributedStringConverterTest, SimpleString) { - base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); - [attr_str addAttributes:FontAttribute(@"Helvetica", 12.5) - range:NSMakeRange(0, [attr_str length])]; + NSMutableAttributedString* attr_str = AttributedString(); + [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 12.5) + range:NSMakeRange(0, attr_str.length)]; - NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get()); - EXPECT_NSEQ(attr_str.get(), ns_attributed_string); + NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str); + EXPECT_NSEQ(attr_str, ns_attributed_string); } TEST_F(AttributedStringConverterTest, NoAttributes) { - base::scoped_nsobject<NSAttributedString> attr_str(NewAttrString()); - NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get()); - EXPECT_NSEQ(attr_str.get(), ns_attributed_string); + NSMutableAttributedString* attr_str = AttributedString(); + NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str); + EXPECT_NSEQ(attr_str, ns_attributed_string); } TEST_F(AttributedStringConverterTest, StripColor) { - base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); - const NSUInteger kStringLength = [attr_str length]; + NSMutableAttributedString* attr_str = AttributedString(); + const NSUInteger kStringLength = attr_str.length; [attr_str addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:26] range:NSMakeRange(0, kStringLength)]; [attr_str addAttribute:NSForegroundColorAttributeName - value:[NSColor redColor] + value:NSColor.redColor range:NSMakeRange(0, kStringLength)]; - NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get()); + NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str); NSRange range; NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0 effectiveRange:&range]; EXPECT_TRUE(NSEqualRanges(NSMakeRange(0, kStringLength), range)); - EXPECT_NSEQ([NSFont systemFontOfSize:26], - [attrs objectForKey:NSFontAttributeName]); - EXPECT_FALSE([attrs objectForKey:NSForegroundColorAttributeName]); + EXPECT_NSEQ([NSFont systemFontOfSize:26], attrs[NSFontAttributeName]); + EXPECT_FALSE(attrs[NSForegroundColorAttributeName]); } TEST_F(AttributedStringConverterTest, MultipleFonts) { - base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); - [attr_str setAttributes:FontAttribute(@"Courier", 12) + NSMutableAttributedString* attr_str = AttributedString(); + [attr_str setAttributes:FontAttributeDictionary(@"Courier", 12) range:NSMakeRange(0, 10)]; - [attr_str addAttributes:FontAttribute(@"Helvetica", 16) + [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 16) range:NSMakeRange(12, 6)]; - [attr_str addAttributes:FontAttribute(@"Helvetica", 14) + [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 14) range:NSMakeRange(15, 5)]; NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str); - EXPECT_NSEQ(attr_str.get(), ns_attributed_string); + EXPECT_NSEQ(attr_str, ns_attributed_string); } TEST_F(AttributedStringConverterTest, NoPertinentAttributes) { - base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); + NSMutableAttributedString* attr_str = AttributedString(); [attr_str addAttribute:NSForegroundColorAttributeName - value:[NSColor blueColor] + value:NSColor.blueColor range:NSMakeRange(0, 10)]; [attr_str addAttribute:NSBackgroundColorAttributeName - value:[NSColor blueColor] + value:NSColor.blueColor range:NSMakeRange(15, 5)]; [attr_str addAttribute:NSKernAttributeName - value:[NSNumber numberWithFloat:2.6] + value:@(2.6) range:NSMakeRange(11, 3)]; - NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get()); + NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str); - base::scoped_nsobject<NSAttributedString> expected(NewAttrString()); - EXPECT_NSEQ(expected.get(), ns_attributed_string); + NSMutableAttributedString* expected = AttributedString(); + EXPECT_NSEQ(expected, ns_attributed_string); } TEST_F(AttributedStringConverterTest, NilString) { NSAttributedString* ns_attributed_string = ConvertAndRestore(nil); EXPECT_TRUE(ns_attributed_string); - EXPECT_EQ(0U, [ns_attributed_string length]); + EXPECT_EQ(0U, ns_attributed_string.length); } TEST_F(AttributedStringConverterTest, OutOfRange) { NSFont* system_font = [NSFont systemFontOfSize:10]; - std::u16string font_name = base::SysNSStringToUTF16([system_font fontName]); + std::u16string font_name = base::SysNSStringToUTF16(system_font.fontName); ui::mojom::AttributedStringPtr attributed_string = ui::mojom::AttributedString::New(); attributed_string->string = u"Hello World"; @@ -120,20 +119,21 @@ attributed_string->attributes.push_back( ui::mojom::FontAttribute::New(font_name, 16, gfx::Range(100, 5))); + CFAttributedStringRef cf_attributed_string = + attributed_string.To<CFAttributedStringRef>(); + EXPECT_TRUE(cf_attributed_string); NSAttributedString* ns_attributed_string = - attributed_string.To<NSAttributedString*>(); - EXPECT_TRUE(ns_attributed_string); + base::mac::CFToNSCast(cf_attributed_string); NSRange range; NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0 effectiveRange:&range]; - EXPECT_NSEQ([NSFont systemFontOfSize:12], - [attrs objectForKey:NSFontAttributeName]); + EXPECT_NSEQ([NSFont systemFontOfSize:12], attrs[NSFontAttributeName]); EXPECT_TRUE(NSEqualRanges(range, NSMakeRange(0, 5))); attrs = [ns_attributed_string attributesAtIndex:5 effectiveRange:&range]; - EXPECT_FALSE([attrs objectForKey:NSFontAttributeName]); - EXPECT_EQ(0U, [attrs count]); + EXPECT_FALSE(attrs[NSFontAttributeName]); + EXPECT_EQ(0U, attrs.count); } TEST_F(AttributedStringConverterTest, SystemFontSubstitution) { @@ -146,14 +146,15 @@ attributed_string->attributes.push_back( ui::mojom::FontAttribute::New(font_name, 12, gfx::Range(0, 5))); + CFAttributedStringRef cf_attributed_string = + attributed_string.To<CFAttributedStringRef>(); + EXPECT_TRUE(cf_attributed_string); NSAttributedString* ns_attributed_string = - attributed_string.To<NSAttributedString*>(); - EXPECT_TRUE(ns_attributed_string); + base::mac::CFToNSCast(cf_attributed_string); NSRange range; NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0 effectiveRange:&range]; - EXPECT_NSEQ([NSFont systemFontOfSize:12], - [attrs objectForKey:NSFontAttributeName]); + EXPECT_NSEQ([NSFont systemFontOfSize:12], attrs[NSFontAttributeName]); EXPECT_TRUE(NSEqualRanges(range, NSMakeRange(0, 5))); }
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index a156561..a5a855e 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -230,6 +230,7 @@ "java/src/org/chromium/content/browser/NfcHost.java", "java/src/org/chromium/content/browser/PopupController.java", "java/src/org/chromium/content/browser/RenderCoordinatesImpl.java", + "java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java", "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java", "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java", "java/src/org/chromium/content/browser/SpareChildConnection.java", @@ -449,6 +450,7 @@ "java/src/org/chromium/content/browser/MediaSessionImpl.java", "java/src/org/chromium/content/browser/MessagePayloadJni.java", "java/src/org/chromium/content/browser/NfcHost.java", + "java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java", "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java", "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java", "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java", @@ -648,6 +650,7 @@ "junit/src/org/chromium/content/browser/BindingManagerTest.java", "junit/src/org/chromium/content/browser/ChildProcessConnectionMetricsUnitTest.java", "junit/src/org/chromium/content/browser/ChildProcessRankingTest.java", + "junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java", "junit/src/org/chromium/content/browser/GestureListenerManagerImplUnitTest.java", "junit/src/org/chromium/content/browser/ScreenOrientationProviderImplTest.java", "junit/src/org/chromium/content/browser/SpareChildConnectionTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java index 7c8a329..b6b59a2a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
@@ -9,6 +9,8 @@ import android.view.KeyEvent; import android.view.MotionEvent; +import androidx.annotation.VisibleForTesting; + import org.chromium.base.UserData; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -47,16 +49,21 @@ ContentUiEventHandlerJni.get().init(ContentUiEventHandler.this, webContents); } + @VisibleForTesting + static ContentUiEventHandler createForTesting( + WebContents webContents, long nativeContentUiEventHandler) { + ContentUiEventHandler contentUiEventHandler = new ContentUiEventHandler(webContents); + contentUiEventHandler.mNativeContentUiEventHandler = nativeContentUiEventHandler; + return contentUiEventHandler; + } + public void setEventDelegate(InternalAccessDelegate delegate) { mEventDelegate = delegate; } - private EventForwarder getEventForwarder() { - return mWebContents.getEventForwarder(); - } - + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @CalledByNative - private boolean onGenericMotionEvent(MotionEvent event) { + protected boolean onGenericMotionEvent(MotionEvent event) { if (Gamepad.from(mWebContents).onGenericMotionEvent(event)) return true; if (JoystickHandler.fromWebContents(mWebContents).onGenericMotionEvent(event)) return true; if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { @@ -69,13 +76,21 @@ // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here? // https://crbug.com/592082 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { - return onMouseEvent(event); + return onMouseEvent(event, false); } } } + if (isTrackpadEventThatNeedsConversion(event)) { + return onMouseEvent(event, true); + } return mEventDelegate.super_onGenericMotionEvent(event); } + private boolean isTrackpadEventThatNeedsConversion(MotionEvent event) { + return mWebContents.getEventForwarder().isTrackpadToMouseEventConversionEnabled() + && EventForwarder.isTrackpadClickOrClickAndDragEvent(event); + } + private void onMouseWheelEvent(MotionEvent event) { assert mNativeContentUiEventHandler != 0; ContentUiEventHandlerJni.get().sendMouseWheelEvent(mNativeContentUiEventHandler, @@ -84,7 +99,7 @@ event.getAxisValue(MotionEvent.AXIS_VSCROLL)); } - private boolean onMouseEvent(MotionEvent event) { + private boolean onMouseEvent(MotionEvent event, boolean shouldConvertToMouseEvent) { assert mNativeContentUiEventHandler != 0; EventForwarder eventForwarder = mWebContents.getEventForwarder(); boolean didOffsetEvent = false; @@ -99,7 +114,8 @@ event.getPressure(0), event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), EventForwarder.getMouseEventActionButton(event), event.getButtonState(), - event.getMetaState(), event.getToolType(0)); + event.getMetaState(), + shouldConvertToMouseEvent ? MotionEvent.TOOL_TYPE_MOUSE : event.getToolType(0)); if (didOffsetEvent) event.recycle(); return true; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java new file mode 100644 index 0000000..80dbcc58 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java
@@ -0,0 +1,23 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser; + +import org.chromium.base.JavaExceptionReporter; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; + +@JNINamespace("content::android") +class RenderFrameMetadataProviderImpl { + private RenderFrameMetadataProviderImpl() {} + + private static class RenderFrameMetadataProviderRecursiveDeleteException + extends RuntimeException {} + + @CalledByNative + private static void reportRecursiveDelete() { + JavaExceptionReporter.reportException( + new RenderFrameMetadataProviderRecursiveDeleteException()); + } +}
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 56352723..66a4d78 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -223,8 +223,8 @@ } @CalledByNative - @VisibleForTesting - static WebContentsImpl create( + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public static WebContentsImpl create( long nativeWebContentsAndroid, NavigationController navigationController) { return new WebContentsImpl(nativeWebContentsAndroid, navigationController); } @@ -1010,6 +1010,35 @@ return key.cast(data); } + /** + * Convenience method to initialize test state. Only use for testing. + */ + @VisibleForTesting + public void initializeForTesting() { + if (mInternalsHolder == null) { + mInternalsHolder = WebContents.createDefaultInternalsHolder(); + } + WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get(); + if (internals == null) { + internals = new WebContentsInternalsImpl(); + internals.userDataHost = new UserDataHost(); + } + mInternalsHolder.set(internals); + mInitialized = true; + } + + /** + * Convenience method to set user data. Only use for testing. + */ + @VisibleForTesting + public <T extends UserData> void setUserDataForTesting(Class<T> key, T userData) { + // Be sure to call initializeForTesting() first. + assert mInitialized; + + WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get(); + internals.userDataHost.setUserData(key, userData); + } + public <T extends UserData> void removeUserData(Class<T> key) { UserDataHost userDataHost = getUserDataHost(); if (userDataHost == null) return; @@ -1125,8 +1154,9 @@ "Native WebContents already destroyed", mNativeDestroyThrowable); } + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) @NativeMethods - interface Natives { + public interface Natives { // This is static to avoid exposing a public destroy method on the native side of this // class. void destroyWebContents(long webContentsAndroidPtr);
diff --git a/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java b/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java new file mode 100644 index 0000000..685058e --- /dev/null +++ b/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java
@@ -0,0 +1,139 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.view.InputDevice; +import android.view.MotionEvent; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.JniMocker; +import org.chromium.content.browser.webcontents.WebContentsImpl; +import org.chromium.content.browser.webcontents.WebContentsImplJni; +import org.chromium.content_public.browser.NavigationController; +import org.chromium.ui.MotionEventUtils; +import org.chromium.ui.base.EventForwarder; + +/** Unit tests for {@link ContentUiEventHandler} */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ContentUiEventHandlerTest { + private static final int NATIVE_WEB_CONTENTS_ANDROID = 1; + private static final int NATIVE_CONTENT_UI_EVENT_HANDLER = 2; + + @Mock + private NavigationController mNavigationController; + @Mock + private WebContentsImpl.Natives mWebContentsJniMock; + @Mock + private ContentUiEventHandler.Natives mContentUiEventHandlerJniMock; + @Rule + public JniMocker mJniMocker = new JniMocker(); + + private ContentUiEventHandler mContentUiEventHandler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mJniMocker.mock(WebContentsImplJni.TEST_HOOKS, mWebContentsJniMock); + mJniMocker.mock(ContentUiEventHandlerJni.TEST_HOOKS, mContentUiEventHandlerJniMock); + + WebContentsImpl webContentsImpl = + spy(WebContentsImpl.create(NATIVE_WEB_CONTENTS_ANDROID, mNavigationController)); + webContentsImpl.initializeForTesting(); + + Gamepad gamepad = mock(Gamepad.class); + when(gamepad.onGenericMotionEvent(any())).thenReturn(false); + webContentsImpl.setUserDataForTesting(Gamepad.class, gamepad); + + JoystickHandler joystickHandler = mock(JoystickHandler.class); + when(joystickHandler.onGenericMotionEvent(any())).thenReturn(false); + webContentsImpl.setUserDataForTesting(JoystickHandler.class, joystickHandler); + + EventForwarder eventForwarder = mock(EventForwarder.class); + when(eventForwarder.isTrackpadToMouseEventConversionEnabled()).thenReturn(true); + when(eventForwarder.createOffsetMotionEventIfNeeded(any())) + .thenAnswer((Answer<MotionEvent>) invocation -> { + Object[] args = invocation.getArguments(); + return (MotionEvent) args[0]; + }); + doReturn(eventForwarder).when(webContentsImpl).getEventForwarder(); + + mContentUiEventHandler = ContentUiEventHandler.createForTesting( + webContentsImpl, NATIVE_CONTENT_UI_EVENT_HANDLER); + } + + @Test + public void testOnGenericMotionEventSendsTrackpadClicksToNative() { + MotionEvent trackpadLeftClickEvent = getTrackpadLeftClickEvent(); + mContentUiEventHandler.onGenericMotionEvent(getTrackpadLeftClickEvent()); + verifySendMouseEvent(trackpadLeftClickEvent); + + MotionEvent trackpadRightClickEvent = getTrackRightClickEvent(); + mContentUiEventHandler.onGenericMotionEvent(getTrackRightClickEvent()); + verifySendMouseEvent(trackpadRightClickEvent); + } + + private void verifySendMouseEvent(MotionEvent event) { + verify(mContentUiEventHandlerJniMock) + .sendMouseEvent(NATIVE_CONTENT_UI_EVENT_HANDLER, mContentUiEventHandler, + MotionEventUtils.getEventTimeNano(event), event.getActionMasked(), + event.getX(), event.getY(), event.getPointerId(0), event.getPressure(0), + event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), + EventForwarder.getMouseEventActionButton(event), event.getButtonState(), + event.getMetaState(), MotionEvent.TOOL_TYPE_MOUSE); + } + + private static MotionEvent getTrackpadLeftClickEvent() { + return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_PRIMARY); + } + + private static MotionEvent getTrackRightClickEvent() { + return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_SECONDARY); + } + + private static MotionEvent getTrackpadEvent(int action, int buttonState) { + return MotionEvent.obtain(0, 1, action, 1, getToolTypeFingerProperties(), + getPointerCoords(), 0, buttonState, 0, 0, 0, 0, getTrackpadSource(), 0); + } + + private static MotionEvent.PointerProperties[] getToolTypeFingerProperties() { + MotionEvent.PointerProperties[] pointerPropertiesArray = + new MotionEvent.PointerProperties[1]; + MotionEvent.PointerProperties trackpadProperties = new MotionEvent.PointerProperties(); + trackpadProperties.id = 7; + trackpadProperties.toolType = MotionEvent.TOOL_TYPE_FINGER; + pointerPropertiesArray[0] = trackpadProperties; + return pointerPropertiesArray; + } + + private static MotionEvent.PointerCoords[] getPointerCoords() { + MotionEvent.PointerCoords[] pointerCoordsArray = new MotionEvent.PointerCoords[1]; + MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + coords.x = 14; + coords.y = 21; + pointerCoordsArray[0] = coords; + return pointerCoordsArray; + } + + private static int getTrackpadSource() { + return InputDevice.SOURCE_MOUSE; + } +}
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 3e51341..6c75fdb 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -635,7 +635,6 @@ sources += [ "chromeos/multi_capture_service.cc", "chromeos/multi_capture_service.h", - "firewall_hole_proxy.h", "lock_screen_storage.h", "smart_card_delegate.h", ]
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index bf19525f..8182fa1 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -76,10 +76,6 @@ #include "content/public/browser/tts_environment_android.h" #endif -#if BUILDFLAG(IS_CHROMEOS) -#include "content/public/browser/firewall_hole_proxy.h" -#endif - namespace content { std::unique_ptr<BrowserMainParts> ContentBrowserClient::CreateBrowserMainParts(
diff --git a/content/public/browser/firewall_hole_proxy.h b/content/public/browser/firewall_hole_proxy.h deleted file mode 100644 index 25b3bd0..0000000 --- a/content/public/browser/firewall_hole_proxy.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_ -#define CONTENT_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_ - -#include <cstdint> -#include <memory> -#include <string> - -#include "base/functional/callback_forward.h" -#include "content/common/content_export.h" - -namespace content { - -// FirewallHoleProxy represents a hole in the ChromeOS system firewall. -// When this class gets destroyed, it's supposed the close the corresponding -// firewall hole. -class CONTENT_EXPORT FirewallHoleProxy { - public: - using OpenCallback = - base::OnceCallback<void(std::unique_ptr<FirewallHoleProxy>)>; - - virtual ~FirewallHoleProxy() = default; -}; - -// Opens a TCP port on the system firewall for the given |interface| -// (or all interfaces if |interface| is ""). On success invokes the callback -// with a valid FirewallHoleProxy; on failure supplies nullptr. -CONTENT_EXPORT void OpenTCPFirewallHole(const std::string& interface, - uint16_t port, - FirewallHoleProxy::OpenCallback callback); - -// Opens a UDP port on the system firewall for the given |interface| -// (or all interfaces if |interface| is ""). On success invokes the callback -// with a valid FirewallHoleProxy; on failure supplies nullptr. -CONTENT_EXPORT void OpenUDPFirewallHole(const std::string& interface, - uint16_t port, - FirewallHoleProxy::OpenCallback callback); - -} // namespace content - -#endif // CONTENT_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_
diff --git a/content/public/browser/web_ui.h b/content/public/browser/web_ui.h index 95c65d15..e4492b87 100644 --- a/content/public/browser/web_ui.h +++ b/content/public/browser/web_ui.h
@@ -21,6 +21,7 @@ namespace content { +class RenderFrameHost; class WebContents; class WebUIController; class WebUIMessageHandler; @@ -50,6 +51,14 @@ virtual WebUIController* GetController() = 0; virtual void SetController(std::unique_ptr<WebUIController> controller) = 0; + // This might return nullptr + // 1. During construction, until the WebUI is associated with + // a RenderFrameHost. + // 2. During destruction, if the WebUI's destruction causes the + // RenderFrameHost to be destroyed (crbug.com/1308391). + // 3. In unittests where the WebUI is mocked, notably by TestWebUI. + virtual RenderFrameHost* GetRenderFrameHost() = 0; + // Returns the device scale factor of the monitor that the renderer is on. // Whenever possible, WebUI should push resources with this scale factor to // Javascript.
diff --git a/content/public/browser/web_ui_controller.cc b/content/public/browser/web_ui_controller.cc index d23f987f..0e990df 100644 --- a/content/public/browser/web_ui_controller.cc +++ b/content/public/browser/web_ui_controller.cc
@@ -5,6 +5,7 @@ #include "content/public/browser/web_ui_controller.h" #include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/webui/web_ui_managed_interface.h" #include "content/public/browser/web_ui_browser_interface_broker_registry.h" namespace content { @@ -21,7 +22,9 @@ WebUIController::WebUIController(WebUI* web_ui) : web_ui_(web_ui) {} -WebUIController::~WebUIController() = default; +WebUIController::~WebUIController() { + RemoveWebUIManagedInterfaces(this); +} bool WebUIController::OverrideHandleWebUIMessage( const GURL& source_url,
diff --git a/content/public/test/back_forward_cache_util.cc b/content/public/test/back_forward_cache_util.cc index 6a0c862f..0194ad3 100644 --- a/content/public/test/back_forward_cache_util.cc +++ b/content/public/test/back_forward_cache_util.cc
@@ -211,4 +211,17 @@ return final_features; } +void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list, + bool enable_back_forward_cache) { + if (enable_back_forward_cache) { + feature_list->InitWithFeaturesAndParameters( + GetBasicBackForwardCacheFeatureForTesting( + {{kBackForwardCacheNoTimeEviction, {}}, + {features::kBackForwardCacheMemoryControls, {}}}), + {}); + } else { + feature_list->InitAndDisableFeature(features::kBackForwardCache); + } +} + } // namespace content
diff --git a/content/public/test/back_forward_cache_util.h b/content/public/test/back_forward_cache_util.h index fe91afe..4b65bb2 100644 --- a/content/public/test/back_forward_cache_util.h +++ b/content/public/test/back_forward_cache_util.h
@@ -129,6 +129,10 @@ GetDefaultDisabledBackForwardCacheFeaturesForTesting( const std::vector<base::test::FeatureRef>& additional_features); +// Initializes BFCache to `enable_back_forward_cache` for `feature_list`. +void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list, + bool enable_back_forward_cache); + } // namespace content #endif // CONTENT_PUBLIC_TEST_BACK_FORWARD_CACHE_UTIL_H_
diff --git a/content/public/test/content_browser_test_utils_mac.mm b/content/public/test/content_browser_test_utils_mac.mm index 181d41f..9b5a267f 100644 --- a/content/public/test/content_browser_test_utils_mac.mm +++ b/content/public/test/content_browser_test_utils_mac.mm
@@ -142,8 +142,8 @@ const gfx::Point& baseline_point) { std::string string = attributed_string - ? base::SysNSStringToUTF8( - [attributed_string.To<NSAttributedString*>() string]) + ? base::SysCFStringRefToUTF8(CFAttributedStringGetString( + attributed_string.To<CFAttributedStringRef>())) : std::string(); std::move(callback).Run(string, baseline_point); }), @@ -165,8 +165,8 @@ const gfx::Point& baseline_point) { std::string string = attributed_string - ? base::SysNSStringToUTF8( - [attributed_string.To<NSAttributedString*>() string]) + ? base::SysCFStringRefToUTF8(CFAttributedStringGetString( + attributed_string.To<CFAttributedStringRef>())) : std::string(); std::move(callback).Run(string, baseline_point); }),
diff --git a/content/public/test/test_web_ui.cc b/content/public/test/test_web_ui.cc index fe6a71a..3cb32eb 100644 --- a/content/public/test/test_web_ui.cc +++ b/content/public/test/test_web_ui.cc
@@ -48,6 +48,10 @@ return controller_.get(); } +RenderFrameHost* TestWebUI::GetRenderFrameHost() { + return nullptr; +} + void TestWebUI::SetController(std::unique_ptr<WebUIController> controller) { controller_ = std::move(controller); }
diff --git a/content/public/test/test_web_ui.h b/content/public/test/test_web_ui.h index 83a1214..a62df0f 100644 --- a/content/public/test/test_web_ui.h +++ b/content/public/test/test_web_ui.h
@@ -39,6 +39,7 @@ // WebUI overrides. WebContents* GetWebContents() override; WebUIController* GetController() override; + RenderFrameHost* GetRenderFrameHost() override; void SetController(std::unique_ptr<WebUIController> controller) override; float GetDeviceScaleFactor() override; const std::u16string& GetOverriddenTitle() override;
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index 0be71f2..cd449c72 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -23,6 +23,7 @@ #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/test/test_switches.h" +#include "cc/base/switches.h" #include "content/app/mojo/mojo_init.h" #include "content/common/in_process_child_thread_params.h" #include "content/common/pseudonymization_salt.h" @@ -48,7 +49,6 @@ #include "gpu/config/gpu_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/scheduler/test/web_mock_thread_scheduler.h" @@ -179,7 +179,7 @@ cmd->AppendSwitchASCII(switches::kLang, "en-US"); - cmd->AppendSwitchASCII(blink::switches::kNumRasterThreads, "1"); + cmd->AppendSwitchASCII(cc::switches::kNumRasterThreads, "1"); // To avoid creating a GPU channel to query if // accelerated_video_decode is blocklisted on older Android system
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index bb4395ae..309475a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1048,6 +1048,7 @@ mojom("web_ui_test_mojo_bindings") { testonly = true sources = [ + "data/web_ui_managed_interface_test.test-mojom", "data/web_ui_test.test-mojom", "data/web_ui_test_types.test-mojom", ] @@ -1445,6 +1446,7 @@ "../browser/renderer_host/input/wheel_scroll_latching_browsertest.cc", "../browser/renderer_host/isolated_web_app_throttle_browsertest.cc", "../browser/renderer_host/media/video_capture_browsertest.cc", + "../browser/renderer_host/navigation_controller_history_intervention_browsertest.cc", "../browser/renderer_host/navigation_controller_impl_browsertest.cc", "../browser/renderer_host/navigation_handle_user_data_browsertest.cc", "../browser/renderer_host/navigation_policy_container_builder_browsertest.cc", @@ -1549,6 +1551,7 @@ "../browser/webrtc/webrtc_webcam_browsertest.cc", "../browser/webrtc/webrtc_webcam_browsertest.h", "../browser/webui/web_ui_browsertest.cc", + "../browser/webui/web_ui_managed_interface_browsertest.cc", "../browser/webui/web_ui_mojo_browsertest.cc", "../browser/webui/web_ui_navigation_browsertest.cc", "../browser/webui/web_ui_security_browsertest.cc",
diff --git a/content/test/content_unittests_bundle_data.filelist b/content/test/content_unittests_bundle_data.filelist index 32c8395c..b2da4dde 100644 --- a/content/test/content_unittests_bundle_data.filelist +++ b/content/test/content_unittests_bundle_data.filelist
@@ -1809,6 +1809,9 @@ data/web_bundle/web_bundle_browsertest_b2.wbn data/web_bundle/web_bundle_browsertest_b2.wbn.mock-http-headers data/web_ui_dedicated_worker.js +data/web_ui_managed_interface_test.html +data/web_ui_managed_interface_test.js +data/web_ui_managed_interface_test.test-mojom data/web_ui_mojo_native.html data/web_ui_mojo_native.js data/web_ui_mojo_test.html
diff --git a/content/test/data/web_ui_managed_interface_test.html b/content/test/data/web_ui_managed_interface_test.html new file mode 100644 index 0000000..b35460c --- /dev/null +++ b/content/test/data/web_ui_managed_interface_test.html
@@ -0,0 +1,10 @@ +<!-- +Copyright 2023 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<html> +<title>Foo</title> +<script src="/web_ui_managed_interface_test.js" type="module"></script> +</html>
diff --git a/content/test/data/web_ui_managed_interface_test.js b/content/test/data/web_ui_managed_interface_test.js new file mode 100644 index 0000000..ce7679b --- /dev/null +++ b/content/test/data/web_ui_managed_interface_test.js
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {BarCallbackRouter, BazCallbackRouter, FooRemote, TestWebUIJsBridge} from '/web_ui_managed_interface_test.test-mojom-webui.js'; + +Object.assign( + window, + {BarCallbackRouter, BazCallbackRouter, FooRemote, TestWebUIJsBridge});
diff --git a/content/test/data/web_ui_managed_interface_test.test-mojom b/content/test/data/web_ui_managed_interface_test.test-mojom new file mode 100644 index 0000000..781b773 --- /dev/null +++ b/content/test/data/web_ui_managed_interface_test.test-mojom
@@ -0,0 +1,32 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content.mojom; + +interface Foo { + GetFoo() => (string value); +}; + +interface Bar { + GetBar() => (string value); +}; + +interface Baz { + GetBaz() => (string value); +}; + +// A bridge (aka Factory) interface that is used for binding other +// interfaces. +interface TestWebUIJsBridge { + // The WebUI calls this method to bind a Foo remote. + BindFoo(pending_receiver<Foo> foo); + + // The WebUI calls this method to bind a Foo remote and provide the + // browser with a Bar remote. + BindFooBar(pending_receiver<Foo> foo, + pending_remote<Bar> bar); + + // The WebUI calls this method to provide the browser with a Baz remote. + BindBaz(pending_remote<Baz> baz); +};
diff --git a/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt index f0a167b..9fe1b91 100644 --- a/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt index ba87993..92d61bd 100644 --- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt index 7fb9c94d..0216d36 100644 --- a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt index 36dee58..3e36540d 100644 --- a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt index 20db553..d0c0cf56 100644 --- a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt index d7d4730b..03171ba 100644 --- a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt index cf9fc31..1b88e07 100644 --- a/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 34539494..36e5b73 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1 @@ -264,8 +265,8 @@ crbug.com/1201009 [ fuchsia ] Pixel_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ Skip ] # 5 minute timeout on ChromeOS FYI Release (both amd64-generic and kevin) -crbug.com/1353952 [ chromeos chromeos-board-amd64-generic ] Pixel_WebGLContextRestored [ Skip ] -crbug.com/1353952 [ chromeos chromeos-board-kevin ] Pixel_WebGLContextRestored [ Skip ] +crbug.com/1353952 [ chromeos cros-chrome chromeos-board-amd64-generic ] Pixel_WebGLContextRestored [ Skip ] +crbug.com/1353952 [ chromeos cros-chrome chromeos-board-kevin ] Pixel_WebGLContextRestored [ Skip ] ################### # Failures/Flakes # @@ -392,6 +393,12 @@ crbug.com/1418987 [ linux amd-0x7340 angle-vulkan ] Pixel_OffscreenCanvasAccelerated2D [ RetryOnFailure ] crbug.com/1418987 [ linux amd-0x7340 angle-vulkan ] Pixel_OffscreenCanvasWebGLDefaultWorker [ RetryOnFailure ] +# Lacros consistent failures on CrOS devices, skip to save some time +crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_CanvasDisplaySRGBAccelerated2D [ Skip ] +crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_Video_Context_Loss_MP4 [ Skip ] +crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_Video_Context_Loss_VP9 [ Skip ] +crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_WebGLContextRestored [ Skip ] +crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_WebGLPreservedAfterTabSwitch [ Skip ] #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt index 36dee58..3e36540d 100644 --- a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt index 9b9d3b4..bfb21028 100644 --- a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt index 3ea66ba8..2246b8e 100644 --- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt index 13be7d8..df13df2 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 87fd7c2..7111f523 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 8969c970..0db914f 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -20,7 +20,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/validate_tag_consistency.py b/content/test/gpu/validate_tag_consistency.py index 72417817..f651612 100755 --- a/content/test/gpu/validate_tag_consistency.py +++ b/content/test/gpu/validate_tag_consistency.py
@@ -33,7 +33,8 @@ # tags: [ android-chromium android-webview-instrumentation # debug debug-x64 # release release-x64 -# fuchsia-chrome web-engine-shell ] +# fuchsia-chrome web-engine-shell +# lacros-chrome cros-chrome ] # GPU # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340 # apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/web_ui_mojo_test_resources.grd b/content/test/web_ui_mojo_test_resources.grd index 1efffd8..cfd054c 100644 --- a/content/test/web_ui_mojo_test_resources.grd +++ b/content/test/web_ui_mojo_test_resources.grd
@@ -14,6 +14,9 @@ <translations /> <release seq="1"> <includes> + <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_HTML" file="data/web_ui_managed_interface_test.html" type="BINDATA" resource_path="web_ui_managed_interface_test.html" /> + <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_JS" file="data/web_ui_managed_interface_test.js" type="BINDATA" resource_path="web_ui_managed_interface_test.js" /> + <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_TEST_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/content/test/data/web_ui_managed_interface_test.test-mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_managed_interface_test.test-mojom-webui.js" /> <include name="IDR_WEB_UI_MOJO_HTML" file="data/web_ui_mojo_test.html" type="BINDATA" /> <include name="IDR_WEB_UI_MOJO_JS" file="data/web_ui_mojo_test.js" type="BINDATA" resource_path="web_ui_mojo_test.js" /> <include name="IDR_WEB_UI_MOJO_TS_HTML" file="data/web_ui_mojo_ts_test.html" type="BINDATA" />
diff --git a/docs/security/faq.md b/docs/security/faq.md index 37fc27f..79f87620 100644 --- a/docs/security/faq.md +++ b/docs/security/faq.md
@@ -371,12 +371,14 @@ bar or the DevTools console. <a name="TOC-Does-executing-JavaScript-from-a-bookmark-mean-there-s-an-XSS-vulnerability-"></a> -### Does executing JavaScript from a bookmark mean there's an XSS vulnerability? +### Does executing JavaScript from a bookmark or the Home button mean there's an XSS vulnerability? No. Chromium allows users to create bookmarks to JavaScript URLs that will run on the currently-loaded page when the user clicks the bookmark; these are called [bookmarklets](https://en.wikipedia.org/wiki/Bookmarklet). +Similarly, the Home button may be configured to invoke a JavaScript URL when clicked. + <a name="TOC-Does-executing-JavaScript-in-a-PDF-file-mean-there-s-an-XSS-vulnerability-"></a> ### Does executing JavaScript in a PDF file mean there's an XSS vulnerability?
diff --git a/docs/security/security-labels.md b/docs/security/security-labels.md index b7bfca16..19e00009 100644 --- a/docs/security/security-labels.md +++ b/docs/security/security-labels.md
@@ -110,7 +110,7 @@ **Security_Impact**, **OS**, **Pri**, **M**, **Component**, and an **owner** set. -### When to use Security_Impact-None {#TOC-Security_Impact-None} +### When to use Security_Impact-None {#TOC-Security-Impact-None} **Security_Impact-None** says that the bug can't affect any users running the default configuration of Chrome. It's most commonly used for cases where
diff --git a/gpu/command_buffer/service/dxgi_shared_handle_manager.cc b/gpu/command_buffer/service/dxgi_shared_handle_manager.cc index 8878ece..31b05dd 100644 --- a/gpu/command_buffer/service/dxgi_shared_handle_manager.cc +++ b/gpu/command_buffer/service/dxgi_shared_handle_manager.cc
@@ -8,6 +8,7 @@ #include <windows.h> #include "base/atomic_ref_count.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "gpu/command_buffer/common/constants.h" #include "ui/gl/gl_angle_util_win.h" @@ -94,6 +95,8 @@ if (acquired_for_d3d12_) { DLOG(ERROR) << "Recursive BeginAccess not supported"; + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return false; } if (acquired_for_d3d11_count_ > 0) { @@ -104,6 +107,8 @@ dxgi_keyed_mutex_->AcquireSync(kDXGIKeyedMutexAcquireKey, INFINITE); if (FAILED(hr)) { DLOG(ERROR) << "Unable to acquire the keyed mutex " << std::hex << hr; + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return false; } acquired_for_d3d11_count_++;
diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc index 60fb514..9960748 100644 --- a/gpu/command_buffer/service/shared_context_state.cc +++ b/gpu/command_buffer/service/shared_context_state.cc
@@ -370,12 +370,13 @@ bool SharedContextState::InitializeGraphite( const GpuPreferences& gpu_preferences) { #if BUILDFLAG(ENABLE_SKIA_GRAPHITE) - skgpu::graphite::ContextOptions options = GetDefaultGraphiteContextOptions(); + skgpu::graphite::ContextOptions context_options = + GetDefaultGraphiteContextOptions(); if (gr_context_type_ == GrContextType::kGraphiteDawn) { #if BUILDFLAG(SKIA_USE_DAWN) if (dawn_context_provider_ && - dawn_context_provider_->InitializeGraphiteContext(options)) { + dawn_context_provider_->InitializeGraphiteContext(context_options)) { graphite_context_ = dawn_context_provider_->GetGraphiteContext(); } else { DLOG(ERROR) << "Failed to create Graphite Context for Dawn"; @@ -385,7 +386,7 @@ CHECK_EQ(gr_context_type_, GrContextType::kGraphiteMetal); #if BUILDFLAG(SKIA_USE_METAL) if (metal_context_provider_ && - metal_context_provider_->InitializeGraphiteContext(options)) { + metal_context_provider_->InitializeGraphiteContext(context_options)) { graphite_context_ = metal_context_provider_->GetGraphiteContext(); } else { DLOG(ERROR) << "Failed to create Graphite Context for Metal"; @@ -397,7 +398,8 @@ LOG(ERROR) << "Skia Graphite disabled: Graphite Context creation failed."; return false; } - // TODO(crbug.com/1429361): Create graphite recorders here. + gpu_main_graphite_recorder_ = graphite_context_->makeRecorder(); + viz_compositor_graphite_recorder_ = graphite_context_->makeRecorder(); transfer_cache_ = std::make_unique<ServiceTransferCache>(gpu_preferences); return true; #else // BUILDFLAG(ENABLE_SKIA_GRAPHITE)
diff --git a/gpu/command_buffer/service/shared_context_state.h b/gpu/command_buffer/service/shared_context_state.h index fab84ad..c07796e 100644 --- a/gpu/command_buffer/service/shared_context_state.h +++ b/gpu/command_buffer/service/shared_context_state.h
@@ -29,6 +29,7 @@ #include "gpu/ipc/common/command_buffer_id.h" #include "gpu/ipc/common/gpu_peak_memory.h" #include "gpu/vulkan/buildflags.h" +#include "skia/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -49,6 +50,7 @@ namespace skgpu::graphite { class Context; +class Recorder; } // namespace skgpu::graphite namespace gpu { @@ -139,10 +141,30 @@ return dawn_context_provider_; } gl::ProgressReporter* progress_reporter() const { return progress_reporter_; } + // Ganesh/Graphite contexts may only be used on the GPU main thread. GrDirectContext* gr_context() { return gr_context_; } +#if BUILDFLAG(ENABLE_SKIA_GRAPHITE) skgpu::graphite::Context* graphite_context() const { return graphite_context_; } + // Graphite recorder for GPU main thread, used by RasterDecoder, + // SkiaOutputSurfaceImplOnGpu, etc. + skgpu::graphite::Recorder* gpu_main_graphite_recorder() const { + return gpu_main_graphite_recorder_.get(); + } + // Graphite recorder for Viz compositor thread, used by SkiaOutputSurfaceImpl. + skgpu::graphite::Recorder* viz_compositor_graphite_recorder() const { + return viz_compositor_graphite_recorder_.get(); + } +#else + skgpu::graphite::Context* graphite_context() const { return nullptr; } + skgpu::graphite::Recorder* gpu_main_graphite_recorder() const { + return nullptr; + } + skgpu::graphite::Recorder* viz_compositor_graphite_recorder() const { + return nullptr; + } +#endif GrContextType gr_context_type() const { return gr_context_type_; } // Handles Skia-reported shader compilation errors. void compileError(const char* shader, const char* errors) override; @@ -330,7 +352,11 @@ const raw_ptr<viz::DawnContextProvider> dawn_context_provider_ = nullptr; bool created_on_compositor_gpu_thread_ = false; raw_ptr<GrDirectContext> gr_context_ = nullptr; +#if BUILDFLAG(ENABLE_SKIA_GRAPHITE) raw_ptr<skgpu::graphite::Context> graphite_context_ = nullptr; + std::unique_ptr<skgpu::graphite::Recorder> gpu_main_graphite_recorder_; + std::unique_ptr<skgpu::graphite::Recorder> viz_compositor_graphite_recorder_; +#endif scoped_refptr<gl::GLShareGroup> share_group_; scoped_refptr<gl::GLContext> context_;
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc index f3d6bbc9..1c49881 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -6,6 +6,7 @@ #include <d3d11_3.h> +#include "base/debug/dump_without_crashing.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/memory/ptr_util.h" @@ -965,8 +966,11 @@ #endif bool D3DImageBacking::BeginAccessD3D11(bool write_access) { - if (!ValidateBeginAccess(write_access)) + if (!ValidateBeginAccess(write_access)) { + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return false; + } // If read fences or write fence are present, shared handle should be too. DCHECK((read_fences_.empty() && !write_fence_) || dxgi_shared_handle_state_); @@ -976,6 +980,8 @@ // no dependency between concurrent reads and instead wait for the last write. if (write_fence_ && !write_fence_->WaitD3D11(d3d11_device_)) { DLOG(ERROR) << "Failed to wait for write fence"; + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return false; } if (write_access) { @@ -983,6 +989,8 @@ for (const auto& fence : read_fences_) { if (!fence->WaitD3D11(d3d11_device_)) { DLOG(ERROR) << "Failed to wait for read fence"; + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return false; } }
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.cc b/gpu/command_buffer/service/shared_image/shared_image_representation.cc index 7a49807..50bde77 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -408,12 +408,17 @@ OverlayImageRepresentation::BeginScopedReadAccess() { if (!IsCleared()) { LOG(ERROR) << "Attempt to read from an uninitialized SharedImage"; + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return nullptr; } gfx::GpuFenceHandle acquire_fence; - if (!BeginReadAccess(acquire_fence)) + if (!BeginReadAccess(acquire_fence)) { + // TODO(crbug.com/1430941): Remove after fixing overlay access crash. + base::debug::DumpWithoutCrashing(); return nullptr; + } backing()->OnReadSucceeded();
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 033c254..373cc3a 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1931,6 +1931,12 @@ <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_NO_THANKS" desc="The action button to dismiss the password bottom sheet and revert to using the keyboard to fill in username and password information on the webpage."> No Thanks </message> + <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER" desc="The password bottom sheet's long press menu item to open the password manager."> + Password Manager + </message> + <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS" desc="The password bottom sheet's long press menu item to open the password details page, which displays more information, like username, password and associated website."> + Show Details + </message> <message name="IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_CHIP" desc="Acessibility label to describe the UI which displays a product's price in the Price Tracking Item UI."> Price </message> @@ -3126,7 +3132,7 @@ <message name="IDS_IOS_SETTINGS_PRIVACY_TITLE" desc="Title for the Privacy and Security preferences."> Privacy and Security </message> - <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE" desc="Title for the passwords element of safety check" meaning="Row title to access the passowrd check subpage if a probelm is found with user's saved passwords [CHAR_LIMIT=20]"> + <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE" desc="Title for the passwords element of safety check" meaning="Row title to access the password check subpage if a probelm is found with user's saved passwords [CHAR_LIMIT=20]"> Passwords </message> <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_DESCRIPTION" desc="Description text on the password element describing what the password check does.">
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1 new file mode 100644 index 0000000..b227fb1 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1
@@ -0,0 +1 @@ +67d70e4ed9fee06f88c698fdbcf5c0f6f9f2a95e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1 new file mode 100644 index 0000000..b227fb1 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1
@@ -0,0 +1 @@ +67d70e4ed9fee06f88c698fdbcf5c0f6f9f2a95e \ No newline at end of file
diff --git a/ios/chrome/app/variations_app_state_agent.mm b/ios/chrome/app/variations_app_state_agent.mm index 6851a3e2..433c678 100644 --- a/ios/chrome/app/variations_app_state_agent.mm +++ b/ios/chrome/app/variations_app_state_agent.mm
@@ -293,7 +293,7 @@ #pragma mark - IOSChromeVariationsSeedFetcherDelegate -- (void)didFetchSeedSuccess:(BOOL)succeeded { +- (void)variationsSeedFetcherDidCompleteFetchWithSuccess:(BOOL)success { DCHECK_EQ(_group, IOSChromeVariationsGroup::kEnabled); DCHECK_LE(self.appState.initStage, InitStageVariationsSeed); _seedFetchCompleted = YES;
diff --git a/ios/chrome/app/variations_app_state_agent_unittest.mm b/ios/chrome/app/variations_app_state_agent_unittest.mm index 0259c53..c6e6957 100644 --- a/ios/chrome/app/variations_app_state_agent_unittest.mm +++ b/ios/chrome/app/variations_app_state_agent_unittest.mm
@@ -112,7 +112,8 @@ // Simulate that the fetcher has completed fetching. void SimulateFetchCompletion(VariationsAppStateAgent* agent) { - [mock_fetcher_.delegate didFetchSeedSuccess:NO]; + [mock_fetcher_.delegate + variationsSeedFetcherDidCompleteFetchWithSuccess:NO]; } // Setter of the current stage of the mock app state. This also invokes
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index 08c133b..a5121b6 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -28,6 +28,7 @@ "//components/feed:feature_list", "//components/flags_ui", "//components/flags_ui:switches", + "//components/history/core/browser", "//components/invalidation/impl:feature_list", "//components/ntp_tiles", "//components/omnibox/browser",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 63e46891..c64e343 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -40,6 +40,7 @@ #import "components/flags_ui/feature_entry_macros.h" #import "components/flags_ui/flags_storage.h" #import "components/flags_ui/flags_ui_switches.h" +#import "components/history/core/browser/features.h" #import "components/invalidation/impl/invalidation_switches.h" #import "components/ntp_tiles/features.h" #import "components/ntp_tiles/switches.h" @@ -1031,6 +1032,9 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE( optimization_guide::features::kOptimizationTargetPrediction)}, + {"sync-segments-data", flag_descriptions::kSyncSegmentsDataName, + flag_descriptions::kSyncSegmentsDataDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(history::kSyncSegmentsData)}, {"sync-standalone-invalidations", flag_descriptions::kSyncInvalidationsName, flag_descriptions::kSyncInvalidationsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(::syncer::kUseSyncInvalidations)},
diff --git a/ios/chrome/browser/flags/ios_chrome_field_trials.mm b/ios/chrome/browser/flags/ios_chrome_field_trials.mm index 38f5fa9..b144cb0 100644 --- a/ios/chrome/browser/flags/ios_chrome_field_trials.mm +++ b/ios/chrome/browser/flags/ios_chrome_field_trials.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/paths/paths.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_retention_field_trial.h" +#import "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -40,4 +41,7 @@ new_tab_page_retention_field_trial::Create( entropy_providers.low_entropy(), feature_list, GetApplicationContext()->GetLocalState()); + synced_segments_field_trial::Create(entropy_providers.low_entropy(), + feature_list, + GetApplicationContext()->GetLocalState()); }
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 62a386a..1c41f9d 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -953,6 +953,11 @@ const char kSyncSandboxDescription[] = "Connects to the testing server for Chrome Sync."; +const char kSyncSegmentsDataName[] = "Use synced segments data"; +const char kSyncSegmentsDataDescription[] = + "Enables history's segments to include foreign visits from syncing " + "devices."; + const char kSynthesizedRestoreSessionName[] = "Use a synthesized native WKWebView sesion restoration (iOS15 only)."; const char kSynthesizedRestoreSessionDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 740ae629..c484b44 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -846,6 +846,11 @@ extern const char kSyncSandboxName[]; extern const char kSyncSandboxDescription[]; +// Title and description for the flag to control if history's segments should +// include foreign visits from syncing devices. +extern const char kSyncSegmentsDataName[]; +extern const char kSyncSegmentsDataDescription[]; + // Title and description for the flag to synthesize native restore web states. extern const char kSynthesizedRestoreSessionName[]; extern const char kSynthesizedRestoreSessionDescription[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 0269032d..dd437d19 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -76,6 +76,7 @@ #import "ios/chrome/browser/ui/first_run/trending_queries_field_trial.h" #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_retention_field_trial.h" +#import "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h" #import "ios/chrome/browser/voice/voice_search_prefs_registration.h" #import "ios/chrome/browser/web/font_size/font_size_tab_helper.h" #import "ios/web/common/features.h" @@ -140,6 +141,7 @@ variations::VariationsService::RegisterPrefs(registry); trending_queries_field_trial::RegisterLocalStatePrefs(registry); new_tab_page_retention_field_trial::RegisterLocalStatePrefs(registry); + synced_segments_field_trial::RegisterLocalStatePrefs(registry); component_updater::RegisterComponentUpdateServicePrefs(registry); component_updater::AutofillStatesComponentInstallerPolicy::RegisterPrefs( registry);
diff --git a/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn index 45e18c2..cadb0e2a 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn
@@ -19,7 +19,9 @@ deps = [ ":bring_android_tabs_ui", ":bring_android_tabs_ui_swift", + ":constants", "//base", + "//components/favicon/core", "//ios/chrome/browser/bring_android_tabs", "//ios/chrome/browser/bring_android_tabs:features", "//ios/chrome/browser/bring_android_tabs:metrics", @@ -29,6 +31,7 @@ "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//ios/chrome/browser/shared/public/commands", + "//ios/chrome/browser/shared/ui/list_model", "//ios/chrome/browser/shared/ui/table_view", "//ios/chrome/browser/synced_sessions", "//ios/chrome/browser/url_loading", @@ -41,11 +44,27 @@ configs += [ "//build/config/compiler:enable_arc" ] sources = [ "bring_android_tabs_prompt_view_controller_delegate.h", + "tab_list_from_android_consumer.h", + "tab_list_from_android_table_view_item.h", + "tab_list_from_android_table_view_item.mm", + "tab_list_from_android_view_controller.h", + "tab_list_from_android_view_controller.mm", "tab_list_from_android_view_controller_delegate.h", ] deps = [ ":constants", "//base", + "//components/url_formatter", + "//ios/chrome/app/strings", + "//ios/chrome/browser/bring_android_tabs", + "//ios/chrome/browser/net:crurl", + "//ios/chrome/browser/shared/ui/list_model", + "//ios/chrome/browser/shared/ui/table_view", + "//ios/chrome/browser/shared/ui/table_view:utils", + "//ios/chrome/browser/synced_sessions", + "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/favicon", + "//ios/chrome/common/ui/table_view:cells_constants", ] }
diff --git a/ios/chrome/browser/ui/bring_android_tabs/constants.h b/ios/chrome/browser/ui/bring_android_tabs/constants.h index 67afece..bf3ea55 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/constants.h +++ b/ios/chrome/browser/ui/bring_android_tabs/constants.h
@@ -15,4 +15,14 @@ // view controller. extern NSString* const kBringAndroidTabsPromptBottomMessageAXId; +// Accessibility identifier for the "Bring Android Tabs" tab list +// view controller. +extern NSString* const kBringAndroidTabsPromptTabListAXId; + +// Size of the favicons in the "Bring Android Tabs" tab list. +extern CGFloat const kBringAndroidTabsFaviconSize; + +// Height of the table rows in the "Bring Android Tabs" tab list. +extern CGFloat const kTabListFromAndroidCellHeight; + #endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/constants.mm b/ios/chrome/browser/ui/bring_android_tabs/constants.mm index c15d52cc..ff9cc96 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/constants.mm +++ b/ios/chrome/browser/ui/bring_android_tabs/constants.mm
@@ -13,3 +13,10 @@ NSString* const kBringAndroidTabsPromptBottomMessageAXId = @"kBringAndroidTabsPromptBottomMessageAccessibilityIdentifier"; + +NSString* const kBringAndroidTabsPromptTabListAXId = + @"kBringAndroidTabsPromptTabListAccessibilityIdentifier"; + +CGFloat const kBringAndroidTabsFaviconSize = 48; + +CGFloat const kTabListFromAndroidCellHeight = 78.0;
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h new file mode 100644 index 0000000..370981a8 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h
@@ -0,0 +1,20 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_ + +#import <Foundation/Foundation.h> + +@class TabListFromAndroidTableViewItem; + +// Consumer for the Tab List From Android view. +@protocol TabListFromAndroidConsumer + +// Sets the `items` displayed by this consumer. +- (void)setTabListItems:(NSArray<TabListFromAndroidTableViewItem*>*)items; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm index 493b5bb..76c991c7 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm
@@ -4,14 +4,19 @@ #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.h" +#import "components/favicon/core/favicon_service.h" +#import "components/keyed_service/core/service_access_type.h" #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/favicon/favicon_service_factory.h" #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h" #import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller.h" +#import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller.h" #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -21,9 +26,8 @@ @implementation TabListFromAndroidCoordinator { // Main mediator for this coordinator. TabListFromAndroidMediator* _mediator; - - // Main view controller for this coordinator. - ChromeTableViewController* _viewController; + // Navigation controller displaying TabListFromAndroidViewController. + TableViewNavigationController* _navigationController; } - (void)start { @@ -38,20 +42,32 @@ GetForBrowserState( self.browser->GetBrowserState())]; - // TODO(crbug.com/1418120): Create table view controller. - /*_viewController = [ChromeTableViewController - initWithBringAndroidTabsService:service - delegate:_mediator - commandHandler:HandlerForProtocol(self.browser->GetCommandDispatcher(), - BringAndroidTabsCommands)];*/ + TabListFromAndroidViewController* tableViewController = + [[TabListFromAndroidViewController alloc] init]; + tableViewController.delegate = _mediator; + tableViewController.faviconDataSource = _mediator; + _mediator.consumer = tableViewController; + + _navigationController = + [[TableViewNavigationController alloc] initWithTable:tableViewController]; + [_navigationController + setModalPresentationStyle:UIModalPresentationFormSheet]; + _navigationController.toolbarHidden = YES; + _navigationController.overrideUserInterfaceStyle = UIUserInterfaceStyleDark; + _navigationController.presentationController.delegate = tableViewController; + + [self.baseViewController presentViewController:_navigationController + animated:YES + completion:nil]; } - (void)stop { [super stop]; - [_viewController.presentingViewController dismissViewControllerAnimated:YES - completion:nil]; + [_navigationController.presentingViewController + dismissViewControllerAnimated:YES + completion:nil]; _mediator = nil; - _viewController = nil; + _navigationController = nil; } @end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h index 4f2cfef..e331397 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h
@@ -12,12 +12,16 @@ class BringAndroidTabsToIOSService; class FaviconLoader; +@protocol TabListFromAndroidConsumer; class UrlLoadingBrowserAgent; // Mediator for the "Tab List From Android" table. @interface TabListFromAndroidMediator - : NSObject <TabListFromAndroidViewControllerDelegate, - TableViewFaviconDataSource> + : NSObject <TableViewFaviconDataSource, + TabListFromAndroidViewControllerDelegate> + +// The main consumer for this mediator. +@property(nonatomic, weak) id<TabListFromAndroidConsumer> consumer; // Designated initializer for the mediator. `service` is used to load the user's // tabs to bring to iOS from their Android device.
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm index 48c811c..985bfe70 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm
@@ -5,11 +5,17 @@ #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h" #import "base/metrics/histogram_functions.h" +#import "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" #import "ios/chrome/browser/bring_android_tabs/metrics.h" #import "ios/chrome/browser/favicon/favicon_loader.h" #import "ios/chrome/browser/net/crurl.h" +#import "ios/chrome/browser/shared/ui/list_model/list_model.h" +#import "ios/chrome/browser/synced_sessions/distant_tab.h" #import "ios/chrome/browser/synced_sessions/synced_sessions_util.h" +#import "ios/chrome/browser/ui/bring_android_tabs/constants.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/common/ui/favicon/favicon_constants.h" @@ -18,6 +24,14 @@ #error "This file requires ARC support." #endif +namespace { + +typedef NS_ENUM(NSInteger, ItemType) { + TabItemType = kItemTypeEnumZero, +}; + +} // namespace + @implementation TabListFromAndroidMediator { // Keyed service to retrieve active tabs from Android. BringAndroidTabsToIOSService* _bringAndroidTabsService; @@ -40,13 +54,18 @@ return self; } +- (void)setConsumer:(id<TabListFromAndroidConsumer>)consumer { + _consumer = consumer; + [_consumer setTabListItems:[self tableViewItemArray]]; +} + #pragma mark - TableViewFaviconDataSource - (void)faviconForPageURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { _faviconLoader->FaviconForPageUrl( - URL.gurl, kDesiredMediumFaviconSizePt, kMinFaviconSizePt, - /*fallback_to_google_server=*/false, ^(FaviconAttributes* attributes) { + URL.gurl, kBringAndroidTabsFaviconSize, kMinFaviconSizePt, + /*fallback_to_google_server=*/true, ^(FaviconAttributes* attributes) { completion(attributes); }); } @@ -54,14 +73,15 @@ #pragma mark - TabListFromAndroidViewControllerDelegate - (void)tabListFromAndroidViewControllerDidDismissWithSwipe:(BOOL)swiped - numberOfDeselectedTabs:(int)count { + numberOfDeselectedTabs: + (int)countDeselected { bring_android_tabs::TabsListActionType action = swiped ? bring_android_tabs::TabsListActionType::kSwipeDown : bring_android_tabs::TabsListActionType::kCancel; base::UmaHistogramEnumeration(bring_android_tabs::kTabListActionHistogramName, action); base::UmaHistogramCounts1000( - bring_android_tabs::kDeselectedTabCountHistogramName, count); + bring_android_tabs::kDeselectedTabCountHistogramName, countDeselected); // The user journey to bring recent tabs on Android to iOS has finished. // Reload the service to update/clear the tabs. _bringAndroidTabsService->LoadTabs(); @@ -86,4 +106,24 @@ } } +#pragma mark - Private + +// Returns an array of table view items corresponding to the user's tabs from +// Android. +- (NSArray<TabListFromAndroidTableViewItem*>*)tableViewItemArray { + NSMutableArray<TabListFromAndroidTableViewItem*>* itemArray = + [[NSMutableArray alloc] init]; + for (size_t idx = 0; idx < _bringAndroidTabsService->GetNumberOfAndroidTabs(); + idx++) { + synced_sessions::DistantTab* distantTab = + _bringAndroidTabsService->GetTabAtIndex(idx); + TabListFromAndroidTableViewItem* tabListItem = + [[TabListFromAndroidTableViewItem alloc] initWithType:TabItemType]; + tabListItem.title = base::SysUTF16ToNSString(distantTab->title); + tabListItem.URL = [[CrURL alloc] initWithGURL:distantTab->virtual_url]; + [itemArray addObject:tabListItem]; + } + return itemArray; +} + @end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h new file mode 100644 index 0000000..733f444 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h
@@ -0,0 +1,51 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_cell.h" +#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_item.h" + +@class CrURL; +@class FaviconView; + +// TabListFromAndroidTableViewItem contains the model data for a +// TabListFromAndroidTableViewCell. +@interface TabListFromAndroidTableViewItem : TableViewItem + +// The title of the page at `URL`. +@property(nonatomic, readwrite, copy) NSString* title; + +// CrURL from which the cell will retrieve a favicon and display the host name. +@property(nonatomic, readwrite, strong) CrURL* URL; + +// Identifier to match a TabListFromAndroidTableViewItem with its +// TabListFromAndroidTableViewCell. +@property(nonatomic, readonly) NSString* uniqueIdentifier; + +@end + +// TabListFromAndroidTableViewCell is used in the Bring Android Tabs prompt. +// Contains a favicon, title, and URL. +@interface TabListFromAndroidTableViewCell : TableViewCell + +// The imageview that is displayed on the leading edge of the cell. This +// contains a favicon composited on top of an off-white background. +@property(nonatomic, readwrite, strong) FaviconView* faviconView; + +// The cell title. +@property(nonatomic, readonly, strong) UILabel* titleLabel; + +// The host URL associated with this cell. +@property(nonatomic, readonly, strong) UILabel* URLLabel; + +// Unique identifier that matches with one TabListFromAndroidTableViewItem. +@property(nonatomic, strong) NSString* cellUniqueIdentifier; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm new file mode 100644 index 0000000..ea8c02cc --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm
@@ -0,0 +1,217 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h" + +#import "base/mac/foundation_util.h" +#import "base/strings/sys_string_conversions.h" +#import "components/url_formatter/elide_url.h" +#import "ios/chrome/browser/net/crurl.h" +#import "ios/chrome/browser/ui/bring_android_tabs/constants.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/favicon/favicon_container_view.h" +#import "ios/chrome/common/ui/favicon/favicon_view.h" +#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation TabListFromAndroidTableViewItem + +- (instancetype)initWithType:(NSInteger)type { + if (self = [super initWithType:type]) { + self.cellClass = [TabListFromAndroidTableViewCell class]; + } + return self; +} + +- (void)configureCell:(TableViewCell*)tableCell + withStyler:(ChromeTableViewStyler*)styler { + [super configureCell:tableCell withStyler:styler]; + + TabListFromAndroidTableViewCell* cell = + base::mac::ObjCCastStrict<TabListFromAndroidTableViewCell>(tableCell); + cell.titleLabel.text = [self titleLabelText]; + cell.URLLabel.text = [self URLLabelText]; + cell.cellUniqueIdentifier = self.uniqueIdentifier; + cell.accessibilityTraits |= UIAccessibilityTraitButton; +} + +- (NSString*)uniqueIdentifier { + return self.URL ? base::SysUTF8ToNSString(self.URL.gurl.host()) : @""; +} + +#pragma mark - Private + +// Returns the text to use when configuring a TabListFromAndroidTableViewCell's +// title label. +- (NSString*)titleLabelText { + if (self.title.length) { + return self.title; + } + if (!self.URL) { + return @""; + } + NSString* hostname = [self displayedURL]; + if (hostname.length) { + return hostname; + } + // Backup in case host returns nothing (e.g. about:blank). + return base::SysUTF8ToNSString(self.URL.gurl.spec()); +} + +// Returns the text to use when configuring a TabListFromAndroidTableViewCell's +// URL label. +- (NSString*)URLLabelText { + return self.URL ? [self displayedURL] : @""; +} + +// Returns a formatted URL text. +- (NSString*)displayedURL { + return base::SysUTF16ToNSString( + url_formatter:: + FormatUrlForDisplayOmitSchemePathTrivialSubdomainsAndMobilePrefix( + self.URL.gurl)); +} + +@end + +@implementation TabListFromAndroidTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style + reuseIdentifier:(NSString*)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + _faviconView = [[FaviconView alloc] init]; + _titleLabel = [[UILabel alloc] init]; + _URLLabel = [[UILabel alloc] init]; + self.isAccessibilityElement = YES; + } + return self; +} + +#pragma mark - UIView + +- (void)willMoveToSuperview:(UIView*)newSuperview { + [super willMoveToSuperview:newSuperview]; + + [self createSubviews]; +} + +#pragma mark - Accessors + +- (NSString*)accessibilityLabel { + NSString* accessibilityLabel = self.titleLabel.text; + accessibilityLabel = [NSString + stringWithFormat:@"%@, %@", accessibilityLabel, self.URLLabel.text]; + return accessibilityLabel; +} + +- (NSArray<NSString*>*)accessibilityUserInputLabels { + NSMutableArray<NSString*>* userInputLabels = [[NSMutableArray alloc] init]; + if (self.titleLabel.text) { + [userInputLabels addObject:self.titleLabel.text]; + } + return userInputLabels; +} + +- (NSString*)accessibilityIdentifier { + return self.titleLabel.text; +} + +#pragma mark - Private + +// Creates and lays out the favicon, title, and URL subviews. +- (void)createSubviews { + // Return if the subviews have already been created and added. + if (self.contentView.subviews.count != 0) { + return; + } + FaviconContainerView* faviconContainerView = [self faviconContainerView]; + UIStackView* verticalStack = [self stackView]; + + UIView* contentView = self.contentView; + contentView.frame = self.frame; + [contentView addSubview:faviconContainerView]; + [contentView addSubview:verticalStack]; + + NSLayoutConstraint* heightConstraint = [contentView.heightAnchor + constraintGreaterThanOrEqualToConstant:kTabListFromAndroidCellHeight]; + // Don't set the priority to required to avoid clashing with the estimated + // height. + heightConstraint.priority = UILayoutPriorityRequired - 1; + + CGFloat faviconContainerSize = kBringAndroidTabsFaviconSize + 3; + + [NSLayoutConstraint activateConstraints:@[ + [faviconContainerView.leadingAnchor + constraintEqualToAnchor:contentView.leadingAnchor + constant:kTableViewHorizontalSpacing], + [faviconContainerView.centerYAnchor + constraintEqualToAnchor:contentView.centerYAnchor], + [faviconContainerView.widthAnchor + constraintEqualToConstant:faviconContainerSize], + [faviconContainerView.heightAnchor + constraintEqualToAnchor:faviconContainerView.widthAnchor], + + [_faviconView.widthAnchor + constraintEqualToConstant:kBringAndroidTabsFaviconSize], + [_faviconView.heightAnchor + constraintEqualToAnchor:_faviconView.widthAnchor], + [_faviconView.centerYAnchor + constraintEqualToAnchor:faviconContainerView.centerYAnchor], + [_faviconView.centerXAnchor + constraintEqualToAnchor:faviconContainerView.centerXAnchor], + + [verticalStack.leadingAnchor + constraintEqualToAnchor:faviconContainerView.trailingAnchor + constant:kTableViewSubViewHorizontalSpacing], + [verticalStack.trailingAnchor + constraintEqualToAnchor:contentView.trailingAnchor + constant:-kTableViewHorizontalSpacing], + [verticalStack.centerYAnchor + constraintEqualToAnchor:contentView.centerYAnchor], + [verticalStack.topAnchor + constraintGreaterThanOrEqualToAnchor:contentView.topAnchor + constant: + kTableViewTwoLabelsCellVerticalSpacing], + [verticalStack.bottomAnchor + constraintLessThanOrEqualToAnchor:contentView.bottomAnchor + constant: + -kTableViewTwoLabelsCellVerticalSpacing], + heightConstraint + ]]; +} + +// Creates and returns the vertical stack view. The stack consists of a title +// and URL. +- (UIStackView*)stackView { + _titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; + _titleLabel.adjustsFontForContentSizeCategory = YES; + _titleLabel.numberOfLines = 2; + _URLLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + _URLLabel.adjustsFontForContentSizeCategory = YES; + _URLLabel.textColor = [UIColor colorNamed:kTextSecondaryColor]; + + UIStackView* verticalStack = [[UIStackView alloc] + initWithArrangedSubviews:@[ _titleLabel, _URLLabel ]]; + verticalStack.axis = UILayoutConstraintAxisVertical; + verticalStack.translatesAutoresizingMaskIntoConstraints = NO; + return verticalStack; +} + +// Creates and returns the container for the favicon view. +- (FaviconContainerView*)faviconContainerView { + FaviconContainerView* faviconContainerView = + [[FaviconContainerView alloc] init]; + [faviconContainerView addSubview:_faviconView]; + faviconContainerView.translatesAutoresizingMaskIntoConstraints = NO; + _faviconView.translatesAutoresizingMaskIntoConstraints = NO; + _faviconView.contentMode = UIViewContentModeScaleAspectFill; + _faviconView.clipsToBounds = YES; + _faviconView.layer.masksToBounds = YES; + return faviconContainerView; +} + +@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h new file mode 100644 index 0000000..d84e2a4 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h
@@ -0,0 +1,34 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h" + +@protocol TableViewFaviconDataSource; +@protocol TabListFromAndroidViewControllerDelegate; + +// Table view controller for the "Bring Android Tabs" tab list. +@interface TabListFromAndroidViewController + : ChromeTableViewController <TabListFromAndroidConsumer, + UIAdaptivePresentationControllerDelegate> + +// Delegate protocol that handles model updates on interaction. +@property(nonatomic, weak) id<TabListFromAndroidViewControllerDelegate> + delegate; + +// Data source for favicon images. +@property(nonatomic, weak) id<TableViewFaviconDataSource> faviconDataSource; + +// Designated initializer for this view controller. +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +// Unavailable initializer. +- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm new file mode 100644 index 0000000..311ca49 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm
@@ -0,0 +1,219 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h" + +#import "base/check_op.h" +#import "base/i18n/message_formatter.h" +#import "base/mac/foundation_util.h" +#import "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/net/crurl.h" +#import "ios/chrome/browser/shared/ui/list_model/list_model.h" +#import "ios/chrome/browser/shared/ui/table_view/table_view_favicon_data_source.h" +#import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" +#import "ios/chrome/browser/synced_sessions/distant_tab.h" +#import "ios/chrome/browser/ui/bring_android_tabs/constants.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h" +#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h" +#import "ios/chrome/common/ui/favicon/favicon_attributes.h" +#import "ios/chrome/common/ui/favicon/favicon_view.h" +#import "ios/chrome/grit/ios_strings.h" +#import "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +typedef NS_ENUM(NSInteger, SectionIdentifier) { + TabListSectionIdentifier = kSectionIdentifierEnumZero, +}; + +} // namespace + +@implementation TabListFromAndroidViewController + +- (instancetype)init { + return [super initWithStyle:ChromeTableViewStyle()]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.definesPresentationContext = YES; + self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark; + self.title = + l10n_util::GetNSString(IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE); + [self.tableView setDelegate:self]; + self.tableView.allowsMultipleSelectionDuringEditing = YES; + self.tableView.allowsMultipleSelection = YES; + [self.tableView + setSeparatorInset:UIEdgeInsetsMake(0, kTableViewSeparatorInset, 0, 0)]; + self.tableView.estimatedRowHeight = kTabListFromAndroidCellHeight; + self.navigationItem.leftBarButtonItem = [self navigationCancelButton]; + self.navigationItem.rightBarButtonItem = [self navigationOpenTabsButton]; + self.tableView.accessibilityIdentifier = kBringAndroidTabsPromptTabListAXId; +} + +#pragma mark - UITableViewDelegate + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + CHECK_EQ(tableView, self.tableView); + TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; + item.accessoryType = UITableViewCellAccessoryCheckmark; + [self reconfigureCellsForItems:@[ item ]]; + [self updateOpenTabsButton]; +} + +- (void)tableView:(UITableView*)tableView + didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { + CHECK_EQ(tableView, self.tableView); + TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; + item.accessoryType = UITableViewCellAccessoryNone; + [self reconfigureCellsForItems:@[ item ]]; + [self updateOpenTabsButton]; +} + +- (UITableViewCell*)tableView:(UITableView*)tableView + cellForRowAtIndexPath:(NSIndexPath*)indexPath { + CHECK_EQ(tableView, self.tableView); + UITableViewCell* cell = [super tableView:tableView + cellForRowAtIndexPath:indexPath]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + [self loadFaviconForCell:cell indexPath:indexPath]; + return cell; +} + +#pragma mark - UIAdaptivePresentationControllerDelegate + +- (void)presentationControllerDidDismiss: + (UIPresentationController*)presentationController { + int numberDeselected = + [self.tableView numberOfRowsInSection:TabListSectionIdentifier] - + [self.tableView indexPathsForSelectedRows].count; + [_delegate + tabListFromAndroidViewControllerDidDismissWithSwipe:YES + numberOfDeselectedTabs:numberDeselected]; +} + +#pragma mark - TabListFromAndroidConsumer + +- (void)setTabListItems:(NSArray<TabListFromAndroidTableViewItem*>*)items { + [self loadModel]; + + [self.tableViewModel addSectionWithIdentifier:TabListSectionIdentifier]; + for (TabListFromAndroidTableViewItem* item : items) { + item.accessoryType = UITableViewCellAccessoryCheckmark; + [self.tableViewModel addItem:item + toSectionWithIdentifier:TabListSectionIdentifier]; + } + // Tabs are selected by default. + NSInteger section = [self.tableViewModel + sectionForSectionIdentifier:TabListSectionIdentifier]; + for (NSInteger index = 0; + index < [self.tableViewModel numberOfItemsInSection:section]; index++) { + [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:index + inSection:section] + animated:NO + scrollPosition:UITableViewScrollPositionNone]; + } + + [self updateOpenTabsButton]; +} + +#pragma mark - Helpers + +// Retrieves favicon from FaviconLoader and sets FaviconView in given `cell`. +- (void)loadFaviconForCell:(UITableViewCell*)cell + indexPath:(NSIndexPath*)indexPath { + TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; + CHECK(item); + CHECK(cell); + TabListFromAndroidTableViewItem* tabListItem = + base::mac::ObjCCastStrict<TabListFromAndroidTableViewItem>(item); + TabListFromAndroidTableViewCell* tabListCell = + base::mac::ObjCCastStrict<TabListFromAndroidTableViewCell>(cell); + + NSString* itemIdentifier = tabListItem.uniqueIdentifier; + [_faviconDataSource + faviconForPageURL:tabListItem.URL + completion:^(FaviconAttributes* attributes) { + // Only set favicon if the cell hasn't been reused. + if ([tabListCell.cellUniqueIdentifier + isEqualToString:itemIdentifier]) { + [tabListCell.faviconView configureWithAttributes:attributes]; + } + }]; +} + +// Returns the navigation 'cancel' button. +- (UIBarButtonItem*)navigationCancelButton { + return [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self + action:@selector(cancelButtonTapped)]; +} + +// Updates the title and enabled status of the 'Open Tabs' button. This method +// is called and the button is recreated every time the user selects/de-selects +// a table row. +- (void)updateOpenTabsButton { + UIBarButtonItem* rightBarButton = self.navigationItem.rightBarButtonItem; + rightBarButton.title = [self openTabsButtonTitle]; + int numberSelectedTabs = [self.tableView indexPathsForSelectedRows].count; + if (numberSelectedTabs == 0) { + [rightBarButton setEnabled:NO]; + } else { + [rightBarButton setEnabled:YES]; + } +} + +// Returns the title of the navigation 'Open Tabs' button. +- (NSString*)openTabsButtonTitle { + int numberSelectedTabs = [self.tableView indexPathsForSelectedRows].count; + return base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16( + IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON, numberSelectedTabs)); +} + +// Returns the navigation 'Open Tabs' button. +- (UIBarButtonItem*)navigationOpenTabsButton { + return [[UIBarButtonItem alloc] initWithTitle:[self openTabsButtonTitle] + style:UIBarButtonItemStylePlain + target:self + action:@selector(openButtonTapped)]; +} + +// Called when the cancel button is tapped. +- (void)cancelButtonTapped { + int numberDeselected = + [self.tableView numberOfRowsInSection:TabListSectionIdentifier] - + [self.tableView indexPathsForSelectedRows].count; + [_delegate + tabListFromAndroidViewControllerDidDismissWithSwipe:NO + numberOfDeselectedTabs:numberDeselected]; + [self.presentingViewController dismissViewControllerAnimated:YES + completion:nil]; +} + +// Called when the open tabs button is tapped. +- (void)openButtonTapped { + [_delegate tabListFromAndroidViewControllerDidTapOpenButtonWithTabIndices: + [self selectedTabIndices]]; + [self.presentingViewController dismissViewControllerAnimated:YES + completion:nil]; +} + +// Returns an array with the indices of the tabs the user has selected. Indices +// correspond to the indices of the list of user's tabs retrieved from +// BringAndroidTabsToIOSService. +- (NSArray<NSNumber*>*)selectedTabIndices { + NSMutableArray<NSNumber*>* tabIndices = [[NSMutableArray alloc] init]; + for (NSIndexPath* indexPath in self.tableView.indexPathsForSelectedRows) { + [tabIndices addObject:@(indexPath.row)]; + } + return tabIndices; +} + +@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h index 9c33c3a0..d398b354 100644 --- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h +++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h
@@ -10,10 +10,11 @@ @protocol TabListFromAndroidViewControllerDelegate // Called when the user dismisses the prompt. If the dismissal is done using a -// modal swipe, the parameter `swiped` is YES. `count` is the number of tabs the -// user deselected before dismissal. +// modal swipe, the parameter `swiped` is YES. `countDeselected` is the number +// of tabs the user deselected before dismissal. - (void)tabListFromAndroidViewControllerDidDismissWithSwipe:(BOOL)swiped - numberOfDeselectedTabs:(int)count; + numberOfDeselectedTabs: + (int)countDeselected; // Called when the user taps the "open" button. Values in `tabIndices` // correspond to the indices of the tabs the user wants to open in the
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index 26571a5d..90f8393 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -2659,6 +2659,7 @@ #pragma mark - NewTabPageTabHelperDelegate +// TODO(crbug.com/1427128): Have the TabEventsMediator implement this. - (void)newTabPageHelperDidChangeVisibility:(NewTabPageTabHelper*)NTPHelper forWebState:(web::WebState*)webState { DCHECK(self.browser); @@ -2672,16 +2673,15 @@ } NewTabPageCoordinator* NTPCoordinator = self.NTPCoordinator; DCHECK(NTPCoordinator); + // Handle NTP visibility changes within a web state. if (NTPHelper->IsActive()) { - // Starting the NTPCoordinator triggers its visibility, so we only - // explicitly call `didNavigateToNTP` if the NTP was already started. - if (NTPCoordinator.started) { - [NTPCoordinator didNavigateToNTP]; - } else { + if (!NTPCoordinator.started) { [NTPCoordinator start]; } + [NTPCoordinator didNavigateToNTPInWebState:webState]; } else { [NTPCoordinator didNavigateAwayFromNTP]; + [NTPCoordinator stopIfNeeded]; } if (self.isActive) { [self.viewController displayCurrentTab];
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm index 741e6923..3b6db39 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
@@ -325,7 +325,7 @@ EXPECT_OCMOCK_VERIFY(mockNTPCoordinator); // Open another NTP and expect a navigation call. - [[mockNTPCoordinator expect] didNavigateToNTP]; + [[mockNTPCoordinator expect] didNavigateToNTPInWebState:GetActiveWebState()]; OpenURL(GURL("chrome://newtab/")); EXPECT_OCMOCK_VERIFY(mockNTPCoordinator);
diff --git a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm index 28816874..62e2508 100644 --- a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm +++ b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
@@ -111,16 +111,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didDetachWebState:(web::WebState*)webState - atIndex:(int)atIndex { - NewTabPageTabHelper* NTPTabHelper = - NewTabPageTabHelper::FromWebState(webState); - if (NTPTabHelper->IsActive()) { - [self stopNTPIfNeeded]; - } -} - -- (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index activating:(BOOL)activating { @@ -133,10 +123,32 @@ } - (void)webStateList:(WebStateList*)webStateList + willCloseWebState:(web::WebState*)webState + atIndex:(int)atIndex + userAction:(BOOL)userAction { + // When an NTP web state is closed, check if the coordinator should be + // stopped. + NewTabPageTabHelper* NTPTabHelper = + NewTabPageTabHelper::FromWebState(webState); + if (NTPTabHelper->IsActive()) { + [self stopNTPIfNeeded]; + } +} + +- (void)webStateList:(WebStateList*)webStateList didChangeActiveWebState:(web::WebState*)newWebState oldWebState:(web::WebState*)oldWebState atIndex:(int)atIndex reason:(ActiveWebStateChangeReason)reason { + // If the user is leaving an NTP web state, trigger a visibility change. + if (oldWebState && _ntpCoordinator.started) { + NewTabPageTabHelper* NTPHelper = + NewTabPageTabHelper::FromWebState(oldWebState); + if (NTPHelper->IsActive()) { + [_ntpCoordinator didNavigateAwayFromNTP]; + } + } + if (reason == ActiveWebStateChangeReason::Inserted) { [self didInsertActiveWebState:newWebState]; } @@ -150,6 +162,14 @@ // WebState is showing the NTP. BrowserCoordinator's -setActive: only starts // the NTP if it is the active view. [self startNTPIfNeededForActiveWebState:newWebState]; + + // If the user is entering an NTP web state, trigger a visibility change. + NewTabPageTabHelper* NTPHelper = + NewTabPageTabHelper::FromWebState(newWebState); + if (NTPHelper->IsActive()) { + [_ntpCoordinator didNavigateToNTPInWebState:newWebState]; + } + [self.consumer webStateSelected]; } } @@ -208,16 +228,10 @@ // Remove the helper because it isn't needed anymore. NewTabAnimationTabHelper::RemoveFromWebState(newWebState); } - // Since we share the NTP coordinator across web states, the feed type could - // be different from default, so we reset it. NewTabPageTabHelper* NTPHelper = NewTabPageTabHelper::FromWebState(newWebState); - if (NTPHelper && NTPHelper->IsActive()) { + if (NTPHelper->IsActive()) { [_ntpCoordinator start]; - FeedType defaultFeedType = NTPHelper->DefaultFeedType(); - if (_ntpCoordinator.selectedFeed != defaultFeedType) { - [_ntpCoordinator selectFeedType:defaultFeedType]; - } } BOOL inBackground = (NTPHelper && NTPHelper->ShouldShowStartSurface()) || !animated;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index 897017c9..2bb7c34 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -1104,7 +1104,9 @@ // Test that signing in and signing out results in the NTP scrolled to the top // and not in some unexpected layout state. -- (void)testSignInSignOutScrolledToTop { +// TODO(crbug.com/1433014): Non-stop animation on discover feed after signing +// out. +- (void)FLAKY_testSignInSignOutScrolledToTop { [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPLogo()] assertWithMatcher:grey_sufficientlyVisible()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
diff --git a/ios/chrome/browser/ui/integration_tests/BUILD.gn b/ios/chrome/browser/ui/integration_tests/BUILD.gn index b5d21e14..5cc26030 100644 --- a/ios/chrome/browser/ui/integration_tests/BUILD.gn +++ b/ios/chrome/browser/ui/integration_tests/BUILD.gn
@@ -10,6 +10,7 @@ testonly = true sources = [ "pdf_egtest.mm" ] deps = [ + "//ios/chrome/browser/snapshots:features", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//net:test_support",
diff --git a/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm b/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm index aac16e8..3ef28a91 100644 --- a/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm +++ b/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm
@@ -6,6 +6,9 @@ #import <XCTest/XCTest.h> #import "base/test/ios/wait_util.h" +#import "base/test/scoped_feature_list.h" +#import "ios/chrome/browser/snapshots/features.h" +#import "ios/chrome/test/earl_grey/chrome_actions.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" @@ -17,13 +20,24 @@ #error "This file requires ARC support." #endif +using chrome_test_util::RegularTabGrid; +using chrome_test_util::ScrollToTop; +using chrome_test_util::TabGridCellAtIndex; + const char kPDFPath[] = "/complex_document.pdf"; +const char kGreenPDFPath[] = "/green.pdf"; @interface PDFTestCase : ChromeTestCase @end @implementation PDFTestCase +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + config.features_enabled.push_back(kPDFSnapshot); + return config; +} + // Regression test for crbug/981893. Repro steps: open a PDF in a new // tab, switch back and forth betweeen the new tab and the old one by // swiping in the toolbar. The regression is a crash. @@ -106,7 +120,7 @@ - (void)testPDFIntoTabGridAndWait { GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); - // Load a page, then a PDF + // Load a page, then a PDF. [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; [ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)]; @@ -118,4 +132,95 @@ [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()] performAction:grey_tap()]; } + +// Tests the center color of the grid tab showing a PDF. (physical device only) +- (void)testCenterColorOfPDFTabGrid { +#if TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_SKIPPED(@"The API to take a snapshot is not working correctly " + @"and it becomes black on simulator."); +#endif + + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + + // Load a page, then a PDF. + [ChromeEarlGrey loadURL:self.testServer->GetURL(kGreenPDFPath)]; + + // Open more than 6 pages to scroll down/up in a tab grid. + for (int i = 0; i < 10; i++) { + [ChromeEarlGreyUI openNewTab]; + [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; + } + + // Open a tab grid and then scroll up to make a tab grid cell recycled and + // re-created. + [ChromeEarlGreyUI openTabGrid]; + [[EarlGrey selectElementWithMatcher:RegularTabGrid()] + performAction:ScrollToTop()]; + + // Take a snapshot of the tab grid showing a PDF. + EDORemoteVariable<UIImage*>* tabGridSnapshot = + [[EDORemoteVariable alloc] init]; + [[EarlGrey selectElementWithMatcher:TabGridCellAtIndex(0)] + performAction:grey_snapshot(tabGridSnapshot)]; + + // Get a color of the center position in a tab grid. + CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; + [self getCenterColor:tabGridSnapshot.object + red:&red + green:&green + blue:&blue + alpha:&alpha]; + + // The values may not be exactly 0.0 or 1.0 due to the image compression. The + // test allows more flexible values. + GREYAssert( + red < 0.1, + @"A red value of the center color in a tab grid should be close to 0."); + GREYAssert( + green > 0.9, + @"A green value of the center color in a tab grid should be close to 1."); + GREYAssert( + blue < 0.1, + @"A blue value of the center color in a tab grid should be close to 0."); + GREYAssert( + alpha > 0.9, + @"A alpha value of the center color in a tab grid should be close to 1."); +} + +#pragma mark - Helper methods + +- (void)getCenterColor:(UIImage*)image + red:(CGFloat*)red + green:(CGFloat*)green + blue:(CGFloat*)blue + alpha:(CGFloat*)alpha { + CGImageRef imageRef = [image CGImage]; + + NSUInteger width = CGImageGetWidth(imageRef); + NSUInteger height = CGImageGetHeight(imageRef); + NSUInteger x = width / 2; + NSUInteger y = height / 2; + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + unsigned char* data = + (unsigned char*)calloc(height * width * 4, sizeof(unsigned char)); + NSUInteger bytesPerPixel = 4; + NSUInteger bytesPerRow = bytesPerPixel * width; + NSUInteger bitsPerComponent = 8; + CGContextRef context = + CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, + colorSpace, kCGImageAlphaPremultipliedLast); + CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); + + NSUInteger index = (bytesPerRow * y) + x * bytesPerPixel; + *red = ((CGFloat)data[index]) / 255.0f; + *green = ((CGFloat)data[index + 1]) / 255.0f; + *blue = ((CGFloat)data[index + 2]) / 255.0f; + *alpha = ((CGFloat)data[index + 3]) / 255.0f; + + CGColorSpaceRelease(colorSpace); + CGContextRelease(context); + free(data); +} + @end
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index b3cffe4d..0df1d23e 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -154,12 +154,17 @@ "new_tab_page_retention_field_trial.cc", "new_tab_page_retention_field_trial.h", "new_tab_page_retention_field_trial_constants.h", + "synced_segments_field_trial.cc", + "synced_segments_field_trial.h", + "synced_segments_field_trial_constants.cc", + "synced_segments_field_trial_constants.h", ] public_deps = [ "//base", "//components/variations", ] deps = [ + "//components/history/core/browser", "//components/ntp_tiles", "//components/prefs", "//components/version_info:version_info",
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h index 8b527ba4..c4d20b7 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
@@ -11,6 +11,10 @@ #import "ios/chrome/browser/ui/ntp/logo_animation_controller.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_configuring.h" +namespace web { +class WebState; +} + @class BubblePresenter; @protocol NewTabPageComponentFactoryProtocol; @protocol NewTabPageControllerDelegate; @@ -73,7 +77,7 @@ - (void)reload; // Called when the user navigates to the NTP. -- (void)didNavigateToNTP; +- (void)didNavigateToNTPInWebState:(web::WebState*)webState; // Called when the user navigates away from the NTP. - (void)didNavigateAwayFromNTP;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 03cbe73..53dfb08 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -112,16 +112,6 @@ #error "This file requires ARC support." #endif -namespace { -bool IsNTPActiveForWebState(web::WebState* web_state) { - if (!web_state) { - return false; - } - NewTabPageTabHelper* helper = NewTabPageTabHelper::FromWebState(web_state); - return helper && helper->IsActive(); -} -} // namespace - @interface NewTabPageCoordinator () <AppStateObserver, BooleanObserver, ContentSuggestionsHeaderCommands, @@ -151,9 +141,6 @@ // Observes changes in the DiscoverFeed. std::unique_ptr<DiscoverFeedObserverBridge> _discoverFeedObserverBridge; - - // Bridges C++ WebStateListObserver methods to this NewTabPageCoordinator. - std::unique_ptr<WebStateListObserverBridge> _webStateListObserver; } // Coordinator for the ContentSuggestions. @@ -181,13 +168,6 @@ // Redefined to readwrite. @property(nonatomic, assign, readwrite) BOOL visible; -// Whether the view is new tab view is currently presented (possibly in -// background). Used to report NTP usage metrics. -@property(nonatomic, assign) BOOL viewPresented; - -// Wheter the scene is currently in foreground. -@property(nonatomic, assign) BOOL sceneInForeground; - // The ViewController displayed by this Coordinator. This is the returned // ViewController and will contain the `containedViewController` (Which can // change depending on Feed visibility). @@ -302,16 +282,11 @@ DCHECK(self.webState); DCHECK(NewTabPageTabHelper::FromWebState(self.webState)->IsActive()); - // Start observing WebStateList changes. - _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self); - self.browser->GetWebStateList()->AddObserver(_webStateListObserver.get()); - // Start observing SceneState changes. SceneState* sceneState = SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState(); [sceneState addObserver:self]; - self.sceneInForeground = - sceneState.activationLevel >= SceneActivationLevelForegroundInactive; + // Configures incognito NTP if user is in incognito mode. if (self.browser->GetBrowserState()->IsOffTheRecord()) { DCHECK(!self.incognitoViewController); @@ -320,16 +295,15 @@ self.incognitoViewController = [[IncognitoViewController alloc] initWithUrlLoader:URLLoader]; self.started = YES; - [self NTPDidChangeVisibility:YES]; return; } - self.selectedFeed = - NewTabPageTabHelper::FromWebState(self.webState)->GetNextNTPFeedType(); - // NOTE: anything that executes below WILL NOT execute for OffTheRecord // browsers! + self.selectedFeed = + NewTabPageTabHelper::FromWebState(self.webState)->GetNextNTPFeedType(); + [self initializeServices]; [self initializeNTPComponents]; [self startObservers]; @@ -356,15 +330,13 @@ [self configureNTPViewController]; self.started = YES; - [self NTPDidChangeVisibility:YES]; } - (void)stop { - if (!self.started) + if (!self.started) { return; + } - self.browser->GetWebStateList()->RemoveObserver(_webStateListObserver.get()); - _webStateListObserver.reset(); _webState = nullptr; SceneState* sceneState = @@ -374,8 +346,6 @@ if (self.browser->GetBrowserState()->IsOffTheRecord()) { self.incognitoViewController = nil; self.started = NO; - self.viewPresented = NO; - [self updateVisible]; return; } @@ -384,9 +354,6 @@ [sceneState.appState removeObserver:self]; - self.viewPresented = NO; - [self updateVisible]; - [self.feedManagementCoordinator stop]; self.feedManagementCoordinator = nil; [self.contentSuggestionsCoordinator stop]; @@ -419,6 +386,7 @@ self.alertCoordinator = nil; self.authService = nil; self.templateURLService = nil; + self.prefService = nil; [self.NTPMediator shutdown]; self.NTPMediator = nil; @@ -499,7 +467,7 @@ - (void)locationBarDidResignFirstResponder { // Do not trigger defocus animation if the user is already navigating away // from the NTP. - if (self.viewPresented) { + if (self.visible) { [self.NTPViewController omniboxDidResignFirstResponder]; } } @@ -535,17 +503,15 @@ } } -- (void)didNavigateToNTP { - if (self.started) { - self.webState = self.browser->GetWebStateList()->GetActiveWebState(); - [self NTPDidChangeVisibility:YES]; - } +- (void)didNavigateToNTPInWebState:(web::WebState*)webState { + CHECK(self.started); + self.webState = webState; + [self updateNTPIsVisible:YES]; } - (void)didNavigateAwayFromNTP { - [self NTPDidChangeVisibility:NO]; + [self updateNTPIsVisible:NO]; self.webState = nullptr; - [self stopIfNeeded]; } #pragma mark - Setters @@ -1373,40 +1339,16 @@ - (void)sceneState:(SceneState*)sceneState transitionedToActivationLevel:(SceneActivationLevel)level { - self.sceneInForeground = level >= SceneActivationLevelForegroundInactive; - [self updateVisible]; -} - -#pragma mark - WebStateListObserving methods - -- (void)webStateList:(WebStateList*)webStateList - didChangeActiveWebState:(web::WebState*)newWebState - oldWebState:(web::WebState*)oldWebState - atIndex:(int)atIndex - reason:(ActiveWebStateChangeReason)reason { - [self didChangeActiveWebState:newWebState]; + if (self.webState && !self.visible && + level >= SceneActivationLevelForegroundInactive) { + [self updateNTPIsVisible:YES]; + } else if (self.visible && level < SceneActivationLevelForegroundInactive) { + [self updateNTPIsVisible:NO]; + } } #pragma mark - Private -// Handles a change in the active WebState. -- (void)didChangeActiveWebState:(web::WebState*)newWebState { - if (self.webState == newWebState) { - return; - } - - if (IsNTPActiveForWebState(self.webState)) { - [self NTPDidChangeVisibility:NO]; - } - - bool active = IsNTPActiveForWebState(newWebState); - self.webState = active ? newWebState : nullptr; - - if (active) { - [self NTPDidChangeVisibility:YES]; - } -} - // Updates the feed visibility or content based on the supervision state // of the account defined in `value`. - (void)updateFeedWithIsSupervisedUser:(BOOL)value { @@ -1436,42 +1378,6 @@ } } -// Updates the visible property based on viewPresented and sceneInForeground -// properties. -// Sends metrics when NTP becomes invisible. -- (void)updateVisible { - BOOL visible = self.viewPresented && self.sceneInForeground; - if (visible == self.visible) { - return; - } - self.visible = visible; - if (self.browser->GetBrowserState()->IsOffTheRecord()) { - // Do not report metrics on incognito NTP. - return; - } - if (visible) { - self.didAppearTime = base::TimeTicks::Now(); - if ([self isFeedHeaderVisible]) { - if ([self.feedExpandedPref value]) { - [self.NTPMetricsRecorder - recordNTPImpression:IOSNTPImpressionType::kFeedVisible]; - } else { - [self.NTPMetricsRecorder - recordNTPImpression:IOSNTPImpressionType::kFeedCollapsed]; - } - } else { - [self.NTPMetricsRecorder - recordNTPImpression:IOSNTPImpressionType::kFeedDisabled]; - } - } else { - if (!self.didAppearTime.is_null()) { - [self.NTPMetricsRecorder - recordTimeSpentInNTP:base::TimeTicks::Now() - self.didAppearTime]; - self.didAppearTime = base::TimeTicks(); - } - } -} - // Updates the NTP to take into account a new feed, or a change in feed // visibility. - (void)updateNTPForFeed { @@ -1685,9 +1591,11 @@ // Called when the NTP changes visibility, either when the user navigates to // or away from the NTP, or when the active WebState changes. -- (void)NTPDidChangeVisibility:(BOOL)visible { - DCHECK(self.started); - DCHECK(self.webState); +- (void)updateNTPIsVisible:(BOOL)visible { + CHECK(visible != self.visible); + CHECK(self.webState); + + self.visible = visible; if (!self.browser->GetBrowserState()->IsOffTheRecord()) { [self updateStartForVisibilityChange:visible]; @@ -1711,6 +1619,32 @@ self.feedMetricsRecorder.feedControlDelegate = self; self.feedMetricsRecorder.followDelegate = self; } + self.didAppearTime = base::TimeTicks::Now(); + if ([self isFeedHeaderVisible]) { + if ([self.feedExpandedPref value]) { + [self.NTPMetricsRecorder + recordNTPImpression:IOSNTPImpressionType::kFeedVisible]; + } else { + [self.NTPMetricsRecorder + recordNTPImpression:IOSNTPImpressionType::kFeedCollapsed]; + } + } else { + [self.NTPMetricsRecorder + recordNTPImpression:IOSNTPImpressionType::kFeedDisabled]; + } + } else { + // Unfocus omnibox, to prevent it from lingering when it should be + // dismissed (for example, when navigating away or when changing feed + // visibility). Do this after the MVC classes are deallocated so no reset + // animations are fired in response to this cancel. + id<OmniboxCommands> omniboxCommandHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), OmniboxCommands); + [omniboxCommandHandler cancelOmniboxEdit]; + if (!self.didAppearTime.is_null()) { + [self.NTPMetricsRecorder + recordTimeSpentInNTP:base::TimeTicks::Now() - self.didAppearTime]; + self.didAppearTime = base::TimeTicks(); + } } // Check if feed is visible before reporting NTP visibility as the feed // needs to be visible in order to use for metrics. @@ -1720,14 +1654,11 @@ } } - self.viewPresented = visible; - [self updateVisible]; - if (!self.browser->GetBrowserState()->IsOffTheRecord() && !visible) { // Unfocus omnibox, to prevent it from lingering when it should be // dismissed (for example, when navigating away or when changing feed // visibility). - // Do this after updating `viewPresented` to prevent defocus animation from + // Do this after updating `visible` to prevent defocus animation from // happening when already navigating away from NTP. [self cancelOmniboxEdit]; }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm index a4ae15dc..6379147 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -241,8 +241,8 @@ ContentSuggestionsCoordinator* mockContentSuggestionsCoordinator = coordinator_mock; - // Test `-start` sets `isStartShowing` to true if NTPTabHelper's - // `-ShouldShowStartSurface` is true. + // Set next NTP as start surface. Test that starting the NTP and navigating to + // it configures the start surface. OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock); OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any] browser:browser_.get()]) @@ -250,12 +250,12 @@ NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]); [coordinator_ start]; - EXPECT_OCMOCK_VERIFY(coordinator_mock); - [coordinator_ stop]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; - // Test `-didNavigateToNTP` configures the NTP for Start. `-didNavigateToNTP` - // should only be called if the NTPCoordinator is still started (e.g. another - // tab has the NTP open). + // Test opening a Start surface with another NTP tab opened in the background + // (e.g. the NTP coordinator is already started). + [coordinator_ didNavigateAwayFromNTP]; + [coordinator_ stop]; OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock); OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any] browser:browser_.get()]) @@ -263,10 +263,11 @@ [coordinator_ start]; NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]); - [coordinator_ didNavigateToNTP]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; EXPECT_OCMOCK_VERIFY(coordinator_mock); - // Test `-didNavigateAwayFromNTP` when currently showing Start resets the - // configuration. + + // Test `-didNavigateAwayFromNTPWithinWebState` when currently showing Start + // resets the configuration. [coordinator_ didNavigateAwayFromNTP]; EXPECT_FALSE( NewTabPageTabHelper::FromWebState(web_state_)->ShouldShowStartSurface()); @@ -274,18 +275,21 @@ // Test `-didChangeActiveWebState:` updates NTP Start state to false if it // began as true. - NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); + // NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock); OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any] browser:browser_.get()]) .andReturn(mockContentSuggestionsCoordinator); OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]); + NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); [coordinator_ start]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; EXPECT_OCMOCK_VERIFY(coordinator_mock); // Save reference before `web_state_` is set to new active WebState. web::WebState* start_web_state = web_state_; // Simulate didChangeActiveWebState: callback. InsertWebState(CreateWebStateWithURL(GURL("chrome://version"))); + [coordinator_ didNavigateAwayFromNTP]; // Moved away from Start surface to a different WebState, Start config for // original WebState's TabHelper should be NO. EXPECT_FALSE(NewTabPageTabHelper::FromWebState(start_web_state) @@ -298,6 +302,7 @@ [[coordinator_mock reject] configureStartSurfaceIfNeeded]; SetNTPAsCurrentURL(); [coordinator_ start]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; EXPECT_OCMOCK_VERIFY(coordinator_mock); [coordinator_ stop]; } @@ -312,6 +317,7 @@ // SetShowStartSurface. NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); [coordinator_ start]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; histogram_tester_->ExpectUniqueSample( "IOS.ContentSuggestions.ActionOnStartSurface", IOSContentSuggestionsActionType::kFakebox, 0); @@ -326,6 +332,7 @@ static_cast<web::FakeWebState*>(web_state_) ->OnNavigationStarted(&navigation_context); [coordinator_ didNavigateAwayFromNTP]; + [coordinator_ stopIfNeeded]; ASSERT_FALSE(coordinator_.started); SetNTPAsCurrentURL(); [coordinator_ start]; @@ -356,6 +363,7 @@ SetupCommandHandlerMocks(); NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); [coordinator_ start]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; histogram_tester_->ExpectUniqueSample( "IOS.ContentSuggestions.ActionOnStartSurface", @@ -390,67 +398,75 @@ [coordinator_ stop]; } -// Test -didNavigateToNTP to simulate the user navigating back to the NTP, and -// -didNavigateAwayFromNTP to simulate the user navigating away from the NTP. -TEST_F(NewTabPageCoordinatorTest, DidNavigate) { - CreateCoordinator(/*off_the_record=*/false); - SetupCommandHandlerMocks(); - [coordinator_ start]; - [coordinator_ sceneState:nil - transitionedToActivationLevel:SceneActivationLevelForegroundInactive]; - EXPECT_TRUE(coordinator_.visible); - - // Create second NTP since `-didNavigateToNTP` should only be called instead - // of `-start` when there is another tab showing the NTP. - InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab"))); - // Simulate navigating away from the NTP. - web::FakeNavigationContext navigation_context; - navigation_context.SetUrl(GURL("chrome://version")); - static_cast<web::FakeWebState*>(web_state_) - ->OnNavigationStarted(&navigation_context); - [coordinator_ didNavigateAwayFromNTP]; - ASSERT_TRUE(coordinator_.started); - EXPECT_EQ(coordinator_.webState, nullptr); - EXPECT_FALSE(coordinator_.visible); - - // Simulate navigating back to the NTP. - [coordinator_ didNavigateToNTP]; - EXPECT_EQ(coordinator_.webState, web_state_); - EXPECT_TRUE(coordinator_.visible); - - // Remove one of the tabs so that NTPCoordinator will actually stop. - browser_->GetWebStateList()->CloseWebStateAt( - /*index=*/0, /* close_flags= */ 0); - web_state_ = browser_->GetWebStateList()->GetActiveWebState(); - [coordinator_ stopIfNeeded]; - ASSERT_FALSE(coordinator_.started); -} - -// Test that NTPCoordinator's DidChangeActiveWebState will change the -// `webState` property as well as the NTP's visibility appropriately. -TEST_F(NewTabPageCoordinatorTest, DidChangeActiveWebState) { +TEST_F(NewTabPageCoordinatorTest, DidNavigateWithinWebState) { // Test normal and incognito modes. for (bool off_the_record : {false, true}) { CreateCoordinator(off_the_record); SetupCommandHandlerMocks(); + + // Starting the NTP coordinator should not make it visible. [coordinator_ start]; - [coordinator_ sceneState:nil - transitionedToActivationLevel:SceneActivationLevelForegroundInactive]; + EXPECT_TRUE(coordinator_.started); + EXPECT_FALSE(coordinator_.visible); + + // Navigate to NTP within the web state and check that NTP is visible. + [coordinator_ didNavigateToNTPInWebState:web_state_]; + EXPECT_TRUE(coordinator_.started); + EXPECT_TRUE(coordinator_.visible); + + // Simulate navigating away from the NTP. + web::FakeNavigationContext navigation_context; + navigation_context.SetUrl(GURL("chrome://version")); + static_cast<web::FakeWebState*>(web_state_) + ->OnNavigationStarted(&navigation_context); + [coordinator_ didNavigateAwayFromNTP]; + + // Remove one of the tabs so that NTPCoordinator will actually stop. + browser_->GetWebStateList()->CloseWebStateAt( + /*index=*/0, /* close_flags= */ 0); + [coordinator_ stopIfNeeded]; + EXPECT_FALSE(coordinator_.started); + EXPECT_FALSE(coordinator_.visible); + } +} + +TEST_F(NewTabPageCoordinatorTest, DidNavigateBetweenWebStates) { + // Test normal and incognito modes. + for (bool off_the_record : {false, true}) { + CreateCoordinator(off_the_record); + SetupCommandHandlerMocks(); + + // Starting the NTP coordinator should not make it visible. + [coordinator_ start]; + EXPECT_TRUE(coordinator_.started); + EXPECT_FALSE(coordinator_.visible); + + // Open an NTP in a new web state. + InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab"))); + [coordinator_ didNavigateToNTPInWebState:web_state_]; + EXPECT_TRUE(coordinator_.started); EXPECT_TRUE(coordinator_.visible); // Insert a non-NTP WebState. InsertWebState(CreateWebStateWithURL(GURL("chrome://version"))); - EXPECT_EQ(coordinator_.webState, nullptr); + [coordinator_ didNavigateAwayFromNTP]; + EXPECT_TRUE(coordinator_.started); EXPECT_FALSE(coordinator_.visible); - // Insert an NTP webstate. - InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab"))); - EXPECT_EQ(coordinator_.webState, web_state_); + // Close non-NTP web state to get back to NTP web state. + browser_->GetWebStateList()->CloseWebStateAt( + /*index=*/1, /* close_flags= */ 0); + [coordinator_ didNavigateToNTPInWebState:web_state_]; + EXPECT_TRUE(coordinator_.started); EXPECT_TRUE(coordinator_.visible); - [coordinator_ stop]; - EXPECT_EQ(coordinator_.webState, nullptr); - coordinator_ = nil; + // Close all web states. + [coordinator_ didNavigateAwayFromNTP]; + browser_->GetWebStateList()->CloseAllWebStates( + WebStateList::CLOSE_NO_FLAGS); + [coordinator_ stopIfNeeded]; + EXPECT_FALSE(coordinator_.visible); + EXPECT_FALSE(coordinator_.started); } } @@ -460,6 +476,7 @@ CreateCoordinator(/*off_the_record=*/false); SetupCommandHandlerMocks(); [coordinator_ start]; + [coordinator_ didNavigateToNTPInWebState:web_state_]; ExpectMethodToProxyToVC(@selector(stopScrolling), @selector(stopScrolling)); ExpectMethodToProxyToVC(@selector(isScrolledToTop),
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc new file mode 100644 index 0000000..9617faaf --- /dev/null +++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc
@@ -0,0 +1,133 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h" + +#include "base/feature_list.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" +#include "components/history/core/browser/features.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/version_info/version_info.h" +#include "ios/chrome/browser/first_run/first_run.h" +#include "ios/chrome/browser/ui/first_run/ios_first_run_field_trials.h" +#include "ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h" +#include "ios/chrome/common/channel_info.h" + +namespace { + +// The placeholder trial version that is stored for a client who has not been +// enrolled in the experiment. +const int kPlaceholderTrialVersion = -1; + +// Store local state preference with whether the client has participated in +// `kIOSSyncedSegmentsFieldTrialName` experiment or not. +const char kTrialPrefName[] = "synced_segments.trial_version"; + +// The current trial version of +// `kIOSSyncedSegmentsFieldTrialName`; should be updated when +// the experiment is modified. +const int kCurrentTrialVersion = 1; + +// Returns a map of the group weights for each arm. +std::map<variations::VariationID, int> GetGroupWeights() { + std::map<variations::VariationID, int> weight_by_id = { + {synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID, 0}, + {synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID, 0}}; + + return weight_by_id; +} + +} // namespace + +namespace synced_segments_field_trial { + +// Creates the trial config, initializes the trial that puts clients into +// different groups, and returns the version number of the current trial. +void CreateSyncedSegmentsTrial( + std::map<variations::VariationID, int> weight_by_id, + const base::FieldTrial::EntropyProvider& low_entropy_provider, + base::FeatureList* feature_list) { + FirstRunFieldTrialConfig config( + synced_segments_field_trial_constants::kIOSSyncedSegmentsFieldTrialName); + + config.AddGroup( + synced_segments_field_trial_constants::kIOSSyncedSegmentsControlGroup, + synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID, + weight_by_id + [synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID]); + + config.AddGroup( + synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledGroup, + synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID, + weight_by_id + [synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID]); + + scoped_refptr<base::FieldTrial> trial = config.CreateOneTimeRandomizedTrial( + synced_segments_field_trial_constants::kIOSSyncedSegmentsControlGroup, + low_entropy_provider); + + // Finalize the group choice and activates the trial - similar to a variation + // config that's marked with `starts_active` true. This is required for + // studies that register variation ids, so they don't reveal extra information + // beyond the low-entropy source. + const std::string& group_name = trial->group_name(); + + if (group_name == + synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledGroup) { + feature_list->RegisterFieldTrialOverride( + history::kSyncSegmentsData.name, + base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); + } else if (group_name == synced_segments_field_trial_constants:: + kIOSSyncedSegmentsControlGroup) { + feature_list->RegisterFieldTrialOverride( + history::kSyncSegmentsData.name, + base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get()); + } +} + +void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + registry->RegisterIntegerPref(kTrialPrefName, kPlaceholderTrialVersion); +} + +void Create(const base::FieldTrial::EntropyProvider& low_entropy_provider, + base::FeatureList* feature_list, + PrefService* local_state) { + // Don't create the trial if the feature is overridden to avoid having + // multiple registered trials for the same feature. + if (feature_list->IsFeatureOverridden(synced_segments_field_trial_constants:: + kIOSSyncedSegmentsFieldTrialName)) { + return; + } + + // If the client is already an existing client by the time this experiment + // began running, don't register (e.g. the client is not in a First Run + // experience and was never grouped client-side into this study when it went + // through First Run). If the user is enrolled in a previous version of the + // same experiment, exclude them out of the current version. + if (!FirstRun::IsChromeFirstRun() && + local_state->GetInteger(kTrialPrefName) != kCurrentTrialVersion) { + return; + } + + // Enroll first run clients in the experiment. + // If the client is enrolled in the current version of the experiment, + // register the trial to keep them in the experiment; they will be placed + // in the same group because `low_entropy_provider` is persisted across + // launches. + CreateSyncedSegmentsTrial(GetGroupWeights(), low_entropy_provider, + feature_list); + + local_state->SetInteger(kTrialPrefName, kCurrentTrialVersion); +} + +void CreateSyncedSegmentsTrialForTesting( + std::map<variations::VariationID, int> weights_by_id, + const base::FieldTrial::EntropyProvider& low_entropy_provider, + base::FeatureList* feature_list) { + CreateSyncedSegmentsTrial(weights_by_id, low_entropy_provider, feature_list); +} + +} // namespace synced_segments_field_trial
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h new file mode 100644 index 0000000..eeb0794 --- /dev/null +++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h
@@ -0,0 +1,35 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_ +#define IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_ + +#include "base/metrics/field_trial.h" +#include "components/variations/variations_associated_data.h" + +class PrefService; +class PrefRegistrySimple; + +namespace synced_segments_field_trial { + +// Creates a field trial to control the synced segments experiment. +// +// The trial group chosen on first run is persisted to local state prefs. +void Create(const base::FieldTrial::EntropyProvider& low_entropy_provider, + base::FeatureList* feature_list, + PrefService* local_state); + +// Registers the local state pref used to manage grouping for this field trial. +void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + +// Exposes CreateSyncedSegmentsTrialForTesting() for testing FieldTrial +// set-up. +void CreateSyncedSegmentsTrialForTesting( + std::map<variations::VariationID, int> weights_by_id, + const base::FieldTrial::EntropyProvider& low_entropy_provider, + base::FeatureList* feature_list); + +} // namespace synced_segments_field_trial + +#endif // IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc new file mode 100644 index 0000000..2540319 --- /dev/null +++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc
@@ -0,0 +1,20 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h" + +namespace synced_segments_field_trial_constants { + +const char kIOSSyncedSegmentsFieldTrialName[] = "IOSSyncedSegments"; + +const variations::VariationID kIOSSyncedSegmentsEnabledID = 4976469; +const variations::VariationID kIOSSyncedSegmentsControlID = 4976470; + +extern const char kIOSSyncedSegmentsEnabledGroup[] = + "IOSSyncedSegmentsEnabled-V1"; +extern const char kIOSSyncedSegmentsControlGroup[] = + "IOSSyncedSegmentsControl-V1"; +extern const char kIOSSyncedSegmentsDefaultGroup[] = "Default"; + +} // namespace synced_segments_field_trial_constants
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h new file mode 100644 index 0000000..3b8a3dd --- /dev/null +++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h
@@ -0,0 +1,27 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_ + +#include "components/variations/variations_associated_data.h" + +namespace synced_segments_field_trial_constants { + +// Name of the field trial to configure the synced segments experiment +// for most visited tiles. +extern const char kIOSSyncedSegmentsFieldTrialName[]; + +// Variation IDs for the synced segments experiment arms. +extern const variations::VariationID kIOSSyncedSegmentsEnabledID; +extern const variations::VariationID kIOSSyncedSegmentsControlID; + +// Group names for the synced segments experiment. +extern const char kIOSSyncedSegmentsEnabledGroup[]; +extern const char kIOSSyncedSegmentsControlGroup[]; +extern const char kIOSSyncedSegmentsDefaultGroup[]; + +} // namespace synced_segments_field_trial_constants + +#endif // IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_
diff --git a/ios/chrome/browser/variations/BUILD.gn b/ios/chrome/browser/variations/BUILD.gn index 22e60e43..09030ed0 100644 --- a/ios/chrome/browser/variations/BUILD.gn +++ b/ios/chrome/browser/variations/BUILD.gn
@@ -25,10 +25,12 @@ source_set("fetcher") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "ios_chrome_variations_seed_fetcher+testing.h", "ios_chrome_variations_seed_fetcher.h", "ios_chrome_variations_seed_fetcher.mm", ] deps = [ + ":constants", ":store", ":store_private", "//base", @@ -58,7 +60,11 @@ ":fetcher", ":store", ] - sources = [ "ios_chrome_variations_seed_store+private.h" ] + sources = [ "ios_chrome_variations_seed_store+fetcher.h" ] +} + +source_set("constants") { + sources = [ "constants.h" ] } generate_ui_string_overrider("ios_chrome_ui_string_overrider_factory") { @@ -151,11 +157,9 @@ source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true - sources = [ - "ios_chrome_variations_seed_fetcher+testing.h", - "ios_chrome_variations_seed_fetcher_unittest.mm", - ] + sources = [ "ios_chrome_variations_seed_fetcher_unittest.mm" ] deps = [ + ":constants", ":fetcher", ":store", "//base",
diff --git a/ios/chrome/browser/variations/constants.h b/ios/chrome/browser/variations/constants.h new file mode 100644 index 0000000..21fbc72 --- /dev/null +++ b/ios/chrome/browser/variations/constants.h
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_ + +// Enum for the seed fetch result histogram. Must stay in sync with +// `VariationsSeedFetchResult` from enums.xml. +enum class IOSSeedFetchException : int { + // Default value. DO NOT LOG. + kNotApplicable = 0, + // HTTPS request times out. + kHTTPSRequestTimeout = -2, + // Variations URL error. + kHTTPSRequestBadUrl = -3, + // The "IM" header returned from the variations server does not exist or + // contains invalid value. + kInvalidIMHeader = -5, +}; + +#endif // IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h index 3035db9f..b165861 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h
@@ -7,10 +7,6 @@ #import <memory> -namespace base { -class Time; -} // namespace base - namespace variations { struct SeedResponse; } // namespace variations @@ -19,13 +15,9 @@ // IOSChromeVariationsSeedFetcher to be tested. @interface IOSChromeVariationsSeedFetcher (Testing) -@property(nonatomic, readonly) NSURL* variationsUrl; +- (void)doActualFetch; -@property(nonatomic, assign) base::Time startTimeOfOngoingSeedRequest; - -- (void)applySwitchesFromArguments:(NSArray<NSString*>*)arguments; - -- (void)onSeedRequestCompletedWithData:(NSData*)data +- (void)seedRequestDidCompleteWithData:(NSData*)data response:(NSHTTPURLResponse*)httpResponse error:(NSError*)error;
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h index 39dbc5d..6202937 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h
@@ -7,27 +7,14 @@ #import <Foundation/Foundation.h> -// Enum for the seed fetch result histogram. Must stay in sync with -// `VariationsSeedFetchResult` from enums.xml. -enum class IOSSeedFetchException : int { - // Default value. DO NOT LOG. - kNotApplicable = 0, - // HTTPS request times out. - kHTTPSRequestTimeout = -2, - // Variations URL error. - kHTTPSRequestBadUrl = -3, - // The "IM" header returned from the variations server does not exist or - // contains invalid value. - kInvalidIMHeader = -5, -}; - // Protocol for variations seed fetcher that reacts to variations seed fetch // stages. @protocol IOSChromeVariationsSeedFetcherDelegate -// Informs the delegate that the initial seed fetch has successfully completed -// or failed. -- (void)didFetchSeedSuccess:(BOOL)succeeded; +// Informs the delegate that the initial seed fetch has completed. +// If the value of the `success` parameter is YES, the seed fetch is successful; +// if NO, the fetch has failed. +- (void)variationsSeedFetcherDidCompleteFetchWithSuccess:(BOOL)success; @end @@ -35,10 +22,21 @@ // components are initialized. @interface IOSChromeVariationsSeedFetcher : NSObject -// Delegate object that observes the status of seed fetching. +// Delegate object that would be informed when the seed fetch completes. @property(nonatomic, weak) id<IOSChromeVariationsSeedFetcherDelegate> delegate; -// Starts fetching the initial seed from the variations server. +// Initializes the seed fetcher using `arguments` as variation switches, and +// apply them to the seed manager. +// +// Note: If the user calls `init`, the fetcher +// would be initialized with command line arguments. +- (instancetype)initWithArguments:(NSArray<NSString*>*)arguments + NS_DESIGNATED_INITIALIZER; + +// Starts fetching the initial seed from the variations server. The `delegate` +// property would be informed when the fetch completes. If the fetch is +// successful, the acquired seed would be stored in +// IOSChromeVariationsSeedStore. // // Note: the caller is responsible for making sure that a seed fetcher object is // only be initiated when there is no valid variations seed available in local
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm index ab78bb8e..5f537ab 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm
@@ -3,6 +3,7 @@ // found in the LICENSE file. #import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h" +#import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h" #import "base/metrics/histogram_functions.h" #import "base/notreached.h" @@ -14,11 +15,12 @@ #import "components/variations/variations_switches.h" #import "components/variations/variations_url_constants.h" #import "components/version_info/version_info.h" +#import "ios/chrome/browser/variations/constants.h" #import "ios/chrome/browser/variations/ios_chrome_variations_seed_store.h" #import "ios/chrome/common/channel_info.h" #import "net/http/http_status_code.h" -#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h" +#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -33,39 +35,38 @@ "IOS.Variations.FirstRun.SeedFetchResult"; const char kSeedFetchTimeHistogram[] = "IOS.Variations.FirstRun.SeedFetchTime"; -// Whether a current request for variations seed is being made; this variable -// exists that only one instance of the manager updates the global seed at one -// time. +// Whether a current request for variations seed is being made. +// +// This variable exists so that only one instance of the manager updates the +// global seed at one time. It is access in the static serial queue +// "*.first_run_variations_seed_manager" at the start of each task in the queue. +// If the value is NO, it's set to YES and keep executing the task; otherwise, +// it aborts the task to make sure the fetch result won't be overriden. static BOOL g_seed_fetching_in_progress = NO; } // namespace -@interface IOSChromeVariationsSeedFetcher () { - // The variations server domain name. +@implementation IOSChromeVariationsSeedFetcher { + // Whether the current binary should fetch Finch seed for experiment purpose. + // Accessed on the main thread. + BOOL _fetchingEnabled; + + // The variations server domain name. Accessed on the main thread. std::string _variationsDomain; - // The forced channel string retrieved from the command line. + // The forced channel string retrieved from the command line. Accessed on the + // main thread. std::string _forcedChannel; + + // The timestamp when the current seed request starts. This is used for metric + // reporting, and will be reset to null value when the request finishes. + // Accessed in the static serial queue "*.first_run_variations_seed_manager". + base::Time _startTimeOfOngoingSeedRequest; } -// Whether the current binary should fetch Finch seed for experiment purpose. -@property(nonatomic, assign) BOOL fetchingEnabled; - -// The URL of the variations server, including query parameters that identifies -// the request initiator. -@property(nonatomic, readonly) NSURL* variationsUrl; - -// The timestamp when the current seed request starts. This is used for metric -// reporting, and will be reset to null value when the request finishes. -@property(nonatomic, assign) base::Time startTimeOfOngoingSeedRequest; - -@end - -@implementation IOSChromeVariationsSeedFetcher - #pragma mark - Public -- (instancetype)init { +- (instancetype)initWithArguments:(NSArray<NSString*>*)arguments { self = [super init]; if (self) { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -75,12 +76,37 @@ #endif _variationsDomain = variations::kDefaultServerUrl; _forcedChannel = std::string(); - [self applySwitchesFromArguments:[[NSProcessInfo processInfo] arguments]]; + + std::string url_switch = + "--" + std::string(variations::switches::kVariationsServerURL) + "="; + std::string channel_switch = + "--" + std::string(variations::switches::kFakeVariationsChannel) + "="; + for (NSString* a in arguments) { + std::string arg = base::SysNSStringToUTF8(a); + + if (base::StartsWith(arg, url_switch)) { + _variationsDomain = arg.substr(url_switch.size()); + if (!_fetchingEnabled && !_variationsDomain.empty()) { + _fetchingEnabled = YES; + } + } else if (base::StartsWith(arg, channel_switch)) { + _forcedChannel = arg.substr(channel_switch.size()); + } + } } return self; } +- (instancetype)init { + return [self initWithArguments:[[NSProcessInfo processInfo] arguments]]; +} + - (void)startSeedFetch { + if (!_fetchingEnabled) { + // Stops executing if seed fetching is disabled. + [self notifyDelegateSeedFetchResult:NO]; + return; + } // Set up a serial queue to to avoid concurrent read/write to static data. static dispatch_once_t onceToken; static dispatch_queue_t queue = nil; @@ -94,15 +120,23 @@ }); // Adds the task of fetching the seed to the static serial queue, and return - // from `startSeedFetch` immediately. Note that the block will retain `self`. + // from `doActualFetch` immediately. Note that the block will retain `self`. dispatch_async(queue, ^{ - [self startSeedFetchHelper]; + if (g_seed_fetching_in_progress) { + NOTREACHED() << "SeedFetch started while already in progress"; + [self notifyDelegateSeedFetchResult:NO]; + } else { + [self doActualFetch]; + } }); } -#pragma mark - Accessors +#pragma mark - Private -- (NSURL*)variationsUrl { +// The URL of the variations server, including query parameters that identifies +// the request initiator. Accessed in the static serial queue +// "*.first_run_variations_seed_manager". +- (NSURL*)variationsURL { // Setting "osname", "milestone" and "channel" as parameters. Dogfood // experimenting is not supported on Chrome iOS, therefore we do not need the // "restrict" parameter. @@ -119,43 +153,16 @@ URLWithString:base::SysUTF8ToNSString(_variationsDomain + queryString)]; } -#pragma mark - Private - -// Parse custom values from the command line and apply them to the seed manager. -- (void)applySwitchesFromArguments:(NSArray<NSString*>*)arguments { - std::string url_switch = - "--" + std::string(variations::switches::kVariationsServerURL) + "="; - std::string channel_switch = - "--" + std::string(variations::switches::kFakeVariationsChannel) + "="; - for (NSString* a in arguments) { - std::string arg = base::SysNSStringToUTF8(a); - - if (base::StartsWith(arg, url_switch)) { - _variationsDomain = arg.substr(url_switch.size()); - if (!self.fetchingEnabled && !_variationsDomain.empty()) { - self.fetchingEnabled = YES; - } - } else if (base::StartsWith(arg, channel_switch)) { - _forcedChannel = arg.substr(channel_switch.size()); - } - } -} - // Helper method for `startSeedFetch` that initiates an HTTPS request to the -// Finch server in the static serial queue. -- (void)startSeedFetchHelper { - DCHECK(!g_seed_fetching_in_progress) - << "SeedFetch started while already in progress"; - - // Stops executing if seed fetching is disabled. - if (!self.fetchingEnabled) { - [self notifyDelegateSeedFetchResult:NO]; - return; - } - +// Finch server in the static serial queue +// "*.first_run_variations_seed_manager". +// +// Note that if this method is invoked, the seed would be fetched regardless of +// `_fetchingEnabled`, so please use with caution. +- (void)doActualFetch { g_seed_fetching_in_progress = YES; NSMutableURLRequest* request = [NSMutableURLRequest - requestWithURL:self.variationsUrl + requestWithURL:[self variationsURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:kRequestTimeout.InSecondsF()]; // Pass only "gzip" as an accepted format. Do not pass delta compression @@ -166,17 +173,18 @@ dataTaskWithRequest:request completionHandler:^(NSData* data, NSURLResponse* response, NSError* error) { - [self onSeedRequestCompletedWithData:data + [self seedRequestDidCompleteWithData:data response:(NSHTTPURLResponse*)response error:error]; }]; - self.startTimeOfOngoingSeedRequest = base::Time::Now(); + _startTimeOfOngoingSeedRequest = base::Time::Now(); [task resume]; } -// Method that generates the seed using the HTTPS response sent back from the -// Finch server, stores them in the shared seed, and records relevant metrics. -- (void)onSeedRequestCompletedWithData:(NSData*)data +// Completion handler of a URL session task. It generates the seed using the +// HTTPS response sent back from the Finch server, stores them in the shared +// seed, and records relevant metrics. +- (void)seedRequestDidCompleteWithData:(NSData*)data response:(NSHTTPURLResponse*)httpResponse error:(NSError*)error { // Normally net::HTTP_NOT_MODIFIED should be considered as a @@ -185,9 +193,9 @@ BOOL success = error == nil && httpResponse.statusCode == net::HTTP_OK; IOSSeedFetchException exception = IOSSeedFetchException::kNotApplicable; if (success) { - base::UmaHistogramTimes( - kSeedFetchTimeHistogram, - base::Time::Now() - self.startTimeOfOngoingSeedRequest); + DCHECK(!_startTimeOfOngoingSeedRequest.is_null()); + base::UmaHistogramTimes(kSeedFetchTimeHistogram, + base::Time::Now() - _startTimeOfOngoingSeedRequest); std::unique_ptr<variations::SeedResponse> seed = [self seedResponseForHTTPResponse:httpResponse data:data]; if (seed) { @@ -206,7 +214,7 @@ error.code == NSURLErrorCannotFindHost) { exception = IOSSeedFetchException::kHTTPSRequestBadUrl; } - self.startTimeOfOngoingSeedRequest = base::Time(); + _startTimeOfOngoingSeedRequest = base::Time(); g_seed_fetching_in_progress = NO; // Log seed fetch result on UMA and notify delegate. @@ -219,6 +227,7 @@ // Generates and returns the SeedResponse by parsing the HTTP response returned // by the variations server. Returns `nil` if the HTTP response is invalid. +// Invoked in the completion handler of a URL session task. - (std::unique_ptr<variations::SeedResponse>) seedResponseForHTTPResponse:(NSHTTPURLResponse*)httpResponse data:(NSData*)data { @@ -261,7 +270,7 @@ - (void)notifyDelegateSeedFetchResult:(BOOL)result { __weak IOSChromeVariationsSeedFetcher* weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf.delegate didFetchSeedSuccess:result]; + [weakSelf.delegate variationsSeedFetcherDidCompleteFetchWithSuccess:result]; }); }
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm index 7badc13..234c458 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
@@ -13,6 +13,7 @@ #import "components/variations/variations_switches.h" #import "components/variations/variations_url_constants.h" #import "components/version_info/version_info.h" +#import "ios/chrome/browser/variations/constants.h" #import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h" #import "ios/chrome/browser/variations/ios_chrome_variations_seed_store.h" #import "net/http/http_status_code.h" @@ -38,7 +39,7 @@ const char kSeedFetchTimeHistogram[] = "IOS.Variations.FirstRun.SeedFetchTime"; // Fake server url. -const NSString* testServer = @"https://test.finch.server"; +const NSString* test_server = @"https://test.finch.server"; // Type definition of a block that retrieves the value of an HTTP header from a // custom NSDictionary instead of actual NSURLHTTPRequest header. @@ -48,48 +49,17 @@ // valueForHTTPHeaderField:]. MockValueForHTTPHeaderField GetMockMethodWithHeader( NSDictionary<NSString*, NSString*>* headers) { - void (^outputBlock)(NSInvocation*) = ^(NSInvocation* invocation) { + void (^output_block)(NSInvocation*) = ^(NSInvocation* invocation) { __weak NSString* arg; [invocation getArgument:&arg atIndex:2]; __weak NSString* value = headers[arg]; [invocation setReturnValue:&value]; }; - return outputBlock; + return output_block; } } // namespace -// A test implementation of IOSChromeVariationsSeedFetcher to be used by -// test cases. This avoids writing to global variable for the downloaded seed. -// TODO(crbug.com/1379016): Refactor code so that `fetchingEnabled` could be -// overridden in a test init method of `IOSChromeVariationsSeedFetcher`. -@interface TestVariationsSeedFetcher : IOSChromeVariationsSeedFetcher - -// Exposure of parent class property. -@property(nonatomic, assign) BOOL fetchingEnabled; - -// Initializer with designated arguments that substitutes for command line args. -- (instancetype)initWithCommandLineArgsForTesting: - (NSArray<NSString*>*)arguments; - -@end - -@implementation TestVariationsSeedFetcher - -- (instancetype)initWithCommandLineArgsForTesting: - (NSArray<NSString*>*)arguments { - self = [super init]; - if (self) { - self.fetchingEnabled = NO; - // This overrides `self.fetchingEnabled` if variations server URL is set in - // the argument. - [self applySwitchesFromArguments:arguments]; - } - return self; -} - -@end - #pragma mark - Tests // Tests the IOSChromeVariationsSeedFetcher. @@ -102,57 +72,6 @@ } }; -// Tests that the variations url is correct under different inputs in the -// command line. -TEST_F(IOSChromeVariationsSeedFetcherTest, TestVariationsUrl) { - NSString* testChannel = @"fake_channel"; - NSString* testServerArgument = - [NSString stringWithFormat:@"--%@=%@", - base::SysUTF8ToNSString(kVariationsServerURL), - testServer]; - NSString* testChannelArgument = [NSString - stringWithFormat:@"--%@=%@", - base::SysUTF8ToNSString(kFakeVariationsChannel), - testChannel]; - // No arguments; use default value. - TestVariationsSeedFetcher* fetcherWithDefaultArgs = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; - NSString* expectedUrlPrefix = - [NSString stringWithFormat:@"%@?osname=ios&milestone=", - base::SysUTF8ToNSString(kDefaultServerUrl)]; - EXPECT_TRUE([fetcherWithDefaultArgs.variationsUrl.absoluteString - hasPrefix:expectedUrlPrefix]); - // Valid server url and channel arguments. - NSString* expectedUrl = [NSString - stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", testServer, - base::SysUTF8ToNSString( - version_info::GetMajorVersionNumber()), - testChannel]; - TestVariationsSeedFetcher* fetcherWithValidArgs = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[ - testServerArgument, testChannelArgument - ]]; - EXPECT_NSEQ(fetcherWithValidArgs.variationsUrl.absoluteString, expectedUrl); - // Valid server url argument; no channel argument. - expectedUrlPrefix = [NSString stringWithFormat:@"%@?osname=ios", testServer]; - fetcherWithValidArgs = [[TestVariationsSeedFetcher alloc] - initWithCommandLineArgsForTesting:@[ testServerArgument ]]; - EXPECT_TRUE([fetcherWithValidArgs.variationsUrl.absoluteString - hasPrefix:expectedUrlPrefix]); - EXPECT_FALSE([fetcherWithValidArgs.variationsUrl.absoluteString - containsString:testChannel]); - // Valid channel argument; no server url argument. - expectedUrl = - [NSString stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", - base::SysUTF8ToNSString(kDefaultServerUrl), - base::SysUTF8ToNSString( - version_info::GetMajorVersionNumber()), - testChannel]; - fetcherWithValidArgs = [[TestVariationsSeedFetcher alloc] - initWithCommandLineArgsForTesting:@[ testChannelArgument ]]; - EXPECT_NSEQ(fetcherWithValidArgs.variationsUrl.absoluteString, expectedUrl); -} - // Tests that the request to the finch server would not be made when seed // fetching is not enabled. TEST_F(IOSChromeVariationsSeedFetcherTest, @@ -160,18 +79,18 @@ // Attach mock delegate. id delegate = OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate)); - OCMExpect([delegate didFetchSeedSuccess:NO]); + OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]); // Start fetching seed from fetcher. Seed fetching is disabled by default in // tests. - base::HistogramTester histogramTester; - TestVariationsSeedFetcher* fetcher = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; + base::HistogramTester histogram_tester; + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; fetcher.delegate = delegate; [fetcher startSeedFetch]; base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); EXPECT_OCMOCK_VERIFY(delegate); - histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 0); - histogramTester.ExpectTotalCount(kSeedFetchResultHistogram, 0); + histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0); + histogram_tester.ExpectTotalCount(kSeedFetchResultHistogram, 0); } // Tests that the request to the finch server would be made when seed fetching @@ -179,151 +98,287 @@ TEST_F(IOSChromeVariationsSeedFetcherTest, testThatRequestIsMadeWhenFetchSeedEnabled) { // Instantiate mocks. - BOOL (^requestMatcher)(NSMutableURLRequest* request) = + BOOL (^request_matcher)(NSMutableURLRequest* request) = ^BOOL(NSMutableURLRequest* request) { // The NSString method `hasPrefix` does not take parameter of type // 'const NSString *__strong`. - NSString* prefix = [NSString stringWithFormat:@"%@", testServer]; + NSString* prefix = [NSString stringWithFormat:@"%@", test_server]; return [request.URL.absoluteString hasPrefix:prefix] && [request.allHTTPHeaderFields[@"A-IM"] isEqualToString:@"gzip"]; }; - id mockURLSession = OCMClassMock([NSURLSession class]); - OCMStub([mockURLSession sharedSession]).andReturn(mockURLSession); - OCMExpect([mockURLSession - dataTaskWithRequest:[OCMArg checkWithBlock:requestMatcher] + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + OCMExpect([mock_url_session + dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher] completionHandler:[OCMArg any]]); // Start fetching seed from fetcher. Pass a fake value for // `kVariationsServerURL` to enable testing. NSString* argument = [NSString stringWithFormat:@"--%@=%@", base::SysUTF8ToNSString(kVariationsServerURL), - testServer]; - TestVariationsSeedFetcher* fetcher = [[TestVariationsSeedFetcher alloc] - initWithCommandLineArgsForTesting:@[ argument ]]; + test_server]; + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[ argument ]]; [fetcher startSeedFetch]; base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - EXPECT_OCMOCK_VERIFY(mockURLSession); + EXPECT_OCMOCK_VERIFY(mock_url_session); } -// Tests that the seed would not be created when there is a request with the -// HTTP response, and that the delegate would be notified so. -TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPResponseError) { - // Instantiate mocks and expectation. - id timeoutError = OCMClassMock([NSError class]); - OCMStub([timeoutError code]).andReturn(NSURLErrorTimedOut); - id responseOk = OCMClassMock([NSHTTPURLResponse class]); - OCMStub([responseOk statusCode]).andReturn(net::HTTP_OK); - id responseError = OCMClassMock([NSHTTPURLResponse class]); - OCMStub([responseError statusCode]).andReturn(net::HTTP_NOT_FOUND); +// Tests that the default variations url is correct. +TEST_F(IOSChromeVariationsSeedFetcherTest, TestDefaultVariationsURL) { + // Instantiate mocks and expectations. + BOOL (^request_matcher)(NSMutableURLRequest* request) = + ^BOOL(NSMutableURLRequest* request) { + NSString* expected_url_prefix = [NSString + stringWithFormat:@"%@?osname=ios&milestone=", + base::SysUTF8ToNSString(kDefaultServerUrl)]; + return [request.URL.absoluteString hasPrefix:expected_url_prefix]; + }; + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + OCMExpect([mock_url_session + dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher] + completionHandler:[OCMArg any]]); + // Fetch and check. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + [fetcher doActualFetch]; + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); + EXPECT_OCMOCK_VERIFY(mock_url_session); +} + +// Tests that the variations url is correct with a fake channel. +TEST_F(IOSChromeVariationsSeedFetcherTest, TestVariationsURLWithFakeChannel) { + NSString* test_channel = @"fake_channel"; + // Instantiate mocks. + BOOL (^request_matcher)(NSMutableURLRequest* request) = + ^BOOL(NSMutableURLRequest* request) { + NSString* expected_url = [NSString + stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", + base::SysUTF8ToNSString(kDefaultServerUrl), + base::SysUTF8ToNSString( + version_info::GetMajorVersionNumber()), + test_channel]; + return [request.URL.absoluteString isEqualToString:expected_url]; + }; + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + OCMExpect([mock_url_session + dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher] + completionHandler:[OCMArg any]]); + + // Pass a fake value for `kFakeVariationsChannel` to make sure it's + // represented in the URL. + NSString* test_channel_argument = [NSString + stringWithFormat:@"--%@=%@", + base::SysUTF8ToNSString(kFakeVariationsChannel), + test_channel]; + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] + initWithArguments:@[ test_channel_argument ]]; + [fetcher doActualFetch]; + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); + EXPECT_OCMOCK_VERIFY(mock_url_session); +} + +// Tests that the variations url is correct with a fake channel and fake +// server. +TEST_F(IOSChromeVariationsSeedFetcherTest, + TestVariationsURLWithFakeChannelAndFakeServer) { + NSString* test_channel = @"fake_channel"; + // Instantiate mocks. + BOOL (^request_matcher)(NSMutableURLRequest* request) = ^BOOL( + NSMutableURLRequest* request) { + NSString* expected_url = [NSString + stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", test_server, + base::SysUTF8ToNSString( + version_info::GetMajorVersionNumber()), + test_channel]; + return [request.URL.absoluteString isEqualToString:expected_url]; + }; + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + OCMExpect([mock_url_session + dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher] + completionHandler:[OCMArg any]]); + + // Pass a fake value for `kFakeVariationsChannel` to make sure it's + // represented in the URL. + NSString* test_channel_argument = [NSString + stringWithFormat:@"--%@=%@", + base::SysUTF8ToNSString(kFakeVariationsChannel), + test_channel]; + // Pass a fake value for `kVariationsServerURL` to enable testing. + NSString* test_server_argument = + [NSString stringWithFormat:@"--%@=%@", + base::SysUTF8ToNSString(kVariationsServerURL), + test_server]; + + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] + initWithArguments:@[ test_channel_argument, test_server_argument ]]; + [fetcher doActualFetch]; + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); + EXPECT_OCMOCK_VERIFY(mock_url_session); +} + +// Tests that the see won't be created when an HTTP timeout error occurs, and +// that the delegate would be notified so. +TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPTimeoutError) { + base::HistogramTester histogram_tester; + // Instantiate the mocks + id timeout_error = OCMClassMock([NSError class]); + OCMStub([timeout_error code]).andReturn(NSURLErrorTimedOut); + id response_ok = OCMClassMock([NSHTTPURLResponse class]); + OCMStub([response_ok statusCode]).andReturn(net::HTTP_OK); id delegate = OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate)); - OCMExpect([delegate didFetchSeedSuccess:NO]); - OCMExpect([delegate didFetchSeedSuccess:NO]); - // Test if onSeedRequestCompletedWithData:response:error correctly handles - // NSError and unexpected response code. - TestVariationsSeedFetcher* fetcher = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; + OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]); + // Invalidate the NSURLSession so the original request completion handler + // would not be executed. + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + // Start the test. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; fetcher.delegate = delegate; - fetcher.startTimeOfOngoingSeedRequest = base::Time::Now(); - // Test timeout error. - base::HistogramTester histogramTesterTimeoutError; - [fetcher onSeedRequestCompletedWithData:nil - response:responseOk - error:timeoutError]; + [fetcher doActualFetch]; + [fetcher seedRequestDidCompleteWithData:nil + response:response_ok + error:timeout_error]; base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil); - EXPECT_TRUE(fetcher.startTimeOfOngoingSeedRequest.is_null()); - histogramTesterTimeoutError.ExpectTotalCount(kSeedFetchTimeHistogram, 0); - histogramTesterTimeoutError.ExpectUniqueSample( + histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0); + histogram_tester.ExpectUniqueSample( kSeedFetchResultHistogram, IOSSeedFetchException::kHTTPSRequestTimeout, 1); - // Test response code error. - base::HistogramTester histogramTesterNotFound; - fetcher.startTimeOfOngoingSeedRequest = base::Time::Now(); - [fetcher onSeedRequestCompletedWithData:nil response:responseError error:nil]; - base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil); - EXPECT_TRUE(fetcher.startTimeOfOngoingSeedRequest.is_null()); - EXPECT_OCMOCK_VERIFY(delegate); - histogramTesterNotFound.ExpectTotalCount(kSeedFetchTimeHistogram, 0); - histogramTesterNotFound.ExpectUniqueSample(kSeedFetchResultHistogram, - net::HTTP_NOT_FOUND, 1); } -// Tests that the seed creation would be attempted when there is a request with -// the HTTP response, and that the delegate would be notified if it fails. +// Tests that the see won't be created when the response code is unexpected, and +// that the delegate would be notified so. +TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPResponseCodeError) { + base::HistogramTester histogram_tester; + // Instantiate mocks. + id response_error = OCMClassMock([NSHTTPURLResponse class]); + OCMStub([response_error statusCode]).andReturn(net::HTTP_NOT_FOUND); + id delegate = + OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate)); + OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]); + // Invalidate the NSURLSession so the original request completion handler + // would not be executed. + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); + // Start the test. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + fetcher.delegate = delegate; + [fetcher doActualFetch]; + [fetcher seedRequestDidCompleteWithData:nil + response:response_error + error:nil]; + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); + EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil); + EXPECT_OCMOCK_VERIFY(delegate); + histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0); + histogram_tester.ExpectUniqueSample(kSeedFetchResultHistogram, + net::HTTP_NOT_FOUND, 1); +} + +// Tests that the seed creation would be attempted when there is a request +// with the HTTP response, and that the delegate would be notified if it +// fails. TEST_F(IOSChromeVariationsSeedFetcherTest, testValidHTTPResponseWithFailingSeedCreation) { + base::HistogramTester histogram_tester; // Setup. id delegate = OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate)); - TestVariationsSeedFetcher* rawfetcher = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; - rawfetcher.delegate = delegate; - rawfetcher.startTimeOfOngoingSeedRequest = base::Time::NowFromSystemTime(); + OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]); + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + fetcher.delegate = delegate; id response = OCMClassMock([NSHTTPURLResponse class]); OCMStub([response statusCode]).andReturn(net::HTTP_OK); + // Invalidate the NSURLSession so the original request completion handler + // would not be executed. + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); // Execute test. - id fetcherWithSeed = OCMPartialMock(rawfetcher); - OCMStub([fetcherWithSeed seedResponseForHTTPResponse:response data:nil]) - .andDo(nil); - OCMExpect([delegate didFetchSeedSuccess:NO]); - base::HistogramTester histogramTester; - [fetcherWithSeed onSeedRequestCompletedWithData:nil - response:response - error:nil]; + [fetcher doActualFetch]; + [fetcher seedRequestDidCompleteWithData:nil response:response error:nil]; base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - EXPECT_TRUE([fetcherWithSeed startTimeOfOngoingSeedRequest].is_null()); EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil); EXPECT_OCMOCK_VERIFY(delegate); - histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 1); - histogramTester.ExpectUniqueSample( + histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 1); + histogram_tester.ExpectUniqueSample( kSeedFetchResultHistogram, IOSSeedFetchException::kInvalidIMHeader, 1); } // Tests that the seed would not be created when the instance manipulation -// header format is wrong. -TEST_F(IOSChromeVariationsSeedFetcherTest, testInvalidInstanceManipulation) { - NSString* signature = [NSDate now].description; - NSString* country = @"US"; - NSDictionary<NSString*, NSString*>* headersWithoutIM = @{ - @"X-Seed-Signature" : signature, - @"X-Country" : country, +// header does not exist. +TEST_F(IOSChromeVariationsSeedFetcherTest, testNoIMHeader) { + // Set up. + NSDictionary<NSString*, NSString*>* header = @{ + @"X-Seed-Signature" : [NSDate now].description, + @"X-Country" : @"US", }; - TestVariationsSeedFetcher* fetcher = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; - // No IM. - id responseNoIM = OCMClassMock([NSHTTPURLResponse class]); - OCMStub([responseNoIM valueForHTTPHeaderField:[OCMArg any]]) - .andDo(GetMockMethodWithHeader(headersWithoutIM)); + id response = OCMClassMock([NSHTTPURLResponse class]); + OCMStub([response valueForHTTPHeaderField:[OCMArg any]]) + .andDo(GetMockMethodWithHeader(header)); + // Execute test. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; std::unique_ptr<variations::SeedResponse> seed = - [fetcher seedResponseForHTTPResponse:responseNoIM data:nil]; - EXPECT_EQ(seed, nullptr); - // Incorrect IM. - NSMutableDictionary<NSString*, NSString*>* headerWithBadIM = - [NSMutableDictionary dictionaryWithDictionary:headersWithoutIM]; - headerWithBadIM[@"IM"] = @"not_gzip"; - id responseBadIM = OCMClassMock([NSHTTPURLResponse class]); - OCMStub([responseBadIM valueForHTTPHeaderField:[OCMArg any]]) - .andDo(GetMockMethodWithHeader(headerWithBadIM)); - seed = [fetcher seedResponseForHTTPResponse:responseBadIM data:nil]; - EXPECT_EQ(seed, nullptr); - // More IM than expected. - NSMutableDictionary<NSString*, NSString*>* headerWithTwoIMs = - [NSMutableDictionary dictionaryWithDictionary:headersWithoutIM]; - headerWithTwoIMs[@"IM"] = @"gzip,somethingelse"; - id responseTwoIMs = OCMClassMock([NSHTTPURLResponse class]); - OCMStub([responseTwoIMs valueForHTTPHeaderField:[OCMArg any]]) - .andDo(GetMockMethodWithHeader(headerWithTwoIMs)); - seed = [fetcher seedResponseForHTTPResponse:responseTwoIMs data:nil]; + [fetcher seedResponseForHTTPResponse:response data:nil]; EXPECT_EQ(seed, nullptr); } -// Tests that the seed would be created with property values extracted from the -// HTTP response with expected header format, and that the delegate would be -// notified of the successful seed creation. +// Tests that the seed would not be created when the instance manipulation +// header is not "gzip". +TEST_F(IOSChromeVariationsSeedFetcherTest, testBadIMHeader) { + // Set up. + NSDictionary<NSString*, NSString*>* header = @{ + @"X-Seed-Signature" : [NSDate now].description, + @"X-Country" : @"US", + @"IM" : @"not_gzip" + }; + id response = OCMClassMock([NSHTTPURLResponse class]); + OCMStub([response valueForHTTPHeaderField:[OCMArg any]]) + .andDo(GetMockMethodWithHeader(header)); + // Execute test. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + std::unique_ptr<variations::SeedResponse> seed = + [fetcher seedResponseForHTTPResponse:response data:nil]; + EXPECT_EQ(seed, nullptr); +} + +// Tests that the seed would not be created when the instance manipulation +// header has more than one value. +TEST_F(IOSChromeVariationsSeedFetcherTest, tesMoreThanOneIMHeaders) { + // Set up. + NSDictionary<NSString*, NSString*>* header = @{ + @"X-Seed-Signature" : [NSDate now].description, + @"X-Country" : @"US", + @"IM" : @"gzip,somethingelse" + }; + id response = OCMClassMock([NSHTTPURLResponse class]); + OCMStub([response valueForHTTPHeaderField:[OCMArg any]]) + .andDo(GetMockMethodWithHeader(header)); + // Execute test. + IOSChromeVariationsSeedFetcher* fetcher = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + std::unique_ptr<variations::SeedResponse> seed = + [fetcher seedResponseForHTTPResponse:response data:nil]; + EXPECT_EQ(seed, nullptr); +} + +// Tests that the seed would be created with property values extracted from +// the HTTP response with expected header format, and that the delegate would +// be notified of the successful seed creation. TEST_F(IOSChromeVariationsSeedFetcherTest, testValidHTTPResponseWithSuccessfulSeedCreation) { + base::HistogramTester histogram_tester; NSString* signature = [NSDate now].description; NSString* country = @"US"; NSDictionary<NSString*, NSString*>* headers = @{ @@ -338,26 +393,27 @@ // Setup. id delegate = OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate)); - TestVariationsSeedFetcher* fetcherWithSeed = - [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]]; - fetcherWithSeed.delegate = delegate; - fetcherWithSeed.startTimeOfOngoingSeedRequest = - base::Time::NowFromSystemTime(); + OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:YES]); + IOSChromeVariationsSeedFetcher* fetcher_with_seed = + [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]]; + fetcher_with_seed.delegate = delegate; + // Invalidate the NSURLSession so the original request completion handler + // would not be executed. + id mock_url_session = OCMClassMock([NSURLSession class]); + OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session); // Execute test. - base::HistogramTester histogramTester; - OCMExpect([delegate didFetchSeedSuccess:YES]); - [fetcherWithSeed onSeedRequestCompletedWithData:nil - response:response - error:nil]; + [fetcher_with_seed doActualFetch]; + [fetcher_with_seed seedRequestDidCompleteWithData:nil + response:response + error:nil]; base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - EXPECT_TRUE([fetcherWithSeed startTimeOfOngoingSeedRequest].is_null()); auto seed = [IOSChromeVariationsSeedStore popSeed]; ASSERT_NE(seed, nullptr); EXPECT_EQ(seed->signature, base::SysNSStringToUTF8(signature)); EXPECT_EQ(seed->country, base::SysNSStringToUTF8(country)); EXPECT_EQ(seed->data, ""); EXPECT_OCMOCK_VERIFY(delegate); - histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 1); - histogramTester.ExpectUniqueSample(kSeedFetchResultHistogram, net::HTTP_OK, - 1); + histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 1); + histogram_tester.ExpectUniqueSample(kSeedFetchResultHistogram, net::HTTP_OK, + 1); }
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h similarity index 90% rename from ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h rename to ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h index 010a307c..461f887 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.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 IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_ -#define IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_ +#ifndef IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_ +#define IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_ // Extraction of seed update method in IOSChromeVariationsSeedStore to // be used (and ONLY used) by the fetcher. @@ -13,4 +13,4 @@ @end -#endif // IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_ +#endif // IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm index aa9f4b07..3bef156 100644 --- a/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm +++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm
@@ -6,7 +6,7 @@ #import "base/no_destructor.h" #import "components/variations/seed_response.h" -#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h" +#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/components/webui/sync_internals/sync_internals_message_handler.h b/ios/components/webui/sync_internals/sync_internals_message_handler.h index 945670ca..f28c586 100644 --- a/ios/components/webui/sync_internals/sync_internals_message_handler.h +++ b/ios/components/webui/sync_internals/sync_internals_message_handler.h
@@ -57,9 +57,6 @@ // Handler for requestStart message. void HandleRequestStart(const base::Value::List& args); - // Handler for requestStopKeepData message. - void HandleRequestStopKeepData(const base::Value::List& args); - // Handler for requestStopClearData message. void HandleRequestStopClearData(const base::Value::List& args);
diff --git a/ios/components/webui/sync_internals/sync_internals_message_handler.mm b/ios/components/webui/sync_internals/sync_internals_message_handler.mm index 1f1419553..e9803f73 100644 --- a/ios/components/webui/sync_internals/sync_internals_message_handler.mm +++ b/ios/components/webui/sync_internals/sync_internals_message_handler.mm
@@ -92,12 +92,6 @@ base::Unretained(this))); web_ui()->RegisterMessageCallback( - syncer::sync_ui_util::kRequestStopKeepData, - base::BindRepeating( - &SyncInternalsMessageHandler::HandleRequestStopKeepData, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( syncer::sync_ui_util::kRequestStopClearData, base::BindRepeating( &SyncInternalsMessageHandler::HandleRequestStopClearData, @@ -198,18 +192,6 @@ syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); } -void SyncInternalsMessageHandler::HandleRequestStopKeepData( - const base::Value::List& args) { - DCHECK_EQ(0U, args.size()); - - syncer::SyncService* service = GetSyncService(); - if (!service) { - return; - } - - service->GetUserSettings()->ClearSyncRequested(); -} - void SyncInternalsMessageHandler::HandleRequestStopClearData( const base::Value::List& args) { DCHECK_EQ(0U, args.size());
diff --git a/ios/testing/data/http_server_files/green.pdf b/ios/testing/data/http_server_files/green.pdf new file mode 100644 index 0000000..03b055f --- /dev/null +++ b/ios/testing/data/http_server_files/green.pdf Binary files differ
diff --git a/ios/testing/http_server_bundle_data.filelist b/ios/testing/http_server_bundle_data.filelist index d833ae0..6509579f 100644 --- a/ios/testing/http_server_bundle_data.filelist +++ b/ios/testing/http_server_bundle_data.filelist
@@ -16,6 +16,7 @@ data/http_server_files/download_test_page.html data/http_server_files/fullscreen.html data/http_server_files/generic.pkpass +data/http_server_files/green.pdf data/http_server_files/history.html data/http_server_files/history.js data/http_server_files/history_go.html
diff --git a/ios/web_view/internal/webui/web_view_sync_internals_ui.mm b/ios/web_view/internal/webui/web_view_sync_internals_ui.mm index 734a2fc..b0134b4 100644 --- a/ios/web_view/internal/webui/web_view_sync_internals_ui.mm +++ b/ios/web_view/internal/webui/web_view_sync_internals_ui.mm
@@ -24,7 +24,6 @@ // ios/web_view only supports sync in transport mode. Explicitly override sync // start and stop messages and perform a no op. return message == syncer::sync_ui_util::kRequestStart || - message == syncer::sync_ui_util::kRequestStopKeepData || message == syncer::sync_ui_util::kRequestStopClearData; }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index b686cae..a5951ea 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -372,7 +372,10 @@ "vp9_svc_layers.h", ] configs += [ "//third_party/libvpx:libvpx_config" ] - deps += [ "//third_party/libvpx:libvpxrc" ] + deps += [ + "//third_party/libaom:libaomrc", + "//third_party/libvpx:libvpxrc", + ] } if (use_libgav1_parser) { sources += [
diff --git a/media/gpu/chromeos/BUILD.gn b/media/gpu/chromeos/BUILD.gn index 165d6ea..53cb5a1 100644 --- a/media/gpu/chromeos/BUILD.gn +++ b/media/gpu/chromeos/BUILD.gn
@@ -86,8 +86,6 @@ "vda_video_frame_pool.cc", "vda_video_frame_pool.h", "video_decoder_pipeline.h", - "video_frame_converter.cc", - "video_frame_converter.h", ] # TODO(crbug.com/1012587): Merge :fourcc to :common.
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.cc b/media/gpu/chromeos/mailbox_video_frame_converter.cc index c633f9b..c9a2d78 100644 --- a/media/gpu/chromeos/mailbox_video_frame_converter.cc +++ b/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -16,7 +16,6 @@ #include "gpu/command_buffer/service/scheduler.h" #include "gpu/ipc/service/gpu_channel.h" #include "media/base/format_utils.h" -#include "media/base/video_frame.h" #include "media/base/video_util.h" #include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/macros.h" @@ -172,7 +171,7 @@ }; // static -std::unique_ptr<VideoFrameConverter> MailboxVideoFrameConverter::Create( +std::unique_ptr<MailboxVideoFrameConverter> MailboxVideoFrameConverter::Create( UnwrapFrameCB unwrap_frame_cb, scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, GetCommandBufferStubCB get_stub_cb, @@ -192,7 +191,7 @@ auto gpu_delegate = std::make_unique<GpuDelegateImpl>( gpu_task_runner, std::move(get_gpu_channel_cb)); - return base::WrapUnique<VideoFrameConverter>(new MailboxVideoFrameConverter( + return base::WrapUnique(new MailboxVideoFrameConverter( std::move(unwrap_frame_cb), std::move(gpu_task_runner), std::move(gpu_delegate), enable_unsafe_webgpu)); } @@ -212,6 +211,13 @@ gpu_weak_this_ = gpu_weak_this_factory_.GetWeakPtr(); } +void MailboxVideoFrameConverter::Initialize( + scoped_refptr<base::SequencedTaskRunner> parent_task_runner, + OutputCB output_cb) { + parent_task_runner_ = std::move(parent_task_runner); + output_cb_ = std::move(output_cb); +} + void MailboxVideoFrameConverter::Destroy() { DCHECK(!parent_task_runner_ || parent_task_runner_->RunsTasksInCurrentSequence()); @@ -571,3 +577,12 @@ } } // namespace media + +namespace std { + +void default_delete<media::MailboxVideoFrameConverter>::operator()( + media::MailboxVideoFrameConverter* ptr) const { + ptr->Destroy(); +} + +} // namespace std
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.h b/media/gpu/chromeos/mailbox_video_frame_converter.h index d330f49..1f1ad92 100644 --- a/media/gpu/chromeos/mailbox_video_frame_converter.h +++ b/media/gpu/chromeos/mailbox_video_frame_converter.h
@@ -13,7 +13,7 @@ #include "gpu/command_buffer/common/mailbox.h" #include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/service/shared_image_stub.h" -#include "media/gpu/chromeos/video_frame_converter.h" +#include "media/base/video_frame.h" #include "media/gpu/media_gpu_export.h" #include "third_party/skia/include/core/SkAlphaType.h" #include "third_party/skia/include/gpu/GrTypes.h" @@ -34,14 +34,13 @@ namespace media { -class VideoFrame; - // This class is used for converting GpuMemoryBuffer-backed VideoFrames to // gpu::Mailbox-backed VideoFrames. See ConvertFrame() for more details. After // conversion, the gpu::Mailbox-backed VideoFrame will retain a reference of the // VideoFrame passed to ConvertFrame(). -class MEDIA_GPU_EXPORT MailboxVideoFrameConverter : public VideoFrameConverter { +class MEDIA_GPU_EXPORT MailboxVideoFrameConverter { public: + using OutputCB = base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>; using UnwrapFrameCB = base::RepeatingCallback<VideoFrame*(const VideoFrame& wrapped_frame)>; using GetCommandBufferStubCB = @@ -81,7 +80,7 @@ // |enable_unsafe_webgpu| hints whether to request the creation of // SharedImages with SHARED_IMAGE_USAGE_WEBGPU. Returns nullptr if the // MailboxVideoFrameConverter can't be created. - static std::unique_ptr<VideoFrameConverter> Create( + static std::unique_ptr<MailboxVideoFrameConverter> Create( UnwrapFrameCB unwrap_frame_cb, scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, GetCommandBufferStubCB get_stub_cb, @@ -91,17 +90,24 @@ MailboxVideoFrameConverter& operator=(const MailboxVideoFrameConverter&) = delete; + // Initializes the converter. This method must be called before any + // ConvertFrame() is called. + void Initialize(scoped_refptr<base::SequencedTaskRunner> parent_task_runner, + OutputCB output_cb); + // Enqueues |frame| to be converted to a gpu::Mailbox-backed VideoFrame. If - // the |unwrap_frame_cb| supplied in Create() is non-null, |frame| must wrap a - // GpuMemoryBuffer-backed VideoFrame that is retrieved via that callback. + // the |unwrap_frame_cb| supplied in Create() is non-null, |frame| must wrap + // a GpuMemoryBuffer-backed VideoFrame that is retrieved via that callback. // Otherwise, |frame| will be used directly and must be a - // GpuMemoryBuffer-backed VideoFrame. The generated gpu::Mailbox is kept alive - // until the GpuMemoryBuffer-backed VideoFrame is destroyed. - void ConvertFrame(scoped_refptr<VideoFrame> frame) override; - void AbortPendingFrames() override; - bool HasPendingFrames() const override; + // GpuMemoryBuffer-backed VideoFrame. The generated gpu::Mailbox is kept + // alive until the GpuMemoryBuffer-backed VideoFrame is destroyed. These + // methods must be called on |parent_task_runner_| + void ConvertFrame(scoped_refptr<VideoFrame> frame); + void AbortPendingFrames(); + bool HasPendingFrames() const; private: + friend struct std::default_delete<MailboxVideoFrameConverter>; friend class MailboxVideoFrameConverterTest; friend class MailboxVideoFrameConverterWithUnwrappedFramesTest; @@ -117,8 +123,9 @@ std::unique_ptr<GpuDelegate> gpu_delegate, bool enable_unsafe_webgpu); // Destructor runs on the GPU main thread. - ~MailboxVideoFrameConverter() override; - void Destroy() override; + ~MailboxVideoFrameConverter(); + + void Destroy(); void DestroyOnGPUThread(); // TODO(crbug.com/998279): replace s/OnGPUThread/OnGPUTaskRunner/. @@ -206,6 +213,13 @@ const bool enable_unsafe_webgpu_; + // The working task runner. + scoped_refptr<base::SequencedTaskRunner> parent_task_runner_; + + // The callback to return converted frames back to client. This callback will + // be called on |parent_task_runner_|. + OutputCB output_cb_; + // The weak pointer of this, bound to |parent_task_runner_|. // Used at the VideoFrame destruction callback. base::WeakPtr<MailboxVideoFrameConverter> parent_weak_this_; @@ -218,4 +232,15 @@ }; } // namespace media + +namespace std { + +// Specialize std::default_delete to call Destroy(). +template <> +struct MEDIA_GPU_EXPORT default_delete<media::MailboxVideoFrameConverter> { + void operator()(media::MailboxVideoFrameConverter* ptr) const; +}; + +} // namespace std + #endif // MEDIA_GPU_CHROMEOS_MAILBOX_VIDEO_FRAME_CONVERTER_H_
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc b/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc index 375c74f..95e09246 100644 --- a/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc +++ b/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc
@@ -124,7 +124,7 @@ std::vector<std::unique_ptr<StrictMock<base::MockOnceCallback<void()>>>> mock_frame_destruction_cbs_; - std::unique_ptr<VideoFrameConverter> converter_; + std::unique_ptr<MailboxVideoFrameConverter> converter_; }; class MailboxVideoFrameConverterWithUnwrappedFramesTest @@ -133,8 +133,7 @@ MailboxVideoFrameConverterWithUnwrappedFramesTest() { auto mock_gpu_delegate = std::make_unique<StrictMock<MockGpuDelegate>>(); mock_gpu_delegate_ = mock_gpu_delegate.get(); - converter_ = base::WrapUnique< - VideoFrameConverter>(new MailboxVideoFrameConverter( + converter_ = base::WrapUnique(new MailboxVideoFrameConverter( /*unwrap_frame_cb=*/base::NullCallback(), /*gpu_task_runner=*/base::ThreadPool::CreateSingleThreadTaskRunner({}), std::move(mock_gpu_delegate),
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc index 6e66f2f9a..43b851c 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.cc +++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -194,7 +194,7 @@ const gpu::GpuDriverBugWorkarounds& workarounds, scoped_refptr<base::SequencedTaskRunner> client_task_runner, std::unique_ptr<DmabufVideoFramePool> frame_pool, - std::unique_ptr<VideoFrameConverter> frame_converter, + std::unique_ptr<MailboxVideoFrameConverter> frame_converter, std::vector<Fourcc> renderable_fourccs, std::unique_ptr<MediaLog> media_log, mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder) { @@ -307,7 +307,7 @@ const gpu::GpuDriverBugWorkarounds& gpu_workarounds, scoped_refptr<base::SequencedTaskRunner> client_task_runner, std::unique_ptr<DmabufVideoFramePool> frame_pool, - std::unique_ptr<VideoFrameConverter> frame_converter, + std::unique_ptr<MailboxVideoFrameConverter> frame_converter, std::vector<Fourcc> renderable_fourccs, std::unique_ptr<MediaLog> media_log, CreateDecoderFunctionCB create_decoder_function_cb,
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h index 28216ea3..35d31480 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.h +++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -22,7 +22,7 @@ #include "media/gpu/chromeos/chromeos_status.h" #include "media/gpu/chromeos/fourcc.h" #include "media/gpu/chromeos/image_processor_with_pool.h" -#include "media/gpu/chromeos/video_frame_converter.h" +#include "media/gpu/chromeos/mailbox_video_frame_converter.h" #include "media/gpu/media_gpu_export.h" #include "media/mojo/mojom/stable/stable_video_decoder.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -155,7 +155,7 @@ const gpu::GpuDriverBugWorkarounds& workarounds, scoped_refptr<base::SequencedTaskRunner> client_task_runner, std::unique_ptr<DmabufVideoFramePool> frame_pool, - std::unique_ptr<VideoFrameConverter> frame_converter, + std::unique_ptr<MailboxVideoFrameConverter> frame_converter, std::vector<Fourcc> renderable_fourccs, std::unique_ptr<MediaLog> media_log, mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder); @@ -228,7 +228,7 @@ const gpu::GpuDriverBugWorkarounds& workarounds, scoped_refptr<base::SequencedTaskRunner> client_task_runner, std::unique_ptr<DmabufVideoFramePool> frame_pool, - std::unique_ptr<VideoFrameConverter> frame_converter, + std::unique_ptr<MailboxVideoFrameConverter> frame_converter, std::vector<Fourcc> renderable_fourccs, std::unique_ptr<MediaLog> media_log, CreateDecoderFunctionCB create_decoder_function_cb, @@ -327,7 +327,7 @@ // The frame converter passed from the client, otherwise used and destroyed on // |decoder_task_runner_|. - std::unique_ptr<VideoFrameConverter> frame_converter_ + std::unique_ptr<MailboxVideoFrameConverter> frame_converter_ GUARDED_BY_CONTEXT(decoder_sequence_checker_); // The set of output formats allowed to be used in order of preference.
diff --git a/media/gpu/chromeos/video_frame_converter.cc b/media/gpu/chromeos/video_frame_converter.cc deleted file mode 100644 index c2fee61..0000000 --- a/media/gpu/chromeos/video_frame_converter.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/gpu/chromeos/video_frame_converter.h" -#include "base/task/sequenced_task_runner.h" - -namespace media { - -VideoFrameConverter::VideoFrameConverter() = default; - -VideoFrameConverter::~VideoFrameConverter() = default; - -void VideoFrameConverter::Destroy() { - delete this; -} - -void VideoFrameConverter::Initialize( - scoped_refptr<base::SequencedTaskRunner> parent_task_runner, - OutputCB output_cb) { - parent_task_runner_ = std::move(parent_task_runner); - output_cb_ = std::move(output_cb); -} - -void VideoFrameConverter::ConvertFrame(scoped_refptr<VideoFrame> frame) { - DCHECK(parent_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(output_cb_); - - output_cb_.Run(std::move(frame)); -} - -void VideoFrameConverter::AbortPendingFrames() {} - -bool VideoFrameConverter::HasPendingFrames() const { - return false; -} - -} // namespace media - -namespace std { - -void default_delete<media::VideoFrameConverter>::operator()( - media::VideoFrameConverter* ptr) const { - ptr->Destroy(); -} - -} // namespace std
diff --git a/media/gpu/chromeos/video_frame_converter.h b/media/gpu/chromeos/video_frame_converter.h deleted file mode 100644 index fed2894..0000000 --- a/media/gpu/chromeos/video_frame_converter.h +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_ -#define MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_ - -#include <memory> - -#include "base/functional/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_refptr.h" -#include "base/task/sequenced_task_runner.h" -#include "media/base/video_frame.h" -#include "media/gpu/media_gpu_export.h" - -namespace media { - -// Video decoders make use of a video frame pool to allocate output frames, -// which are sent to the client after decoding. However, the storage type of the -// allocated frame can be different from what the client expects. This class -// can be used to convert the type of output video frame in this case. -class MEDIA_GPU_EXPORT VideoFrameConverter { - public: - using OutputCB = base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>; - - VideoFrameConverter(); - - VideoFrameConverter(const VideoFrameConverter&) = delete; - VideoFrameConverter& operator=(const VideoFrameConverter&) = delete; - - // Initialize the converter. This method must be called before any - // ConvertFrame() is called. - void Initialize(scoped_refptr<base::SequencedTaskRunner> parent_task_runner, - OutputCB output_cb); - - // Convert the frame and return the converted frame to the client by - // |output_cb_|. This method must be called on |parent_task_runner_|. - // The default implementation calls |output_cb_| with |frame| as-is. - virtual void ConvertFrame(scoped_refptr<VideoFrame> frame); - - // Abort all pending frames. |output_cb_| should not be called for the input - // frames passed before calling AbortPendingFrames(). This method must be - // called on |parent_task_runner_|. - virtual void AbortPendingFrames(); - - // Return true if there is any pending frame. This method must be called on - // |parent_task_runner_|. - virtual bool HasPendingFrames() const; - - protected: - // Deletion is only allowed via Destroy(). - virtual ~VideoFrameConverter(); - - // The working task runner. - scoped_refptr<base::SequencedTaskRunner> parent_task_runner_; - - // The callback to return converted frames back to client. This callback will - // be called on |parent_task_runner_|. - OutputCB output_cb_; - - private: - friend struct std::default_delete<VideoFrameConverter>; - // Called by std::default_delete. - virtual void Destroy(); -}; - -} // namespace media - -namespace std { - -// Specialize std::default_delete to call Destroy(). -template <> -struct MEDIA_GPU_EXPORT default_delete<media::VideoFrameConverter> { - void operator()(media::VideoFrameConverter* ptr) const; -}; - -} // namespace std - -#endif // MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index 6881291..e65f9948 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -107,6 +107,7 @@ "//media/gpu/chromeos:common", "//media/parsers", "//mojo/public/cpp/bindings", + "//third_party/libaom:libaomrc", "//third_party/libvpx:libvpxrc", "//third_party/libyuv", "//ui/gfx",
diff --git a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc index bac8e57..702a9db 100644 --- a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
@@ -8,8 +8,10 @@ #include "base/bits.h" #include "base/logging.h" +#include "media/gpu/macros.h" #include "media/gpu/vaapi/vaapi_common.h" #include "media/gpu/vaapi/vaapi_wrapper.h" +#include "third_party/libaom/source/libaom/av1/ratectrl_rtc.h" #include "third_party/libgav1/src/src/utils/constants.h" namespace media { @@ -17,11 +19,16 @@ // Values from // third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc -// TODO(b/267521747): We might need to adjust these when we actually implement -// rate control. constexpr int kKFPeriod = 3000; +// Quantization parameters for AV1. Between 0 and 255. +constexpr int kMinQIndex = 145; +constexpr int kMaxQIndex = 205; + +// From //third_party/webrtc/media/engine/webrtc_video_engine.h +// These are also quantization parameters, but these are in different units than +// above. These are used in AV1 rate control and are between 0 and 63. constexpr int kMinQP = 10; -constexpr int kMaxQP = 205; +constexpr int kMaxQP = 56; // This needs to be 64, not 16, because of superblocks. // TODO: Look into whether or not we can reduce alignment to 16. @@ -264,8 +271,6 @@ bool AV1VaapiVideoEncoderDelegate::Initialize( const VideoEncodeAccelerator::Config& config, const VaapiVideoEncoderDelegate::Config& ave_config) { - // TODO(b/267521747): Implement rate control - if (config.output_profile != VideoCodecProfile::AV1PROFILE_PROFILE_MAIN) { LOG(ERROR) << "Invalid profile: " << GetProfileName(config.output_profile); return false; @@ -283,6 +288,8 @@ current_params_.framerate = config.initial_framerate.value_or( VideoEncodeAccelerator::kDefaultFramerate); + current_params_.bitrate_allocation.SetBitrate(0, 0, + config.bitrate.target_bps()); level_idx_ = ComputeLevel(coded_size_, current_params_.framerate); if (level_idx_ < 0) { @@ -292,7 +299,8 @@ frame_num_ = current_params_.intra_period; - return true; + return UpdateRates(current_params_.bitrate_allocation, + current_params_.framerate); } AV1VaapiVideoEncoderDelegate::~AV1VaapiVideoEncoderDelegate() = default; @@ -302,8 +310,42 @@ uint32_t framerate) { // TODO(b/267521747): Implement rate control + current_params_.bitrate_allocation = bitrate_allocation; current_params_.framerate = framerate; + aom::AV1RateControlRtcConfig rc_config; + rc_config.width = coded_size_.width(); + rc_config.height = coded_size_.height(); + // third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc + rc_config.max_quantizer = kMaxQP; + rc_config.min_quantizer = kMinQP; + rc_config.target_bandwidth = + current_params_.bitrate_allocation.GetSumBps() / 1000; + rc_config.buf_initial_sz = 600; + rc_config.buf_optimal_sz = 600; + rc_config.buf_sz = 1000; + rc_config.undershoot_pct = 50; + rc_config.overshoot_pct = 50; + rc_config.max_intra_bitrate_pct = 300; + rc_config.max_inter_bitrate_pct = 0; + rc_config.framerate = current_params_.framerate; + rc_config.layer_target_bitrate[0] = + current_params_.bitrate_allocation.GetSumBps() / 1000; + rc_config.ts_rate_decimator[0] = 1; + rc_config.aq_mode = 0; + rc_config.ss_number_layers = 1; + rc_config.ts_number_layers = 1; + rc_config.max_quantizers[0] = kMaxQP; + rc_config.min_quantizers[0] = kMinQP; + rc_config.scaling_factor_num[0] = 1; + rc_config.scaling_factor_den[0] = 1; + + if (!rate_ctrl_) { + rate_ctrl_ = AV1RateControl::Create(rc_config); + return !!rate_ctrl_; + } + + rate_ctrl_->UpdateRateControl(rc_config); return true; } @@ -375,7 +417,14 @@ void AV1VaapiVideoEncoderDelegate::BitrateControlUpdate( const BitstreamBufferMetadata& metadata) { - // TODO(b:267521747): Implement proper bitrate control. + DVLOGF(4) << "encoded chunk size=" << metadata.payload_size_bytes; + + aom::AV1FrameParamsRTC frame_params; + frame_params.frame_type = + metadata.key_frame ? aom::kKeyFrame : aom::kInterFrame; + frame_params.spatial_layer_id = 0; + frame_params.temporal_layer_id = 0; + rate_ctrl_->PostEncodeUpdate(metadata.payload_size_bytes, frame_params); } // See section 5.6 of the AV1 specification. @@ -648,16 +697,23 @@ pic_param.mode_deltas[0] = 0; pic_param.mode_deltas[0] = 0; - pic_param.base_qindex = 128; // TODO(b/267521747): replace this fake value - // with real rate control logic. + aom::AV1FrameParamsRTC frame_params; + frame_params.frame_type = is_keyframe ? aom::kKeyFrame : aom::kInterFrame; + frame_params.spatial_layer_id = 0; + frame_params.temporal_layer_id = 0; + // This method name is a misnomer, GetQP() actually returns the QP in QIndex + // form. + pic_param.base_qindex = rate_ctrl_->ComputeQP(frame_params); + DVLOGF(4) << "qp=" << pic_param.base_qindex + << (is_keyframe ? " (keyframe)" : ""); pic_param.y_dc_delta_q = 0; pic_param.u_dc_delta_q = 0; pic_param.u_ac_delta_q = 0; pic_param.v_dc_delta_q = 0; pic_param.v_ac_delta_q = 0; - pic_param.min_base_qindex = kMinQP; - pic_param.max_base_qindex = kMaxQP; + pic_param.min_base_qindex = kMinQIndex; + pic_param.max_base_qindex = kMaxQIndex; pic_param.qmatrix_flags.bits.using_qmatrix = 0; pic_param.qmatrix_flags.bits.qm_y = 0;
diff --git a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h index 51c463f7..5469b68 100644 --- a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h
@@ -10,6 +10,13 @@ #include "media/base/video_bitrate_allocation.h" #include "media/gpu/av1_picture.h" #include "media/gpu/vaapi/vaapi_video_encoder_delegate.h" +#include "media/gpu/video_rate_control.h" + +namespace aom { +struct AV1RateControlRtcConfig; +struct AV1FrameParamsRTC; +class AV1RateControlRTC; +} // namespace aom namespace media { @@ -64,6 +71,10 @@ std::vector<gfx::Size> GetSVCLayerResolutions() override; private: + using AV1RateControl = VideoRateControl<aom::AV1RateControlRtcConfig, + aom::AV1RateControlRTC, + aom::AV1FrameParamsRTC>; + BitstreamBufferMetadata GetMetadata(const EncodeJob& encode_job, size_t payload_size) override; bool PrepareEncodeJob(EncodeJob& encode_job) override; @@ -97,6 +108,7 @@ // reference frames, not just the most recent. scoped_refptr<AV1Picture> last_frame_ = nullptr; VAEncSequenceParameterBufferAV1 seq_param_; + std::unique_ptr<AV1RateControl> rate_ctrl_; }; } // namespace media
diff --git a/media/gpu/video_rate_control.cc b/media/gpu/video_rate_control.cc index 1e68501..6d884d8 100644 --- a/media/gpu/video_rate_control.cc +++ b/media/gpu/video_rate_control.cc
@@ -4,6 +4,7 @@ #include "media/gpu/video_rate_control.h" +#include "third_party/libaom/source/libaom/av1/ratectrl_rtc.h" #include "third_party/libvpx/source/libvpx/vp8/vp8_ratectrl_rtc.h" #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h" @@ -36,4 +37,13 @@ impl_->PostEncodeUpdate(encoded_frame_size); } +template <> +void VideoRateControl<aom::AV1RateControlRtcConfig, + aom::AV1RateControlRTC, + aom::AV1FrameParamsRTC>:: + PostEncodeUpdate(uint64_t encoded_frame_size, + const aom::AV1FrameParamsRTC& frame_params) { + impl_->PostEncodeUpdate(encoded_frame_size); +} + } // namespace media
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn index 46438ff3..c672ba43 100644 --- a/media/test/BUILD.gn +++ b/media/test/BUILD.gn
@@ -55,7 +55,10 @@ source_set("pipeline_integration_tests") { testonly = true - if (media_use_ffmpeg) { + # Even if FFmpeg is enabled on Android we don't want these. + # TODO(watk): Refactor tests that could be made to run on Android. See + # http://crbug.com/570762 + if (media_use_ffmpeg && !is_android) { sources = [ "pipeline_integration_test.cc" ] deps = [ @@ -67,9 +70,13 @@ "//media/mojo/clients", # Needed for the opus_config - "//testing/gmock", "//third_party/opus", "//url", + + # TODO(dalecurtis): Required since the gmock header is included in the + # header for pipeline_integration_test_base.h. This should be moved + # into the .cc file to avoid the extra dependency here. + "//testing/gmock", ] } } @@ -83,9 +90,13 @@ deps = [ ":pipeline_integration_test_base", "//media:test_support", - "//testing/gmock", "//testing/gtest", "//testing/perf", + + # TODO(dalecurtis): Required since the gmock header is included in the + # header for pipeline_integration_test_base.h. This should be moved into + # the .cc file to avoid the extra dependency here. + "//testing/gmock", ] } } @@ -160,7 +171,14 @@ "//base", "//base/test:test_support", "//media", + + # TODO(dalecurtis): Required since the gmock header is included in the + # header for pipeline_integration_test_base.h. This should be + # moved into the .cc file to avoid the extra dependency here. "//testing/gmock", + + # TODO(https://crbug.com/1039559): Required for inclusion of + # gtest-internal-inl.h. "//testing/gtest", "//ui/gfx:test_support", ]
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index 2049b32..2c85178 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -65,80 +65,80 @@ namespace media { #if BUILDFLAG(ENABLE_AV1_DECODER) -constexpr int kAV110bitMp4FileDurationMs = 2735; -constexpr int kAV1640WebMFileDurationMs = 2736; +const int kAV110bitMp4FileDurationMs = 2735; +const int kAV1640WebMFileDurationMs = 2736; #endif // BUILDFLAG(ENABLE_AV1_DECODER) // Constants for the Media Source config change tests. -constexpr int kAppendTimeSec = 1; -constexpr int kAppendTimeMs = kAppendTimeSec * 1000; -constexpr int k320WebMFileDurationMs = 2736; -constexpr int k640WebMFileDurationMs = 2762; -constexpr int kVP9WebMFileDurationMs = 2736; -constexpr int kVP8AWebMFileDurationMs = 2734; +const int kAppendTimeSec = 1; +const int kAppendTimeMs = kAppendTimeSec * 1000; +const int k320WebMFileDurationMs = 2736; +const int k640WebMFileDurationMs = 2762; +const int kVP9WebMFileDurationMs = 2736; +const int kVP8AWebMFileDurationMs = 2734; -constexpr char kSfxLosslessHash[] = "3.03,2.86,2.99,3.31,3.57,4.06,"; +static const char kSfxLosslessHash[] = "3.03,2.86,2.99,3.31,3.57,4.06,"; #if defined(OPUS_FIXED_POINT) // NOTE: These hashes are specific to ARM devices, which use fixed-point Opus // implementation. x86 uses floating-point Opus, so x86 hashes won't match -constexpr char kOpusSmallCodecDelayHash_1[] = - "-0.48,-0.09,1.27,1.06,1.54,-0.22,"; - -#if defined(ARCH_CPU_ARM_FAMILY) -constexpr char kOpusSmallCodecDelayHash_2[] = "0.29,0.15,-0.19,0.25,0.68,0.83,"; -constexpr char kOpusMonoOutputHash[] = "-2.39,-1.66,0.81,1.54,1.48,-0.91,"; - -#if defined(ARCH_CPU_32BITS) -constexpr char kOpusEndTrimmingHash_1[] = - "-4.58,-5.68,-6.53,-6.29,-4.35,-3.59,"; -constexpr char kOpusEndTrimmingHash_2[] = - "-11.93,-11.12,-8.26,-7.11,-7.85,-10.01,"; -constexpr char kOpusEndTrimmingHash_3[] = - "-13.33,-14.39,-13.69,-11.68,-10.19,-10.50,"; -#else // Assume 64-bits for arm-generic configurations. -constexpr char kOpusEndTrimmingHash_1[] = +#if defined(ARCH_CPU_ARM64) +static const char kOpusEndTrimmingHash_1[] = "-4.58,-5.68,-6.53,-6.28,-4.35,-3.59,"; -constexpr char kOpusEndTrimmingHash_2[] = +static const char kOpusEndTrimmingHash_2[] = "-11.92,-11.11,-8.25,-7.10,-7.84,-10.00,"; -constexpr char kOpusEndTrimmingHash_3[] = +static const char kOpusEndTrimmingHash_3[] = "-13.33,-14.38,-13.68,-11.66,-10.18,-10.49,"; -#endif // defined(ARCH_CPU_32BITS) - -#else // Assume X86 hashes: -constexpr char kOpusEndTrimmingHash_1[] = +static const char kOpusSmallCodecDelayHash_1[] = + "-0.48,-0.09,1.27,1.06,1.54,-0.22,"; +static const char kOpusSmallCodecDelayHash_2[] = + "0.29,0.15,-0.19,0.25,0.68,0.83,"; +static const char kOpusMonoOutputHash[] = "-2.39,-1.66,0.81,1.54,1.48,-0.91,"; +#else +static const char kOpusEndTrimmingHash_1[] = "-4.57,-5.66,-6.52,-6.30,-4.37,-3.61,"; -constexpr char kOpusEndTrimmingHash_2[] = +static const char kOpusEndTrimmingHash_2[] = "-11.91,-11.11,-8.27,-7.13,-7.86,-10.00,"; -constexpr char kOpusEndTrimmingHash_3[] = +static const char kOpusEndTrimmingHash_3[] = "-13.31,-14.38,-13.70,-11.71,-10.21,-10.49,"; -constexpr char kOpusSmallCodecDelayHash_2[] = "0.29,0.14,-0.20,0.24,0.68,0.83,"; -constexpr char kOpusMonoOutputHash[] = "-2.41,-1.66,0.79,1.53,1.46,-0.91,"; -#endif // defined(ARCH_CPU_ARM_FAMILY) +static const char kOpusSmallCodecDelayHash_1[] = + "-0.48,-0.09,1.27,1.06,1.54,-0.22,"; +static const char kOpusSmallCodecDelayHash_2[] = + "0.29,0.14,-0.20,0.24,0.68,0.83,"; +static const char kOpusMonoOutputHash[] = "-2.41,-1.66,0.79,1.53,1.46,-0.91,"; +#endif // defined(ARCH_CPU_ARM64) -#else // Use non-fixed point hashes: +#else // Hash for a full playthrough of "opus-trimming-test.(webm|ogg)". -constexpr char kOpusEndTrimmingHash_1[] = +static const char kOpusEndTrimmingHash_1[] = "-4.57,-5.67,-6.52,-6.28,-4.34,-3.58,"; // The above hash, plus an additional playthrough starting from T=1s. -constexpr char kOpusEndTrimmingHash_2[] = +static const char kOpusEndTrimmingHash_2[] = "-11.91,-11.10,-8.24,-7.08,-7.82,-9.99,"; // The above hash, plus an additional playthrough starting from T=6.36s. -constexpr char kOpusEndTrimmingHash_3[] = +static const char kOpusEndTrimmingHash_3[] = "-13.31,-14.36,-13.66,-11.65,-10.16,-10.47,"; // Hash for a full playthrough of "bear-opus.webm". -constexpr char kOpusSmallCodecDelayHash_1[] = +static const char kOpusSmallCodecDelayHash_1[] = "-0.47,-0.09,1.28,1.07,1.55,-0.22,"; // The above hash, plus an additional playthrough starting from T=1.414s. -constexpr char kOpusSmallCodecDelayHash_2[] = "0.31,0.15,-0.18,0.25,0.70,0.84,"; +static const char kOpusSmallCodecDelayHash_2[] = + "0.31,0.15,-0.18,0.25,0.70,0.84,"; // For BasicPlaybackOpusWebmHashed_MonoOutput test case. -constexpr char kOpusMonoOutputHash[] = "-2.36,-1.64,0.84,1.55,1.51,-0.90,"; +static const char kOpusMonoOutputHash[] = "-2.36,-1.64,0.84,1.55,1.51,-0.90,"; #endif // defined(OPUS_FIXED_POINT) -#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) -constexpr int k1280IsoFileDurationMs = 2736; +#if BUILDFLAG(USE_PROPRIETARY_CODECS) +const int k640IsoCencFileDurationMs = 2769; +const int k1280IsoFileDurationMs = 2736; -constexpr int k1280IsoAVC3FileDurationMs = 2736; +// TODO(wolenetz): Update to 2769 once MSE endOfStream implementation no longer +// truncates duration to the highest in intersection ranges, but compliantly to +// the largest track buffer ranges end time across all tracks and SourceBuffers. +// See https://crbug.com/639144. +const int k1280IsoFileDurationMsAV = 2763; + +const int k1280IsoAVC3FileDurationMs = 2736; #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) // Return a timeline offset for bear-320x240-live.webm. @@ -677,11 +677,11 @@ {"bear-av1.webm", kAppendWholeFile, kVP9WebMFileDurationMs}, #endif // BUILDFLAG(ENABLE_AV1_DECODER) -#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) // H264 AVC3 in MP4 {"bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile, k1280IsoAVC3FileDurationMs}, -#endif +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) }; INSTANTIATE_TEST_SUITE_P( @@ -2181,6 +2181,14 @@ } #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) +TEST_F(PipelineIntegrationTest, BasicPlaybackHi10P) { + ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4")); + + Play(); + + ASSERT_TRUE(WaitUntilOnEnded()); +} + std::vector<std::unique_ptr<VideoDecoder>> CreateFailingVideoDecoder() { std::vector<std::unique_ptr<VideoDecoder>> failing_video_decoder; failing_video_decoder.push_back(std::make_unique<FailingVideoDecoder>()); @@ -2189,7 +2197,7 @@ TEST_F(PipelineIntegrationTest, BasicFallback) { ASSERT_EQ(PIPELINE_OK, - Start("bear.webm", kNormal, + Start("bear.mp4", kNormal, base::BindRepeating(&CreateFailingVideoDecoder))); Play(); @@ -2197,7 +2205,6 @@ ASSERT_TRUE(WaitUntilOnEnded()); } -#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) TEST_F(PipelineIntegrationTest, MSE_ConfigChange_MP4) { TestMediaSource source("bear-640x360-av_frag.mp4", kAppendWholeFile); EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source)); @@ -2218,13 +2225,6 @@ EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); - - // TODO(wolenetz): Update to 2769 once MSE endOfStream implementation no - // longer truncates duration to the highest in intersection ranges, but - // compliantly to the largest track buffer ranges end time across all tracks - // and SourceBuffers. See https://crbug.com/639144. - constexpr int k1280IsoFileDurationMsAV = 2763; - EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMsAV, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); @@ -2336,7 +2336,6 @@ EXPECT_EQ(33, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); // The second video was not added, so its time has not been added. - constexpr int k640IsoCencFileDurationMs = 2769; EXPECT_EQ(k640IsoCencFileDurationMs, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); @@ -2345,13 +2344,6 @@ EXPECT_EQ(CHUNK_DEMUXER_ERROR_APPEND_FAILED, WaitUntilEndedOrError()); source.Shutdown(); } -#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - -TEST_F(PipelineIntegrationTest, StereoAACMarkedAsMono) { - ASSERT_EQ(PIPELINE_OK, Start("mono_cpe.adts")); - Play(); - ASSERT_TRUE(WaitUntilOnEnded()); -} #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) // Verify files which change configuration midstream fail gracefully. @@ -2446,7 +2438,6 @@ } #if BUILDFLAG(USE_PROPRIETARY_CODECS) -#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_VideoOnly) { TestMediaSource source("bear-1280x720-v_frag-cenc.mp4", kAppendWholeFile); FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); @@ -2463,6 +2454,22 @@ Stop(); } +TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_AudioOnly) { + TestMediaSource source("bear-1280x720-a_frag-cenc.mp4", kAppendWholeFile); + FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); + EXPECT_EQ(PIPELINE_OK, + StartPipelineWithEncryptedMedia(&source, &encrypted_media)); + + source.EndOfStream(); + ASSERT_EQ(PIPELINE_OK, pipeline_status_); + + Play(); + + ASSERT_TRUE(WaitUntilOnEnded()); + source.Shutdown(); + Stop(); +} + TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_NoEncryptedFrames_MP4_CENC_VideoOnly) { TestMediaSource source("bear-1280x720-v_frag-cenc_clear-all.mp4", @@ -2499,24 +2506,6 @@ #endif } -#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - -TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_AudioOnly) { - TestMediaSource source("bear-1280x720-a_frag-cenc.mp4", kAppendWholeFile); - FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); - EXPECT_EQ(PIPELINE_OK, - StartPipelineWithEncryptedMedia(&source, &encrypted_media)); - - source.EndOfStream(); - ASSERT_EQ(PIPELINE_OK, pipeline_status_); - - Play(); - - ASSERT_TRUE(WaitUntilOnEnded()); - source.Shutdown(); - Stop(); -} - TEST_F(PipelineIntegrationTest, MSE_Mpeg2ts_MP3Audio_Mp4a_6B) { TestMediaSource source("bear-audio-mp4a.6B.ts", "video/mp2t; codecs=\"mp4a.6B\"", kAppendWholeFile); @@ -2562,8 +2551,6 @@ Stop(); } -#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - // Older packagers saved sample encryption auxiliary information in the // beginning of mdat box. TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_MDAT_Video) { @@ -2635,24 +2622,6 @@ Stop(); } -TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_AVC3) { - TestMediaSource source("bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile); - EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source)); - source.EndOfStream(); - - EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); - EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); - EXPECT_EQ(k1280IsoAVC3FileDurationMs, - pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); - - Play(); - - ASSERT_TRUE(WaitUntilOnEnded()); - source.Shutdown(); - Stop(); -} -#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_KeyRotation_Audio) { TestMediaSource source("bear-1280x720-a_frag-cenc-key_rotation.mp4", @@ -2670,6 +2639,23 @@ Stop(); } +TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_AVC3) { + TestMediaSource source("bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile); + EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source)); + source.EndOfStream(); + + EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); + EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); + EXPECT_EQ(k1280IsoAVC3FileDurationMs, + pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); + + Play(); + + ASSERT_TRUE(WaitUntilOnEnded()); + source.Shutdown(); + Stop(); +} + TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_HEVC) { // HEVC demuxing might be enabled even on platforms that don't support HEVC // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which @@ -2806,6 +2792,45 @@ ASSERT_TRUE(WaitUntilOnEnded()); } +#if BUILDFLAG(USE_PROPRIETARY_CODECS) +TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) { + ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4")); + ASSERT_EQ(VIDEO_ROTATION_0, + metadata_.video_decoder_config.video_transformation().rotation); +} + +TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) { + ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4")); + ASSERT_EQ(VIDEO_ROTATION_90, + metadata_.video_decoder_config.video_transformation().rotation); +} + +TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) { + ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4")); + ASSERT_EQ(VIDEO_ROTATION_180, + metadata_.video_decoder_config.video_transformation().rotation); +} + +TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) { + ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4")); + ASSERT_EQ(VIDEO_ROTATION_270, + metadata_.video_decoder_config.video_transformation().rotation); +} + +TEST_F(PipelineIntegrationTest, Spherical) { + ASSERT_EQ(PIPELINE_OK, Start("spherical.mp4", kHashed)); + Play(); + ASSERT_TRUE(WaitUntilOnEnded()); + EXPECT_HASH_EQ("1cb7f980020d99ea852e22dd6bd8d9de", GetVideoHash()); +} + +TEST_F(PipelineIntegrationTest, StereoAACMarkedAsMono) { + ASSERT_EQ(PIPELINE_OK, Start("mono_cpe.adts")); + Play(); + ASSERT_TRUE(WaitUntilOnEnded()); +} +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) + // Verify audio decoder & renderer can handle aborted demuxer reads. TEST_F(PipelineIntegrationTest, MSE_ChunkDemuxerAbortRead_AudioOnly) { ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", 16384, @@ -2919,6 +2944,17 @@ gfx::ColorSpace::CreateREC709()); } +#if BUILDFLAG(USE_PROPRIETARY_CODECS) +// Verify that full-range H264 video has the right color space. +TEST_F(PipelineIntegrationTest, Fullrange_H264) { + ASSERT_EQ(PIPELINE_OK, Start("blackwhite_yuvj420p.mp4")); + Play(); + ASSERT_TRUE(WaitUntilOnEnded()); + EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_, + gfx::ColorSpace::CreateJpeg()); +} +#endif + TEST_F(PipelineIntegrationTest, HD_VP9_WebM) { ASSERT_EQ(PIPELINE_OK, Start("bear-1280x720.webm")); Play(); @@ -2973,15 +3009,6 @@ ASSERT_TRUE(WaitUntilOnEnded()); } -TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { - ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); - Play(); - ASSERT_TRUE(WaitUntilOnEnded()); - ASSERT_EQ(base::Microseconds(396000), demuxer_->GetStartTime()); -} - -#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - // Ensures audio-video playback with missing or negative timestamps fails // instead of crashing. See http://crbug.com/396864. TEST_F(PipelineIntegrationTest, BasicPlaybackChainedOggVideo) { @@ -3009,55 +3036,11 @@ ASSERT_TRUE(WaitUntilOnEnded()); } -#if BUILDFLAG(USE_PROPRIETARY_CODECS) -TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) { - ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4")); - ASSERT_EQ(VIDEO_ROTATION_0, - metadata_.video_decoder_config.video_transformation().rotation); -} - -TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) { - ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4")); - ASSERT_EQ(VIDEO_ROTATION_90, - metadata_.video_decoder_config.video_transformation().rotation); -} - -TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) { - ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4")); - ASSERT_EQ(VIDEO_ROTATION_180, - metadata_.video_decoder_config.video_transformation().rotation); -} - -TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) { - ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4")); - ASSERT_EQ(VIDEO_ROTATION_270, - metadata_.video_decoder_config.video_transformation().rotation); -} - -TEST_F(PipelineIntegrationTest, Spherical) { - ASSERT_EQ(PIPELINE_OK, Start("spherical.mp4", kHashed)); +TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { + ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); Play(); ASSERT_TRUE(WaitUntilOnEnded()); - EXPECT_HASH_EQ("1cb7f980020d99ea852e22dd6bd8d9de", GetVideoHash()); + ASSERT_EQ(base::Microseconds(396000), demuxer_->GetStartTime()); } -TEST_F(PipelineIntegrationTest, BasicPlaybackHi10P) { - ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4")); - - Play(); - - ASSERT_TRUE(WaitUntilOnEnded()); -} - -// Verify that full-range H264 video has the right color space. -TEST_F(PipelineIntegrationTest, Fullrange_H264) { - ASSERT_EQ(PIPELINE_OK, Start("blackwhite_yuvj420p.mp4")); - Play(); - ASSERT_TRUE(WaitUntilOnEnded()); - EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_, - gfx::ColorSpace::CreateJpeg()); -} -#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) -#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - } // namespace media
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h index 052e4107..9520da44 100644 --- a/mojo/public/cpp/bindings/interface_endpoint_client.h +++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -343,7 +343,7 @@ internal::ControlMessageProxy control_message_proxy_{this}; internal::ControlMessageHandler control_message_handler_; - const char* interface_name_; + const char* const interface_name_; const MessageToMethodInfoCallback method_info_callback_; const MessageToMethodNameCallback method_name_callback_;
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc index 6802bc1d1..8a83521c 100644 --- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc +++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -459,6 +459,7 @@ interface_name_(interface_name), method_info_callback_(method_info_callback), method_name_callback_(method_name_callback) { + DCHECK(interface_name_); DCHECK(handle_.is_valid()); sequence_checker_.DetachFromSequence(); @@ -715,11 +716,7 @@ return; encountered_error_ = true; - // TODO(dcheng): interface_name_ *should* never be null, but for the purposes - // of not introducing a new crash in code intended to help debug crashes, do a - // null check for safety. - DEBUG_ALIAS_FOR_CSTR(interface_name, interface_name_ ? interface_name_ : "", - 256); + DEBUG_ALIAS_FOR_CSTR(interface_name, interface_name_, 256); // Response callbacks may hold on to resource, and there's no need to keep // them alive any longer. Note that it's allowed that a pending response
diff --git a/net/cookies/cookie_store_change_unittest.h b/net/cookies/cookie_store_change_unittest.h index a1b06fc5..be89df1 100644 --- a/net/cookies/cookie_store_change_unittest.h +++ b/net/cookies/cookie_store_change_unittest.h
@@ -1780,16 +1780,14 @@ "__Host-b=2; Secure; Path=/; Partitioned", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com"))); // Partitioned cookie with a different partition key this->CreateAndSetCookie( cs, GURL("https://www.example.com"), "__Host-c=3; Secure; Path=/; Partitioned", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"))); this->DeliverChangeNotifications(); ASSERT_EQ(2u, cookie_changes.size()); @@ -1817,8 +1815,7 @@ "__Host-b=2; Secure; Path=/; Partitioned; Max-Age=7200", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"))); this->DeliverChangeNotifications(); ASSERT_EQ(0u, other_cookie_changes.size()); // Check that the other listener was invoked. @@ -3067,16 +3064,14 @@ "__Host-a=2; Secure; Path=/; Partitioned", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com"))); // Partitioned cookie with a different partition key this->CreateAndSetCookie( cs, GURL("https://www.example.com"), "__Host-a=3; Secure; Path=/; Partitioned", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"))); this->DeliverChangeNotifications(); ASSERT_EQ(2u, cookie_changes.size()); @@ -3103,8 +3098,7 @@ "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200", CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */, absl::nullopt /* system_time */, - absl::make_optional( - CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")))); + CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"))); this->DeliverChangeNotifications(); ASSERT_EQ(0u, other_cookie_changes.size()); // Check that the other listener was invoked.
diff --git a/net/url_request/url_request_test_job.cc b/net/url_request/url_request_test_job.cc index 4fc0612..10be229 100644 --- a/net/url_request/url_request_test_job.cc +++ b/net/url_request/url_request_test_job.cc
@@ -287,7 +287,7 @@ stage_ = DATA_AVAILABLE; // OK if ReadRawData wasn't called yet. if (async_buf_) { - int result = CopyDataForRead(async_buf_, async_buf_size_); + int result = CopyDataForRead(async_buf_.get(), async_buf_size_); if (result < 0) NOTREACHED() << "Reads should not fail in DATA_AVAILABLE."; if (NextReadAsync()) {
diff --git a/net/url_request/url_request_test_job.h b/net/url_request/url_request_test_job.h index d464244f..a144685e9 100644 --- a/net/url_request/url_request_test_job.h +++ b/net/url_request/url_request_test_job.h
@@ -173,7 +173,7 @@ int offset_ = 0; // Holds the buffer for an asynchronous ReadRawData call - raw_ptr<IOBuffer> async_buf_ = nullptr; + scoped_refptr<IOBuffer> async_buf_; int async_buf_size_ = 0; LoadTimingInfo load_timing_info_;
diff --git a/remoting/client/notification/notification_client.cc b/remoting/client/notification/notification_client.cc index 96ae833..94fbe60 100644 --- a/remoting/client/notification/notification_client.cc +++ b/remoting/client/notification/notification_client.cc
@@ -214,13 +214,20 @@ } if (done_ && is_message_translation_fetched_ && is_link_translation_fetched_) { - std::move(done_).Run(true); + RunDoneCallback(true); } } void NotifyFetchFailed() { DCHECK(done_); - std::move(done_).Run(false); + RunDoneCallback(false); + } + + void RunDoneCallback(bool arg) { + // Drop unowned resources before invoking callback destroying them. + out_link_translation_ = nullptr; + out_message_translation_ = nullptr; + std::move(done_).Run(arg); } std::string locale_;
diff --git a/remoting/client/notification/notification_client_unittest.cc b/remoting/client/notification/notification_client_unittest.cc index 5fa22f3f..671b2060 100644 --- a/remoting/client/notification/notification_client_unittest.cc +++ b/remoting/client/notification/notification_client_unittest.cc
@@ -106,8 +106,8 @@ test_locale, should_ignore_dev_messages)); } - raw_ptr<MockJsonFetcher> fetcher_; std::unique_ptr<NotificationClient> client_; + raw_ptr<MockJsonFetcher> fetcher_; // Owned by `client_`. }; TEST_F(NotificationClientTest, NoRule) { @@ -438,4 +438,4 @@ client_->GetNotification(/* user_email= */ "", callback.Get()); } -} // namespace remoting \ No newline at end of file +} // namespace remoting
diff --git a/testing/buildbot/chrome.gpu.fyi.json b/testing/buildbot/chrome.gpu.fyi.json new file mode 100644 index 0000000..b881060b --- /dev/null +++ b/testing/buildbot/chrome.gpu.fyi.json
@@ -0,0 +1,652 @@ +{ + "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, + "AAAAA2 See generate_buildbot_json.py to make changes": {}, + "Lacros FYI Release (eve)": { + "additional_compile_targets": [ + "chrome" + ], + "isolated_scripts": [ + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_passthrough_test Ash ToT", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_passthrough_test Ash ToT", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "webgl2_conformance", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json", + "--jobs=1", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_gles_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "eve", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + } + ] + }, + "Lacros FYI Release (jacuzzi)": { + "additional_compile_targets": [ + "chrome" + ], + "isolated_scripts": [ + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_passthrough_test Ash ToT", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_passthrough_test Ash ToT", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + }, + { + "args": [ + "webgl2_conformance", + "--show-stdout", + "--browser=lacros-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json", + "--jobs=1", + "--deploy-lacros", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_gles_passthrough_tests Ash ToT", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "device_type": "jacuzzi", + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/", + "trigger_script": { + "script": "//testing/trigger_scripts/chromeos_device_trigger.py" + }, + "variant_id": "Ash ToT" + } + ] + } +}
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index d4a03a0..6451ab75 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -1555,7 +1555,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "octopus", - "cros_img": "octopus-release/R114-15419.0.0", + "cros_img": "octopus-release/R114-15408.0.0", "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM", "shards": 10, "swarming": {}, @@ -1794,7 +1794,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R114-15419.0.0", + "cros_img": "dedede-release/R114-15410.0.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1811,7 +1811,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R114-15416.0.0", + "cros_img": "dedede-release/R113-15393.12.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_DEV", "resultdb": { "enable": true, @@ -1828,7 +1828,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R113-15393.12.0", + "cros_img": "dedede-release/R112-15359.37.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_BETA", "resultdb": { "enable": true, @@ -1862,7 +1862,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R114-15419.0.0", + "cros_img": "eve-release/R114-15410.0.0", "name": "lacros_all_tast_tests EVE_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1879,7 +1879,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R114-15416.0.0", + "cros_img": "eve-release/R113-15393.12.0", "name": "lacros_all_tast_tests EVE_RELEASE_DEV", "resultdb": { "enable": true, @@ -1896,7 +1896,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R113-15393.12.0", + "cros_img": "eve-release/R112-15359.37.0", "name": "lacros_all_tast_tests EVE_RELEASE_BETA", "resultdb": { "enable": true, @@ -1913,7 +1913,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R112-15359.45.0", + "cros_img": "eve-release/R111-15329.59.0", "name": "lacros_all_tast_tests EVE_RELEASE_STABLE", "resultdb": { "enable": true, @@ -1965,7 +1965,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R114-15419.0.0", + "cros_img": "jacuzzi-release/R114-15410.0.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1982,7 +1982,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R114-15416.0.0", + "cros_img": "jacuzzi-release/R113-15393.12.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_DEV", "resultdb": { "enable": true, @@ -1999,7 +1999,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R113-15393.12.0", + "cros_img": "jacuzzi-release/R112-15359.37.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_BETA", "resultdb": { "enable": true, @@ -2016,7 +2016,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R112-15359.45.0", + "cros_img": "jacuzzi-release/R111-15329.59.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_STABLE", "resultdb": { "enable": true, @@ -2068,7 +2068,7 @@ { "args": [], "cros_board": "herobrine", - "cros_img": "herobrine-release/R114-15419.0.0", + "cros_img": "herobrine-release/R114-15410.0.0", "name": "lacros_all_tast_tests HEROBRINE_RELEASE_LKGM", "resultdb": { "enable": true,
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json index ff2353e..97ceb06a 100644 --- a/testing/buildbot/chromium.angle.json +++ b/testing/buildbot/chromium.angle.json
@@ -82,7 +82,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "containment_type": "AUTO", @@ -139,7 +139,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "containment_type": "AUTO",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index b5bf0b66..567cc76d 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1620,7 +1620,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15419.0.0", + "cros_img": "jacuzzi-public/R114-15410.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -1650,7 +1650,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15419.0.0", + "cros_img": "kevin64-public/R114-15410.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -5618,9 +5618,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5631,8 +5631,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -5783,9 +5783,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5796,8 +5796,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -5930,9 +5930,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5943,8 +5943,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 5a3dc4be..be5168b 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -38447,7 +38447,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38498,7 +38498,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38549,7 +38549,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38600,7 +38600,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38651,7 +38651,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38702,7 +38702,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38753,7 +38753,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38804,7 +38804,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38855,7 +38855,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38906,7 +38906,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -38957,7 +38957,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39008,7 +39008,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39059,7 +39059,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39110,7 +39110,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39161,7 +39161,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39212,7 +39212,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39263,7 +39263,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39314,7 +39314,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39385,7 +39385,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39431,7 +39431,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39477,7 +39477,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39523,7 +39523,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39569,7 +39569,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39615,7 +39615,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39661,7 +39661,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39707,7 +39707,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39753,7 +39753,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39799,7 +39799,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39845,7 +39845,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39891,7 +39891,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39937,7 +39937,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -39983,7 +39983,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -40029,7 +40029,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -40075,7 +40075,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -40121,7 +40121,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -40167,7 +40167,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index d697c5b6..66caf37 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -10033,7 +10033,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10086,7 +10086,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10139,7 +10139,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10192,7 +10192,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10245,7 +10245,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10298,7 +10298,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10351,7 +10351,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10404,7 +10404,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10457,7 +10457,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10510,7 +10510,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10563,7 +10563,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10616,7 +10616,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10669,7 +10669,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10722,7 +10722,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10775,7 +10775,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10828,7 +10828,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10881,7 +10881,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10934,7 +10934,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10987,7 +10987,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11040,7 +11040,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11093,7 +11093,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11146,7 +11146,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11199,7 +11199,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11252,7 +11252,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11305,7 +11305,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11358,7 +11358,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11411,7 +11411,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11464,7 +11464,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11517,7 +11517,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11570,7 +11570,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11623,7 +11623,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11676,7 +11676,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11729,7 +11729,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11782,7 +11782,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11835,7 +11835,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11888,7 +11888,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11941,7 +11941,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11994,7 +11994,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12047,7 +12047,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12100,7 +12100,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12153,7 +12153,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12206,7 +12206,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12260,7 +12260,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12314,7 +12314,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12368,7 +12368,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12422,7 +12422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12476,7 +12476,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12530,7 +12530,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12584,7 +12584,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12638,7 +12638,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12692,7 +12692,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12747,7 +12747,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12802,7 +12802,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12857,7 +12857,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12912,7 +12912,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12967,7 +12967,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13022,7 +13022,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13077,7 +13077,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13132,7 +13132,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13187,7 +13187,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13242,7 +13242,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13297,7 +13297,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13352,7 +13352,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13407,7 +13407,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13462,7 +13462,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13517,7 +13517,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13572,7 +13572,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13627,7 +13627,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13682,7 +13682,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13737,7 +13737,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13792,7 +13792,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13847,7 +13847,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13902,7 +13902,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13957,7 +13957,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14012,7 +14012,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14066,7 +14066,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14120,7 +14120,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14174,7 +14174,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14228,7 +14228,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14282,7 +14282,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14336,7 +14336,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14390,7 +14390,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14444,7 +14444,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14499,7 +14499,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14554,7 +14554,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14609,7 +14609,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14664,7 +14664,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14719,7 +14719,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14774,7 +14774,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14829,7 +14829,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14883,7 +14883,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14936,7 +14936,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14989,7 +14989,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15042,7 +15042,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15095,7 +15095,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15148,7 +15148,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15201,7 +15201,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15254,7 +15254,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15307,7 +15307,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15360,7 +15360,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15414,7 +15414,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15469,7 +15469,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15524,7 +15524,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15579,7 +15579,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15634,7 +15634,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15689,7 +15689,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15744,7 +15744,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15799,7 +15799,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15853,7 +15853,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15906,7 +15906,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15959,7 +15959,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16013,7 +16013,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16067,7 +16067,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16120,7 +16120,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16174,7 +16174,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16228,7 +16228,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16282,7 +16282,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16336,7 +16336,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16390,7 +16390,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16444,7 +16444,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16498,7 +16498,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16552,7 +16552,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16605,7 +16605,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16658,7 +16658,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16711,7 +16711,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16764,7 +16764,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16817,7 +16817,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16870,7 +16870,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16923,7 +16923,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16976,7 +16976,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17029,7 +17029,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17082,7 +17082,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17135,7 +17135,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17188,7 +17188,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17242,7 +17242,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17296,7 +17296,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17350,7 +17350,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17404,7 +17404,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17458,7 +17458,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17512,7 +17512,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17566,7 +17566,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17620,7 +17620,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17673,7 +17673,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17726,7 +17726,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17779,7 +17779,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17832,7 +17832,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17885,7 +17885,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17938,7 +17938,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17991,7 +17991,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18044,7 +18044,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18097,7 +18097,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18150,7 +18150,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18203,7 +18203,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18256,7 +18256,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18309,7 +18309,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18362,7 +18362,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18415,7 +18415,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18468,7 +18468,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18521,7 +18521,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18574,7 +18574,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18627,7 +18627,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18680,7 +18680,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18733,7 +18733,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18786,7 +18786,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18839,7 +18839,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18892,7 +18892,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18945,7 +18945,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18998,7 +18998,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19051,7 +19051,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19104,7 +19104,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19157,7 +19157,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19210,7 +19210,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19263,7 +19263,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19316,7 +19316,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19369,7 +19369,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19422,7 +19422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19475,7 +19475,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19528,7 +19528,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19581,7 +19581,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19634,7 +19634,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19687,7 +19687,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19740,7 +19740,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19793,7 +19793,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19846,7 +19846,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19899,7 +19899,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19952,7 +19952,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20005,7 +20005,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20058,7 +20058,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20111,7 +20111,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20164,7 +20164,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20217,7 +20217,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20270,7 +20270,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20323,7 +20323,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20376,7 +20376,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20429,7 +20429,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20482,7 +20482,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20535,7 +20535,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20588,7 +20588,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20641,7 +20641,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20694,7 +20694,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25212,9 +25212,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25225,8 +25225,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -25377,9 +25377,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25390,8 +25390,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -25524,9 +25524,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25537,8 +25537,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index ffa5ac6..7e2b986 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -5841,7 +5841,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5892,7 +5892,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5943,7 +5943,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5995,7 +5995,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6047,7 +6047,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6098,7 +6098,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6149,7 +6149,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6200,7 +6200,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6251,7 +6251,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6302,7 +6302,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6353,7 +6353,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6404,7 +6404,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6455,7 +6455,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6506,7 +6506,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6557,7 +6557,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6608,7 +6608,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6659,7 +6659,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6710,7 +6710,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6761,7 +6761,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6812,7 +6812,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6863,7 +6863,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6914,7 +6914,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -6965,7 +6965,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7016,7 +7016,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7067,7 +7067,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7118,7 +7118,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7169,7 +7169,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7220,7 +7220,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7271,7 +7271,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7322,7 +7322,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7373,7 +7373,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7424,7 +7424,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7475,7 +7475,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7526,7 +7526,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7577,7 +7577,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7628,7 +7628,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7679,7 +7679,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7730,7 +7730,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7781,7 +7781,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7832,7 +7832,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7883,7 +7883,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7934,7 +7934,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -7985,7 +7985,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8036,7 +8036,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8087,7 +8087,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8138,7 +8138,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8189,7 +8189,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8240,7 +8240,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8291,7 +8291,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8342,7 +8342,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8393,7 +8393,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8444,7 +8444,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8495,7 +8495,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8546,7 +8546,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8597,7 +8597,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8648,7 +8648,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8699,7 +8699,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8750,7 +8750,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8801,7 +8801,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8852,7 +8852,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8903,7 +8903,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -8954,7 +8954,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9005,7 +9005,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9056,7 +9056,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9107,7 +9107,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9158,7 +9158,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9209,7 +9209,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9260,7 +9260,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9311,7 +9311,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9362,7 +9362,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9413,7 +9413,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9464,7 +9464,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9515,7 +9515,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9566,7 +9566,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9617,7 +9617,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9668,7 +9668,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9719,7 +9719,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9770,7 +9770,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9821,7 +9821,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9872,7 +9872,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9923,7 +9923,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -9974,7 +9974,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10025,7 +10025,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10076,7 +10076,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10127,7 +10127,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10178,7 +10178,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10229,7 +10229,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10280,7 +10280,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10331,7 +10331,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10382,7 +10382,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10433,7 +10433,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10484,7 +10484,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10535,7 +10535,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10586,7 +10586,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10637,7 +10637,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10688,7 +10688,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10745,7 +10745,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10799,7 +10799,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10853,7 +10853,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10908,7 +10908,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10963,7 +10963,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11018,7 +11018,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11073,7 +11073,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11128,7 +11128,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11183,7 +11183,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11237,7 +11237,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11291,7 +11291,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11346,7 +11346,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11401,7 +11401,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11456,7 +11456,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11511,7 +11511,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11565,7 +11565,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11619,7 +11619,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11673,7 +11673,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11732,7 +11732,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11783,7 +11783,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11834,7 +11834,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11885,7 +11885,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11936,7 +11936,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11987,7 +11987,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12038,7 +12038,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12089,7 +12089,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12140,7 +12140,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12191,7 +12191,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12242,7 +12242,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12293,7 +12293,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12344,7 +12344,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12395,7 +12395,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12446,7 +12446,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12497,7 +12497,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12548,7 +12548,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12599,7 +12599,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12653,7 +12653,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12707,7 +12707,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12761,7 +12761,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12815,7 +12815,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12870,7 +12870,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12925,7 +12925,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12980,7 +12980,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13035,7 +13035,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13090,7 +13090,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13145,7 +13145,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13200,7 +13200,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13255,7 +13255,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13310,7 +13310,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13365,7 +13365,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13419,7 +13419,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13473,7 +13473,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13527,7 +13527,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13582,7 +13582,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13637,7 +13637,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13689,7 +13689,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13740,7 +13740,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13791,7 +13791,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13842,7 +13842,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13896,7 +13896,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13951,7 +13951,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14006,7 +14006,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14058,7 +14058,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14109,7 +14109,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14161,7 +14161,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14215,7 +14215,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14269,7 +14269,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14323,7 +14323,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14374,7 +14374,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14425,7 +14425,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14476,7 +14476,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14527,7 +14527,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14578,7 +14578,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14632,7 +14632,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14686,7 +14686,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14740,7 +14740,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14794,7 +14794,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14845,7 +14845,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14896,7 +14896,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14947,7 +14947,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14998,7 +14998,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15049,7 +15049,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15100,7 +15100,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15151,7 +15151,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15202,7 +15202,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15253,7 +15253,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15304,7 +15304,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15355,7 +15355,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15406,7 +15406,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15457,7 +15457,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15508,7 +15508,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15559,7 +15559,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15610,7 +15610,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15661,7 +15661,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15712,7 +15712,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15763,7 +15763,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15814,7 +15814,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15865,7 +15865,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15916,7 +15916,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15967,7 +15967,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16018,7 +16018,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16073,7 +16073,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16128,7 +16128,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16183,7 +16183,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16234,7 +16234,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16285,7 +16285,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16336,7 +16336,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16387,7 +16387,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16438,7 +16438,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16489,7 +16489,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16540,7 +16540,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16591,7 +16591,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16643,7 +16643,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16695,7 +16695,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16748,7 +16748,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16801,7 +16801,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16854,7 +16854,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16906,7 +16906,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16958,7 +16958,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17010,7 +17010,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17062,7 +17062,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17113,7 +17113,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17165,7 +17165,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17217,7 +17217,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17268,7 +17268,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17319,7 +17319,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17371,7 +17371,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17422,7 +17422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17473,7 +17473,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17524,7 +17524,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17575,7 +17575,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17626,7 +17626,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17677,7 +17677,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17728,7 +17728,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17779,7 +17779,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17830,7 +17830,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17887,7 +17887,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17940,7 +17940,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17993,7 +17993,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18046,7 +18046,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18099,7 +18099,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18152,7 +18152,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18205,7 +18205,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18258,7 +18258,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18311,7 +18311,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18364,7 +18364,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18417,7 +18417,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18470,7 +18470,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18523,7 +18523,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18576,7 +18576,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18629,7 +18629,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18682,7 +18682,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18735,7 +18735,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18788,7 +18788,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18842,7 +18842,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18896,7 +18896,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18950,7 +18950,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19005,7 +19005,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19060,7 +19060,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19115,7 +19115,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19170,7 +19170,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19225,7 +19225,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19280,7 +19280,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19334,7 +19334,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19388,7 +19388,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19443,7 +19443,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19497,7 +19497,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19550,7 +19550,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19604,7 +19604,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19659,7 +19659,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19713,7 +19713,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19766,7 +19766,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19819,7 +19819,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19873,7 +19873,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19927,7 +19927,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19980,7 +19980,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20034,7 +20034,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20088,7 +20088,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20141,7 +20141,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20194,7 +20194,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20247,7 +20247,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20300,7 +20300,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20354,7 +20354,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20408,7 +20408,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20461,7 +20461,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20514,7 +20514,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20567,7 +20567,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20620,7 +20620,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20673,7 +20673,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20726,7 +20726,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20779,7 +20779,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20832,7 +20832,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20885,7 +20885,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20938,7 +20938,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20991,7 +20991,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21044,7 +21044,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21097,7 +21097,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21150,7 +21150,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21203,7 +21203,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21256,7 +21256,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21309,7 +21309,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21362,7 +21362,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21417,7 +21417,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21483,7 +21483,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21534,7 +21534,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21585,7 +21585,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21636,7 +21636,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21687,7 +21687,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21738,7 +21738,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21789,7 +21789,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21840,7 +21840,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21891,7 +21891,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21942,7 +21942,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -21993,7 +21993,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22044,7 +22044,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22095,7 +22095,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22146,7 +22146,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22197,7 +22197,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22248,7 +22248,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22299,7 +22299,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22350,7 +22350,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22404,7 +22404,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22458,7 +22458,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22512,7 +22512,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22566,7 +22566,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22620,7 +22620,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22675,7 +22675,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22730,7 +22730,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22785,7 +22785,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22840,7 +22840,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22895,7 +22895,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -22950,7 +22950,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23005,7 +23005,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23060,7 +23060,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23115,7 +23115,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23170,7 +23170,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23225,7 +23225,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23279,7 +23279,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23333,7 +23333,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23387,7 +23387,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23441,7 +23441,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23496,7 +23496,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23551,7 +23551,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23606,7 +23606,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23658,7 +23658,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23709,7 +23709,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23760,7 +23760,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23811,7 +23811,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23865,7 +23865,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23920,7 +23920,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -23975,7 +23975,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24030,7 +24030,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24082,7 +24082,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24134,7 +24134,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24185,7 +24185,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24237,7 +24237,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24291,7 +24291,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24345,7 +24345,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24399,7 +24399,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24453,7 +24453,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24505,7 +24505,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24557,7 +24557,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24608,7 +24608,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24659,7 +24659,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24710,7 +24710,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24761,7 +24761,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24812,7 +24812,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24866,7 +24866,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24920,7 +24920,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -24974,7 +24974,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25025,7 +25025,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25076,7 +25076,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25127,7 +25127,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25178,7 +25178,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25229,7 +25229,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25280,7 +25280,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25331,7 +25331,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25382,7 +25382,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25433,7 +25433,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25484,7 +25484,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25535,7 +25535,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25586,7 +25586,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25637,7 +25637,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25688,7 +25688,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25739,7 +25739,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25790,7 +25790,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25841,7 +25841,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25892,7 +25892,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25943,7 +25943,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -25994,7 +25994,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26045,7 +26045,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26096,7 +26096,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26147,7 +26147,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26198,7 +26198,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26263,7 +26263,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26316,7 +26316,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26369,7 +26369,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26422,7 +26422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26475,7 +26475,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26528,7 +26528,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26581,7 +26581,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26634,7 +26634,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26687,7 +26687,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26740,7 +26740,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26793,7 +26793,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26846,7 +26846,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26899,7 +26899,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -26952,7 +26952,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27005,7 +27005,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27058,7 +27058,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27111,7 +27111,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27164,7 +27164,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27218,7 +27218,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27272,7 +27272,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27326,7 +27326,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27380,7 +27380,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27435,7 +27435,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27490,7 +27490,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27545,7 +27545,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27600,7 +27600,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27655,7 +27655,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27710,7 +27710,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27765,7 +27765,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27820,7 +27820,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27875,7 +27875,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27929,7 +27929,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -27983,7 +27983,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28037,7 +28037,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28092,7 +28092,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28147,7 +28147,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28201,7 +28201,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28254,7 +28254,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28307,7 +28307,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28360,7 +28360,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28414,7 +28414,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28469,7 +28469,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28524,7 +28524,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28578,7 +28578,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28632,7 +28632,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28685,7 +28685,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28739,7 +28739,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28793,7 +28793,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28847,7 +28847,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28901,7 +28901,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -28955,7 +28955,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29009,7 +29009,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29062,7 +29062,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29115,7 +29115,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29168,7 +29168,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29221,7 +29221,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29274,7 +29274,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29328,7 +29328,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29382,7 +29382,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29436,7 +29436,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29489,7 +29489,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29542,7 +29542,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29595,7 +29595,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29648,7 +29648,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29701,7 +29701,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29754,7 +29754,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29807,7 +29807,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29860,7 +29860,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29913,7 +29913,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -29966,7 +29966,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30019,7 +30019,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30072,7 +30072,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30125,7 +30125,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30178,7 +30178,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30231,7 +30231,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30284,7 +30284,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30337,7 +30337,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30390,7 +30390,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30443,7 +30443,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30496,7 +30496,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30549,7 +30549,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30602,7 +30602,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30655,7 +30655,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -30708,7 +30708,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -31093,7 +31093,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "octopus", - "cros_img": "octopus-public/R114-15419.0.0", + "cros_img": "octopus-public/R114-15410.0.0", "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31111,7 +31111,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "eve", - "cros_img": "eve-public/R114-15419.0.0", + "cros_img": "eve-public/R114-15410.0.0", "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31136,7 +31136,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15419.0.0", + "cros_img": "jacuzzi-public/R114-15410.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31154,7 +31154,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15419.0.0", + "cros_img": "kevin64-public/R114-15410.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31179,7 +31179,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15419.0.0", + "cros_img": "jacuzzi-public/R114-15410.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31197,7 +31197,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15419.0.0", + "cros_img": "jacuzzi-public/R114-15410.0.0", "name": "lacros_all_tast_tests JACUZZI_CQ_PUBLIC_LKGM", "public_builder": "cros_test_platform_public", "public_builder_bucket": "testplatform-public", @@ -31217,7 +31217,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15419.0.0", + "cros_img": "kevin64-public/R114-15410.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -33946,9 +33946,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -33958,8 +33958,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -34111,9 +34111,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34123,8 +34123,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -34258,9 +34258,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34270,8 +34270,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -35698,9 +35698,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -35710,8 +35710,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -35863,9 +35863,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -35875,8 +35875,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -36010,9 +36010,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -36022,8 +36022,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -36739,9 +36739,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -36751,8 +36751,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 117c17eb9..6650242 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -10440,7 +10440,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10493,7 +10493,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10546,7 +10546,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10599,7 +10599,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10652,7 +10652,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10705,7 +10705,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10758,7 +10758,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10811,7 +10811,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10864,7 +10864,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10917,7 +10917,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10970,7 +10970,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11023,7 +11023,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11077,7 +11077,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11131,7 +11131,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11184,7 +11184,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11237,7 +11237,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11290,7 +11290,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11344,7 +11344,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11397,7 +11397,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11450,7 +11450,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11503,7 +11503,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11557,7 +11557,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11610,7 +11610,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11663,7 +11663,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11716,7 +11716,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11769,7 +11769,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11822,7 +11822,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11875,7 +11875,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11928,7 +11928,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11981,7 +11981,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12034,7 +12034,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12087,7 +12087,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12140,7 +12140,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12193,7 +12193,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12246,7 +12246,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12299,7 +12299,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12359,7 +12359,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12412,7 +12412,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12465,7 +12465,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12518,7 +12518,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12571,7 +12571,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12624,7 +12624,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12677,7 +12677,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12730,7 +12730,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12783,7 +12783,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12836,7 +12836,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12889,7 +12889,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12942,7 +12942,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12995,7 +12995,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13048,7 +13048,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13101,7 +13101,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13154,7 +13154,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13207,7 +13207,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13260,7 +13260,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13314,7 +13314,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13368,7 +13368,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13422,7 +13422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13476,7 +13476,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13530,7 +13530,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13585,7 +13585,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13640,7 +13640,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13695,7 +13695,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13750,7 +13750,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13805,7 +13805,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13860,7 +13860,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13915,7 +13915,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13970,7 +13970,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14025,7 +14025,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14080,7 +14080,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14135,7 +14135,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14190,7 +14190,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14244,7 +14244,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14298,7 +14298,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14352,7 +14352,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14406,7 +14406,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14461,7 +14461,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14516,7 +14516,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14571,7 +14571,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14625,7 +14625,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14678,7 +14678,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14731,7 +14731,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14784,7 +14784,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14838,7 +14838,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14893,7 +14893,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14948,7 +14948,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15003,7 +15003,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15057,7 +15057,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15110,7 +15110,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15164,7 +15164,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15218,7 +15218,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15272,7 +15272,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15326,7 +15326,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15380,7 +15380,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15433,7 +15433,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15486,7 +15486,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15539,7 +15539,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15592,7 +15592,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15645,7 +15645,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15699,7 +15699,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15753,7 +15753,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15807,7 +15807,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15861,7 +15861,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15914,7 +15914,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15967,7 +15967,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16020,7 +16020,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16073,7 +16073,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16126,7 +16126,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16179,7 +16179,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16232,7 +16232,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16285,7 +16285,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16338,7 +16338,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16391,7 +16391,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16444,7 +16444,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16497,7 +16497,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16550,7 +16550,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16603,7 +16603,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16656,7 +16656,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16709,7 +16709,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16762,7 +16762,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16815,7 +16815,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16868,7 +16868,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16921,7 +16921,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16974,7 +16974,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17027,7 +17027,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17080,7 +17080,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17133,7 +17133,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17192,7 +17192,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17243,7 +17243,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17294,7 +17294,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17345,7 +17345,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17396,7 +17396,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17447,7 +17447,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17498,7 +17498,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17549,7 +17549,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17600,7 +17600,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17651,7 +17651,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17702,7 +17702,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17753,7 +17753,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17807,7 +17807,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17861,7 +17861,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17916,7 +17916,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17970,7 +17970,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18025,7 +18025,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18080,7 +18080,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18135,7 +18135,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18191,7 +18191,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18246,7 +18246,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18301,7 +18301,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18357,7 +18357,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18412,7 +18412,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18466,7 +18466,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18521,7 +18521,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18575,7 +18575,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18630,7 +18630,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18686,7 +18686,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18738,7 +18738,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18789,7 +18789,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18840,7 +18840,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18891,7 +18891,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -18945,7 +18945,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19000,7 +19000,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19056,7 +19056,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19109,7 +19109,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19163,7 +19163,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19217,7 +19217,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19272,7 +19272,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19323,7 +19323,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19374,7 +19374,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19425,7 +19425,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19476,7 +19476,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19530,7 +19530,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19584,7 +19584,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19635,7 +19635,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19686,7 +19686,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19737,7 +19737,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19788,7 +19788,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19839,7 +19839,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19890,7 +19890,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19941,7 +19941,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -19992,7 +19992,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20043,7 +20043,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20094,7 +20094,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20145,7 +20145,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20196,7 +20196,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20247,7 +20247,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20298,7 +20298,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20349,7 +20349,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20400,7 +20400,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20451,7 +20451,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20502,7 +20502,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20553,7 +20553,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -20604,7 +20604,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index dddfaba..8912b3c1 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -14344,7 +14344,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14395,7 +14395,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14446,7 +14446,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14497,7 +14497,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14548,7 +14548,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14599,7 +14599,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14650,7 +14650,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14701,7 +14701,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14752,7 +14752,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14803,7 +14803,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14854,7 +14854,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14905,7 +14905,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -14956,7 +14956,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15007,7 +15007,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15058,7 +15058,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15109,7 +15109,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15160,7 +15160,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15211,7 +15211,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15262,7 +15262,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15313,7 +15313,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15364,7 +15364,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15415,7 +15415,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15466,7 +15466,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15518,7 +15518,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15570,7 +15570,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15621,7 +15621,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15672,7 +15672,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15723,7 +15723,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15774,7 +15774,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15825,7 +15825,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15876,7 +15876,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15927,7 +15927,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -15978,7 +15978,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16029,7 +16029,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16080,7 +16080,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16131,7 +16131,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16182,7 +16182,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16233,7 +16233,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16284,7 +16284,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16335,7 +16335,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16386,7 +16386,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16437,7 +16437,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16488,7 +16488,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16539,7 +16539,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16590,7 +16590,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16641,7 +16641,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16692,7 +16692,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -16743,7 +16743,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -17723,12 +17723,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -17739,8 +17739,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -17908,12 +17908,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -17924,8 +17924,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [ @@ -18070,12 +18070,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5712.0", + "description": "Run with ash-chrome version 114.0.5713.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18086,8 +18086,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5712.0", - "revision": "version:114.0.5712.0" + "location": "lacros_version_skew_tests_v114.0.5713.0", + "revision": "version:114.0.5713.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.rust.json b/testing/buildbot/chromium.rust.json index de2db9a..f462b9b 100644 --- a/testing/buildbot/chromium.rust.json +++ b/testing/buildbot/chromium.rust.json
@@ -693,7 +693,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -734,7 +734,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -775,7 +775,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -816,7 +816,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -857,7 +857,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -899,7 +899,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -941,7 +941,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -986,7 +986,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json index 87390401..aab066f 100644 --- a/testing/buildbot/chromium.webrtc.fyi.json +++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -720,7 +720,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -771,7 +771,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [
diff --git a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter index 4e4163c..c618df2 100644 --- a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter +++ b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
@@ -61,3 +61,6 @@ -org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindow -org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindowFallback -org.chromium.chrome.browser.tasks.tab_management.TabSwitcherMultiWindowTest.* + +# crbug.com/1195129 +-org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
diff --git a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter index b35e2213..fb8aea67 100644 --- a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter +++ b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
@@ -85,3 +85,9 @@ # crbug.com/1432049 -org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSelectionEditorPosition + +# crbug.com/1195129 +-org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion + +# crbug.com/1432785 +-org.chromium.chrome.browser.ContentViewFocusTest.testHideSelectionOnPhoneTabSwiping
diff --git a/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter b/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter new file mode 100644 index 0000000..dddbb79 --- /dev/null +++ b/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter
@@ -0,0 +1,4 @@ +# Small test suite due to limited capacity to run Lacros on devices. + +conformance/attribs/* +conformance2/attribs/*
diff --git a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter index 1b5abac..ec174cf 100644 --- a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter +++ b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter
@@ -3,3 +3,7 @@ # If you want to disable a test only for version skew testing, # you should add the test here, not in the source code. +# ash-chrome < M114 has an older "fake shill" which doesn't mark other services +# as "idle" when connecting a new service. +-NetworkingPrivateChromeOSApiTest.OnNetworksChangedEventConnect +
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index c199135..5b66c3bc 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -1674,8 +1674,8 @@ # Similar to get_builders_that_do_not_actually_exist above, but for # waterfalls defined in internal configs. return [ - 'chrome', 'chrome.pgo', 'internal.chrome.fyi', 'internal.chromeos.fyi', - 'internal.soda' + 'chrome', 'chrome.pgo', 'chrome.gpu.fyi', 'internal.chrome.fyi', + 'internal.chromeos.fyi', 'internal.soda' ] def check_input_file_consistency(self, verbose=False):
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index a8641e4c..b4aaca4 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1117,7 +1117,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "brya", - "cros_img": "brya-release/R114-15419.0.0", + "cros_img": "brya-release/R114-15407.0.0", "name": "chrome_all_tast_tests BRYA_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1163,7 +1163,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "octopus", - "cros_img": "octopus-release/R114-15419.0.0", + "cros_img": "octopus-release/R114-15408.0.0", "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM", "shards": 10, "swarming": {}, @@ -1186,7 +1186,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "trogdor", - "cros_img": "trogdor-release/R114-15419.0.0", + "cros_img": "trogdor-release/R114-15407.0.0", "name": "chrome_all_tast_tests TROGDOR_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1209,7 +1209,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "volteer", - "cros_img": "volteer-release/R114-15419.0.0", + "cros_img": "volteer-release/R114-15407.0.0", "name": "chrome_all_tast_tests VOLTEER_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1229,7 +1229,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15419.0.0", + "cros_img": "octopus-release/R114-15410.0.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1241,7 +1241,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15416.0.0", + "cros_img": "octopus-release/R113-15393.12.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1253,7 +1253,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R113-15393.12.0", + "cros_img": "octopus-release/R112-15359.37.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1265,7 +1265,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R112-15359.45.0", + "cros_img": "octopus-release/R111-15329.59.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1277,7 +1277,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15419.0.0", + "cros_img": "octopus-release/R114-15410.0.0", "name": "ozone_unittests OCTOPUS_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1288,7 +1288,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15416.0.0", + "cros_img": "octopus-release/R113-15393.12.0", "name": "ozone_unittests OCTOPUS_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1299,7 +1299,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R113-15393.12.0", + "cros_img": "octopus-release/R112-15359.37.0", "name": "ozone_unittests OCTOPUS_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1310,7 +1310,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R112-15359.45.0", + "cros_img": "octopus-release/R111-15329.59.0", "name": "ozone_unittests OCTOPUS_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1328,7 +1328,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15419.0.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "lacros_all_tast_tests HANA_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1340,7 +1340,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15416.0.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "lacros_all_tast_tests HANA_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1352,7 +1352,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R112-15359.37.0", "name": "lacros_all_tast_tests HANA_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1364,7 +1364,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.45.0", + "cros_img": "hana-release/R111-15329.59.0", "name": "lacros_all_tast_tests HANA_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1376,7 +1376,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15419.0.0", + "cros_img": "strongbad-release/R114-15410.0.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1388,7 +1388,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15416.0.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "lacros_all_tast_tests strongbad_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1400,7 +1400,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R112-15359.37.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1412,7 +1412,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.45.0", + "cros_img": "strongbad-release/R111-15329.59.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1424,7 +1424,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15419.0.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "ozone_unittests HANA_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1435,7 +1435,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15416.0.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "ozone_unittests HANA_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1446,7 +1446,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R112-15359.37.0", "name": "ozone_unittests HANA_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1457,7 +1457,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.45.0", + "cros_img": "hana-release/R111-15329.59.0", "name": "ozone_unittests HANA_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1468,7 +1468,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15419.0.0", + "cros_img": "strongbad-release/R114-15410.0.0", "name": "ozone_unittests STRONGBAD_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1479,7 +1479,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15416.0.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "ozone_unittests strongbad_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1490,7 +1490,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R112-15359.37.0", "name": "ozone_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1501,7 +1501,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.45.0", + "cros_img": "strongbad-release/R111-15329.59.0", "name": "ozone_unittests STRONGBAD_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1512,7 +1512,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15419.0.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "viz_unittests HANA_RELEASE_LKGM", "swarming": {}, "test": "viz_unittests", @@ -1523,7 +1523,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15416.0.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "viz_unittests HANA_RELEASE_DEV", "swarming": {}, "test": "viz_unittests", @@ -1534,7 +1534,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R112-15359.37.0", "name": "viz_unittests HANA_RELEASE_BETA", "swarming": {}, "test": "viz_unittests", @@ -1545,7 +1545,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.45.0", + "cros_img": "hana-release/R111-15329.59.0", "name": "viz_unittests HANA_RELEASE_STABLE", "swarming": {}, "test": "viz_unittests", @@ -1556,7 +1556,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15419.0.0", + "cros_img": "strongbad-release/R114-15410.0.0", "name": "viz_unittests STRONGBAD_RELEASE_LKGM", "swarming": {}, "test": "viz_unittests", @@ -1567,7 +1567,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15416.0.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "viz_unittests strongbad_RELEASE_DEV", "swarming": {}, "test": "viz_unittests", @@ -1578,7 +1578,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R112-15359.37.0", "name": "viz_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "viz_unittests", @@ -1589,7 +1589,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.45.0", + "cros_img": "strongbad-release/R111-15329.59.0", "name": "viz_unittests STRONGBAD_RELEASE_STABLE", "swarming": {}, "test": "viz_unittests",
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index f02b884..f2142308 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -404,6 +404,14 @@ ], }, }, + 'chromeos-eve': { + 'swarming': { + 'dimensions': { + 'os': 'ChromeOS', + 'device_type': 'eve', + }, + }, + }, 'chromeos-jacuzzi': { 'swarming': { 'dimensions': { @@ -1010,7 +1018,7 @@ { "cipd_package": 'infra/tools/mac_toolchain/${platform}', 'location': '.', - 'revision': 'git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff', + 'revision': 'git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118', }, ], },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 037e9ced..589bfc1 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2209,6 +2209,13 @@ }, }, }, + 'context_lost_passthrough_tests': { + # Not enough capacity. + 'remove_from': [ + 'Lacros FYI Release (eve)', + 'Lacros FYI Release (jacuzzi)', + ], + }, 'context_lost_validating_tests': { # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2) # exception once there is enough capacity to run these tests. @@ -2594,10 +2601,13 @@ ], }, 'gpu_process_launch_tests': { - # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2) - # exception once there is enough capacity to run these tests. 'remove_from': [ + # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2) + # exception once there is enough capacity to run these tests. 'Android FYI Release (Pixel 2)', + # Not enough capacity. + 'Lacros FYI Release (eve)', + 'Lacros FYI Release (jacuzzi)', ], }, 'gpu_pytype': { @@ -2623,10 +2633,13 @@ ], }, 'hardware_accelerated_feature_tests': { - # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2) - # exception once there is enough capacity to run these tests. 'remove_from': [ + # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2) + # exception once there is enough capacity to run these tests. 'Android FYI Release (Pixel 2)', + # Not enough capacity. + 'Lacros FYI Release (eve)', + 'Lacros FYI Release (jacuzzi)', ], }, 'headless_browsertests': { @@ -3531,6 +3544,11 @@ ], }, }, + # Not enough capacity. + 'remove_from': [ + 'Lacros FYI Release (eve)', + 'Lacros FYI Release (jacuzzi)', + ], }, 'screenshot_sync_validating_tests': { 'modifications': { @@ -4194,6 +4212,16 @@ 'shards': 30, }, }, + 'Lacros FYI Release (eve)': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter', + ], + }, + 'Lacros FYI Release (jacuzzi)': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter', + ], + }, }, }, 'webgl2_conformance_metal_passthrough_tests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 5868cb0..458c6123 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -6805,6 +6805,19 @@ }, }, + 'gpu_fyi_lacros_device_release_telemetry_tests': { + 'gpu_passthrough_telemetry_tests': { + 'variants': [ + 'LACROS_ASH_TOT', + ], + }, + 'gpu_webgl2_conformance_gles_passthrough_telemetry_tests': { + 'variants': [ + 'LACROS_ASH_TOT', + ], + }, + }, + 'ios16_beta_simulator_tests': { 'ios_common_tests': { 'variants': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 75d3e60..6670906 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 114.0.5712.0', + 'description': 'Run with ash-chrome version 114.0.5713.0', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v114.0.5712.0', - 'revision': 'version:114.0.5712.0', + 'location': 'lacros_version_skew_tests_v114.0.5713.0', + 'revision': 'version:114.0.5713.0', }, ], }, @@ -383,8 +383,8 @@ 'CROS_BRYA_RELEASE_LKGM': { 'skylab': { 'cros_board': 'brya', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'brya-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5685.0', + 'cros_img': 'brya-release/R114-15407.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, }, @@ -394,8 +394,8 @@ 'CROS_DEDEDE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'dedede-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'dedede-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_LKGM', @@ -403,8 +403,8 @@ 'CROS_DEDEDE_RELEASE_DEV': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'dedede-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'dedede-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_DEV', @@ -412,8 +412,8 @@ 'CROS_DEDEDE_RELEASE_BETA': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'dedede-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'dedede-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_BETA', @@ -430,8 +430,8 @@ 'CROS_EVE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'eve-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'eve-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_LKGM', @@ -439,8 +439,8 @@ 'CROS_EVE_RELEASE_DEV': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'eve-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'eve-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_DEV', @@ -448,8 +448,8 @@ 'CROS_EVE_RELEASE_BETA': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'eve-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'eve-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_BETA', @@ -457,8 +457,8 @@ 'CROS_EVE_RELEASE_STABLE': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '112.0.5615.62', - 'cros_img': 'eve-release/R112-15359.45.0', + 'cros_chrome_version': '111.0.5563.118', + 'cros_img': 'eve-release/R111-15329.59.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_STABLE', @@ -466,8 +466,8 @@ 'CROS_EVE_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'eve-public/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'eve-public/R114-15410.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -476,8 +476,8 @@ 'CROS_HANA_RELEASE_LKGM': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'hana-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'hana-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_LKGM', @@ -485,8 +485,8 @@ 'CROS_HANA_RELEASE_DEV': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'hana-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'hana-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_DEV', @@ -494,8 +494,8 @@ 'CROS_HANA_RELEASE_BETA': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'hana-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'hana-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_BETA', @@ -503,8 +503,8 @@ 'CROS_HANA_RELEASE_STABLE': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '112.0.5615.62', - 'cros_img': 'hana-release/R112-15359.45.0', + 'cros_chrome_version': '111.0.5563.118', + 'cros_img': 'hana-release/R111-15329.59.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_STABLE', @@ -512,8 +512,8 @@ 'CROS_HEROBRINE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'herobrine', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'herobrine-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'herobrine-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'HEROBRINE_RELEASE_LKGM', @@ -521,8 +521,8 @@ 'CROS_JACUZZI_RELEASE_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'jacuzzi-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'jacuzzi-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_LKGM', @@ -530,8 +530,8 @@ 'CROS_JACUZZI_RELEASE_DEV': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'jacuzzi-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'jacuzzi-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_DEV', @@ -539,8 +539,8 @@ 'CROS_JACUZZI_RELEASE_BETA': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'jacuzzi-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'jacuzzi-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_BETA', @@ -560,8 +560,8 @@ 'CROS_JACUZZI_RELEASE_STABLE': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '112.0.5615.62', - 'cros_img': 'jacuzzi-release/R112-15359.45.0', + 'cros_chrome_version': '111.0.5563.118', + 'cros_img': 'jacuzzi-release/R111-15329.59.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_STABLE', @@ -569,8 +569,8 @@ 'CROS_JACUZZI_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'jacuzzi-public/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'jacuzzi-public/R114-15410.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -579,8 +579,8 @@ 'CROS_JACUZZI_CQ_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'jacuzzi-public/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'jacuzzi-public/R114-15410.0.0', 'bucket': 'chromiumos-image-archive', 'public_builder': 'cros_test_platform_public', 'public_builder_bucket': 'testplatform-public', @@ -591,8 +591,8 @@ 'CROS_KEVIN64_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'kevin', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'kevin64-public/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'kevin64-public/R114-15410.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -611,8 +611,8 @@ 'CROS_OCTOPUS_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'octopus-public/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'octopus-public/R114-15410.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -621,8 +621,8 @@ 'CROS_OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'octopus-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5689.0', + 'cros_img': 'octopus-release/R114-15408.0.0', 'tast_expr': '("group:mainline" && !informational)', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, @@ -633,8 +633,8 @@ 'CROS_OCTOPUS_RELEASE_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'octopus-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'octopus-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_LKGM', @@ -642,8 +642,8 @@ 'CROS_OCTOPUS_RELEASE_DEV': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'octopus-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'octopus-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_DEV', @@ -651,8 +651,8 @@ 'CROS_OCTOPUS_RELEASE_BETA': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'octopus-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'octopus-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_BETA', @@ -660,8 +660,8 @@ 'CROS_OCTOPUS_RELEASE_STABLE': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '112.0.5615.62', - 'cros_img': 'octopus-release/R112-15359.45.0', + 'cros_chrome_version': '111.0.5563.118', + 'cros_img': 'octopus-release/R111-15329.59.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_STABLE', @@ -669,8 +669,8 @@ 'CROS_STRONGBAD_RELEASE_LKGM': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'strongbad-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'strongbad-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_LKGM', @@ -678,8 +678,8 @@ 'CROS_STRONGBAD_RELEASE_DEV': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '114.0.5703.0', - 'cros_img': 'strongbad-release/R114-15416.0.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'strongbad-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'strongbad_RELEASE_DEV', @@ -687,8 +687,8 @@ 'CROS_STRONGBAD_RELEASE_BETA': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'strongbad-release/R113-15393.12.0', + 'cros_chrome_version': '112.0.5615.45', + 'cros_img': 'strongbad-release/R112-15359.37.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_BETA', @@ -696,8 +696,8 @@ 'CROS_STRONGBAD_RELEASE_STABLE': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '112.0.5615.62', - 'cros_img': 'strongbad-release/R112-15359.45.0', + 'cros_chrome_version': '111.0.5563.118', + 'cros_img': 'strongbad-release/R111-15329.59.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_STABLE', @@ -705,8 +705,8 @@ 'CROS_TROGDOR_RELEASE_LKGM': { 'skylab': { 'cros_board': 'trogdor', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'trogdor-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5685.0', + 'cros_img': 'trogdor-release/R114-15407.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, }, @@ -716,8 +716,8 @@ 'CROS_VOLTEER_RELEASE_LKGM': { 'skylab': { 'cros_board': 'volteer', - 'cros_chrome_version': '114.0.5707.0', - 'cros_img': 'volteer-release/R114-15419.0.0', + 'cros_chrome_version': '114.0.5685.0', + 'cros_img': 'volteer-release/R114-15407.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, }, @@ -750,6 +750,12 @@ ], }, }, + 'LACROS_ASH_TOT': { + 'args': [ + '--deploy-lacros', + ], + 'identifier': 'Ash ToT', + }, 'LACROS_BETTY_PI_ARC': { 'args': [ '--board=betty-pi-arc',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index bb48f58f..e17f39fbb 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -351,6 +351,49 @@ }, }, { + 'project': 'chrome', + 'bucket': 'ci', + 'name': 'chrome.gpu.fyi', + 'mixins': [ + 'chrome-tester-service-account', + 'swarming_containment_auto', + ], + 'machines': { + 'Lacros FYI Release (eve)': { + 'additional_compile_targets': [ + 'chrome', + ], + 'os_type': 'chromeos', + 'browser_config': 'lacros-chrome', + 'mixins': [ + 'limited_capacity_bot', + 'chromeos-eve', + 'chrome-swarming-pool', + ], + 'test_suites': { + 'gpu_telemetry_tests': 'gpu_fyi_lacros_device_release_telemetry_tests', + }, + 'skip_merge_script': True, + }, + 'Lacros FYI Release (jacuzzi)': { + 'additional_compile_targets': [ + 'chrome', + ], + 'os_type': 'chromeos', + 'browser_config': 'lacros-chrome', + 'mixins': [ + 'limited_capacity_bot', + 'chromeos-jacuzzi', + 'chrome-swarming-pool', + ], + 'test_suites': { + 'gpu_telemetry_tests': 'gpu_fyi_lacros_device_release_telemetry_tests', + }, + 'skip_merge_script': True, + }, + } + }, + { 'name': 'chromium', 'mixins': ['chromium-tester-service-account'], 'machines': {
diff --git a/testing/chromoting/OWNERS b/testing/chromoting/OWNERS index 989a265..79df492 100644 --- a/testing/chromoting/OWNERS +++ b/testing/chromoting/OWNERS
@@ -1,3 +1,2 @@ jamiewalch@chromium.org joedow@chromium.org -sergeyu@chromium.org
diff --git a/testing/platform_test.h b/testing/platform_test.h index 80f9cc8d..f14bd454 100644 --- a/testing/platform_test.h +++ b/testing/platform_test.h
@@ -8,11 +8,9 @@ #include <gtest/gtest.h> #if defined(GTEST_OS_MAC) -#include <objc/objc.h> - // The purpose of this class us to provide a hook for platform-specific // operations across unit tests. For example, on the Mac, it creates and -// releases an outer NSAutoreleasePool for each test case. For now, it's only +// releases an autorelease pool for each test case. For now, it's only // implemented on the Mac. To enable this for another platform, just adjust // the #ifdefs and add a platform_test_<platform>.cc implementation file. class PlatformTest : public testing::Test { @@ -23,13 +21,12 @@ PlatformTest(); private: - // |pool_| is a NSAutoreleasePool, but since this header may be imported from - // files built with Objective-C ARC that forbids explicit usage of - // NSAutoreleasePools, it is declared as id here. - id pool_; + void* autorelease_pool_; }; #else -typedef testing::Test PlatformTest; + +using PlatformTest = testing::Test; + #endif // GTEST_OS_MAC #endif // TESTING_PLATFORM_TEST_H_
diff --git a/testing/platform_test_mac.mm b/testing/platform_test_mac.mm index 30126fc..d52ad37 100644 --- a/testing/platform_test_mac.mm +++ b/testing/platform_test_mac.mm
@@ -4,12 +4,17 @@ #include "platform_test.h" -#import <Foundation/Foundation.h> +// Note that this uses the direct runtime interface to the autorelease pool. +// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support +// This is so this can work when compiled for ARC. -PlatformTest::PlatformTest() - : pool_([[NSAutoreleasePool alloc] init]) { +extern "C" { +void* objc_autoreleasePoolPush(void); +void objc_autoreleasePoolPop(void* pool); } +PlatformTest::PlatformTest() : autorelease_pool_(objc_autoreleasePoolPush()) {} + PlatformTest::~PlatformTest() { - [pool_ release]; + objc_autoreleasePoolPop(autorelease_pool_); }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 2f0fff1..9bf9391 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -211,6 +211,35 @@ ] } ], + "AndroidMediaPickerAdoption": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Direct", + "params": { + "use_action_pick_images": "true" + }, + "enable_features": [ + "MediaPickerAdoption" + ], + "min_os_version": "13.0.0" + }, + { + "name": "Enabled_Direct_Plus", + "params": { + "use_action_pick_images_plus": "true" + }, + "enable_features": [ + "MediaPickerAdoption" + ], + "min_os_version": "13.0.0" + } + ] + } + ], "AndroidMessagesSaveCard": [ { "platforms": [ @@ -2006,6 +2035,21 @@ ] } ], + "CALayerNewLimit": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CALayerNewLimit" + ] + } + ] + } + ], "CPSS": [ { "platforms": [ @@ -5091,22 +5135,6 @@ ] } ], - "FastPairPowerConsumption": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "Enabled_20220919", - "enable_features": [ - "FastPair", - "FastPairSavedDevices" - ] - } - ] - } - ], "FastPathPaintPropertyUpdates": [ { "platforms": [ @@ -9821,9 +9849,7 @@ "IPH_PerformanceNewBadge", "PageTimelineMonitor" ], - "disable_features": [ - "IPH_HighEfficiencyInfoMode" - ] + "disable_features": [] } ] } @@ -14064,21 +14090,6 @@ ] } ], - "WebApkManifestUniqueId": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "WebApkUniqueId" - ] - } - ] - } - ], "WebAuthFlowInBrowserTab": [ { "platforms": [
diff --git a/third_party/blink/common/switches.cc b/third_party/blink/common/switches.cc index 75deec5..1700b28 100644 --- a/third_party/blink/common/switches.cc +++ b/third_party/blink/common/switches.cc
@@ -118,9 +118,6 @@ // signal to dismiss a splash screen. const char kNetworkQuietTimeout[] = "network-quiet-timeout"; -// Number of worker threads used to rasterize content. -const char kNumRasterThreads[] = "num-raster-threads"; - // Visibly render a border around layout shift rects in the web page to help // debug and study layout shifts. const char kShowLayoutShiftRegions[] = "show-layout-shift-regions";
diff --git a/third_party/blink/public/common/switches.h b/third_party/blink/public/common/switches.h index d70c831a..26945c1f 100644 --- a/third_party/blink/public/common/switches.h +++ b/third_party/blink/public/common/switches.h
@@ -62,7 +62,6 @@ BLINK_COMMON_EXPORT extern const char kMaxUntiledLayerWidth[]; BLINK_COMMON_EXPORT extern const char kMinHeightForGpuRasterTile[]; BLINK_COMMON_EXPORT extern const char kNetworkQuietTimeout[]; -BLINK_COMMON_EXPORT extern const char kNumRasterThreads[]; BLINK_COMMON_EXPORT extern const char kSharedArrayBufferAllowedOrigins[]; BLINK_COMMON_EXPORT extern const char kShowLayoutShiftRegions[]; BLINK_COMMON_EXPORT extern const char kShowPaintRects[];
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index cfe1148..1d34dbd 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -775,6 +775,15 @@ # One of the deprecation names from third_party/blink/renderer/core/frame/deprecation/deprecation.json5 string type + # This issue warns about sites in the redirect chain of a finished navigation + # that may be flagged as trackers and have their state cleared if they don't + # receive a user interaction. Note that in this context 'site' means eTLD+1. + # For example, if the URL `https://example.test:80/bounce` was in the + # redirect chain, the site reported would be `example.test`. + type BounceTrackingIssueDetails extends object + properties + array of string trackingSites + type ClientHintIssueReason extends string enum # Items in the accept-ch meta tag allow list must be valid origins. @@ -851,6 +860,7 @@ DeprecationIssue ClientHintIssue FederatedAuthRequestIssue + BounceTrackingIssue # This struct holds a list of optional fields with additional information # specific to the kind of issue. When adding a new issue code, please also @@ -873,6 +883,7 @@ optional DeprecationIssueDetails deprecationIssueDetails optional ClientHintIssueDetails clientHintIssueDetails optional FederatedAuthRequestIssueDetails federatedAuthRequestIssueDetails + optional BounceTrackingIssueDetails bounceTrackingIssueDetails # A unique id for a DevTools inspector issue. Allows other entities (e.g. # exceptions, CDP message, console messages, etc.) to reference an issue.
diff --git a/third_party/blink/public/mojom/devtools/inspector_issue.mojom b/third_party/blink/public/mojom/devtools/inspector_issue.mojom index 4fde945..535428a 100644 --- a/third_party/blink/public/mojom/devtools/inspector_issue.mojom +++ b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
@@ -22,6 +22,7 @@ kHeavyAdIssue, kLowTextContrastIssue, kFederatedAuthRequestIssue, + kBounceTrackingIssue, kGenericIssue, kDeprecationIssue, }; @@ -220,6 +221,10 @@ FederatedAuthRequestResult status; }; +struct BounceTrackingIssueDetails { + array<string> tracking_sites; +}; + enum GenericIssueErrorType { kCrossOriginPortalPostMessageError, kFormLabelForNameError, @@ -263,6 +268,7 @@ HeavyAdIssueDetails? heavy_ad_issue_details; LowTextContrastIssue? low_text_contrast_details; FederatedAuthRequestIssueDetails? federated_auth_request_details; + BounceTrackingIssueDetails? bounce_tracking_issue_details; GenericIssueDetails? generic_issue_details; DeprecationIssueDetails? deprecation_issue_details; mojo_base.mojom.UnguessableToken? issue_id;
diff --git a/third_party/blink/public/mojom/webauthn/authenticator.mojom b/third_party/blink/public/mojom/webauthn/authenticator.mojom index 5367034..04e72eb8 100644 --- a/third_party/blink/public/mojom/webauthn/authenticator.mojom +++ b/third_party/blink/public/mojom/webauthn/authenticator.mojom
@@ -281,16 +281,6 @@ array<uint8>? experiments; }; -// Cloud-assisted BLE extension data for makeCredential. -struct CableRegistration { - // The caBLE versions supported by the relying party. - array<uint8> versions; - - // The 65-byte ECDSA ephemeral public key belonging to the relying party - // for use in establishing an encrypted caBLE channel with an authenticator. - array<uint8, 65> relying_party_public_key; -}; - // See https://w3c.github.io/webauthn/#dictdef-authenticationextensionsprfvalues struct PRFValues { // In the Javascript-to-native direction, id is the credential ID for these @@ -485,12 +475,6 @@ // credential. AttestationConveyancePreference attestation; - // The contents of the cloud assisted BLE extension for makeCredential - // requests, if any. This extension permits browsers and authenticator - // devices to establish a pairingless BLE connection. - // TODO(crbug.com/842371): Add link to spec when available. - CableRegistration? cable_registration_data; - // The contents of the hmacCreateSecret extension, if any. See // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension bool hmac_create_secret;
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index bcd6a715..0bdb4488e 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -237,8 +237,6 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_browsing_topics_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_camera_device_permission_descriptor.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index c515555..894451f8 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -151,7 +151,6 @@ "//third_party/blink/renderer/modules/credentialmanagement/authenticator_response.idl", "//third_party/blink/renderer/modules/credentialmanagement/authenticator_selection_criteria.idl", "//third_party/blink/renderer/modules/credentialmanagement/cable_authentication_data.idl", - "//third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl", "//third_party/blink/renderer/modules/credentialmanagement/collected_client_data.idl", "//third_party/blink/renderer/modules/credentialmanagement/credential.idl", "//third_party/blink/renderer/modules/credentialmanagement/credential_creation_options.idl",
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index a99952f..3db51e1a 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -75,6 +75,7 @@ #include "third_party/blink/renderer/platform/widget/frame_widget.h" #if BUILDFLAG(IS_MAC) +#include "base/mac/foundation_util.h" #include "third_party/blink/renderer/core/editing/substring_util.h" #include "third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h" #include "ui/base/mojom/attributed_string.mojom-blink.h" @@ -1007,8 +1008,10 @@ NSAttributedString* string = SubstringUtil::AttributedSubstringInRange( frame_, base::checked_cast<WTF::wtf_size_t>(range.start()), base::checked_cast<WTF::wtf_size_t>(range.length()), baseline_point); - if (string) - attributed_string = ui::mojom::blink::AttributedString::From(string); + if (string) { + attributed_string = + ui::mojom::blink::AttributedString::From(base::mac::NSToCFCast(string)); + } std::move(callback).Run(std::move(attributed_string), baseline_point); }
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 9bd1f83..01b1cb9 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -149,6 +149,7 @@ #include "ui/gfx/geometry/point_conversions.h" #if BUILDFLAG(IS_MAC) +#include "base/mac/foundation_util.h" #include "third_party/blink/renderer/core/editing/substring_util.h" #include "third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h" #include "ui/base/mojom/attributed_string.mojom-blink.h" @@ -661,8 +662,10 @@ ui::mojom::blink::AttributedStringPtr attributed_string = nullptr; NSAttributedString* string = SubstringUtil::AttributedWordAtPoint( this, point_in_local_root, baseline_point); - if (string) - attributed_string = ui::mojom::blink::AttributedString::From(string); + if (string) { + attributed_string = + ui::mojom::blink::AttributedString::From(base::mac::NSToCFCast(string)); + } std::move(callback).Run(std::move(attributed_string), baseline_point); }
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index df8f440..04b6eb7 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -188,12 +188,6 @@ // when intersecting browser native UI. static const int kMaximumCursorSizeWithoutFallback = 32; -// It's pretty unlikely that a scale of less than one would ever be used. But -// all we really need to ensure here is that the scale isn't so small that -// integer overflow can occur when dividing cursor sizes (limited above) by the -// scale. -static const double kMinimumCursorScale = 0.001; - // The minimum amount of time an element stays active after a ShowPress // This is roughly 9 frames, which should be long enough to be noticeable. constexpr base::TimeDelta kMinimumActiveInterval = base::Seconds(0.15); @@ -584,22 +578,14 @@ kRespectImageOrientation); Image* image = cached_image->GetImage(); - - // If the image is an SVG, then adjust the scale to reflect the device - // scale factor so that the SVG can be rasterized in the native - // resolution and scaled down to the correct size for the cursor. - float device_scale_factor = 1; if (image->IsSVGImage()) { - // Limit the size of cursors (in DIP) so that they cannot be - // used to cover UI elements in chrome. StyleImage::ImageSize does not - // take StyleImage::ImageScaleFactor() into account when computing the - // size for SVG images. + // `StyleImage::ImageSize` does not take `StyleImage::ImageScaleFactor` + // into account when computing the size for SVG images. size.Scale(1 / scale); - device_scale_factor = - page->GetChromeClient().GetScreenInfo(*frame_).device_scale_factor; - scale *= device_scale_factor; } + // Limit the size of cursors (in DIP) so that they cannot be used to cover + // UI elements in chrome. if (size.IsEmpty() || size.width() > kMaximumCursorSize || size.height() > kMaximumCursorSize) continue; @@ -630,19 +616,17 @@ } } - // Ensure no overflow possible in calculations above. - if (scale < kMinimumCursorScale) - continue; - - // Convert from DIP to physical pixels. - hot_spot = gfx::ScaleToRoundedPoint(hot_spot, scale); - - // Special case for SVG so that it can be rasterized in the appropriate - // resolution for high DPI displays. + // If the image is an SVG, then adjust the scale to reflect the device + // scale factor so that the SVG can be rasterized in the native + // resolution and scaled down to the correct size for the cursor. scoped_refptr<Image> svg_image_holder; if (auto* svg_image = DynamicTo<SVGImage>(image)) { + const float device_scale_factor = + page->GetChromeClient().GetScreenInfo(*frame_).device_scale_factor; + scale *= device_scale_factor; // Re-scale back from DIP to device pixels. size.Scale(scale); + // TODO(fs): Should pass proper URL. Use StyleImage::GetImage. svg_image_holder = SVGImageForContainer::Create( svg_image, size, device_scale_factor, NullURL(), @@ -652,6 +636,9 @@ image = svg_image_holder.get(); } + // Convert from DIP to physical pixels. + hot_spot = gfx::ScaleToRoundedPoint(hot_spot, scale); + return ui::Cursor::NewCustom( image->AsSkBitmapForCurrentFrame(kRespectImageOrientation), DetermineHotSpot(*image, hot_spot_specified, hot_spot), scale);
diff --git a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc index c5c3fc2..d5dd4b0 100644 --- a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc +++ b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
@@ -64,6 +64,8 @@ case mojom::blink::InspectorIssueCode::kFederatedAuthRequestIssue: CHECK(false); return ""; + case mojom::blink::InspectorIssueCode::kBounceTrackingIssue: + NOTREACHED_NORETURN(); case mojom::blink::InspectorIssueCode::kGenericIssue: NOTREACHED(); return "";
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 25c1af4..da59c962 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -132,8 +132,6 @@ layer_(&layer), in_resize_mode_(false), scrolls_overflow_(false), - in_overflow_relayout_(false), - allow_second_overflow_relayout_(false), needs_composited_scrolling_(false), needs_scroll_offset_clamp_(false), needs_relayout_(false), @@ -964,15 +962,8 @@ void PaintLayerScrollableArea::UpdateAfterLayout() { InvalidateAllStickyConstraints(); - bool is_horizontal_scrollbar_frozen; - bool is_vertical_scrollbar_frozen; - if (in_overflow_relayout_ && !allow_second_overflow_relayout_) { - is_horizontal_scrollbar_frozen = is_vertical_scrollbar_frozen = true; - } else { - is_horizontal_scrollbar_frozen = IsHorizontalScrollbarFrozen(); - is_vertical_scrollbar_frozen = IsVerticalScrollbarFrozen(); - } - allow_second_overflow_relayout_ = false; + bool is_horizontal_scrollbar_frozen = IsHorizontalScrollbarFrozen(); + bool is_vertical_scrollbar_frozen = IsVerticalScrollbarFrozen(); if (NeedsScrollbarReconstruction()) { RemoveScrollbarsForReconstruction(); @@ -995,16 +986,10 @@ ComputeScrollbarExistence(kLayout, needs_horizontal_scrollbar, needs_vertical_scrollbar); - // Removing auto scrollbars is a heuristic and can be incorrect if the content - // size depends on the scrollbar size (e.g., sized with percentages). Removing - // scrollbars can require two additional layout passes so this is only done on - // the first layout (!in_overflow_layout). - if (!in_overflow_relayout_ && !is_horizontal_scrollbar_frozen && - !is_vertical_scrollbar_frozen && + if (!is_horizontal_scrollbar_frozen && !is_vertical_scrollbar_frozen && TryRemovingAutoScrollbars(needs_horizontal_scrollbar, needs_vertical_scrollbar)) { needs_horizontal_scrollbar = needs_vertical_scrollbar = false; - allow_second_overflow_relayout_ = true; } bool horizontal_scrollbar_should_change = @@ -1050,25 +1035,10 @@ !GetLayoutBox()->IsHorizontalWritingMode())) { GetLayoutBox()->SetIntrinsicLogicalWidthsDirty(); } - if (IsManagedByLayoutNG(*GetLayoutBox())) { - // If the box is managed by LayoutNG, don't go here. We don't want to - // re-enter the NG layout algorithm for this box from here. Just update - // the rectangles, in case scrollbars were added or removed. LayoutNG - // has its own scrollbar change detection mechanism. - UpdateScrollDimensions(); - } else { - in_overflow_relayout_ = true; - SubtreeLayoutScope layout_scope(*GetLayoutBox()); - layout_scope.SetNeedsLayout( - GetLayoutBox(), layout_invalidation_reason::kScrollbarChanged); - if (auto* block = DynamicTo<LayoutBlock>(GetLayoutBox())) { - block->UpdateBlockLayout(true); - } else { - GetLayoutBox()->UpdateLayout(); - } - in_overflow_relayout_ = false; - scrollbar_manager_.DestroyDetachedScrollbars(); - } + // Just update the rectangles, in case scrollbars were added or + // removed. The calling code on the layout side has its own scrollbar + // change detection mechanism. + UpdateScrollDimensions(); } } else if (!HasScrollbar() && resizer_will_change) { Layer()->DirtyStackingContextZOrderLists(); @@ -1651,11 +1621,6 @@ bool PaintLayerScrollableArea::TryRemovingAutoScrollbars( const bool& needs_horizontal_scrollbar, const bool& needs_vertical_scrollbar) { - // If scrollbars are removed but the content size depends on the scrollbars, - // additional layouts will be required to size the content. Therefore, only - // remove auto scrollbars for the initial layout pass. - DCHECK(!in_overflow_relayout_); - if (!needs_horizontal_scrollbar && !needs_vertical_scrollbar) return false;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index 62c40622..9f95065 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -727,12 +727,6 @@ unsigned in_resize_mode_ : 1; unsigned scrolls_overflow_ : 1; - // True if we are in an overflow scrollbar relayout. - unsigned in_overflow_relayout_ : 1; - - // True if a second overflow scrollbar relayout is permitted. - unsigned allow_second_overflow_relayout_ : 1; - // FIXME: once cc can handle composited scrolling with clip paths, we will // no longer need this bit. unsigned needs_composited_scrolling_ : 1;
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index 2ad38389..25a7934 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -455,10 +455,19 @@ // If we're in a fragmentation context, the parent fragment of OOFs is the // fragmentainer, unless the object is monolithic, in which case nothing // contained by the object participates in the current block fragmentation - // context. If we're not participating in block fragmentation, the containing - // fragment of an OOF fragment is always simply the parent. + // context. The monolithic-check here is somewhat special, to match the + // behavior in OOF layout. We need to check that we're monolithic AND the + // first fragment of the node in order to act as an OOF container. A non-first + // fragment may be set as monolithic if overflow is clipped and we've reached + // the end right there. But that doesn't affect how OOF layout behaves. In + // such cases, where there's more than one fragment involved, an OOF fragment + // will become a direct child of a fragmentainer, just as if there were no + // monolithicness involved at all. + // + // If we're not participating in block fragmentation, the containing fragment + // of an OOF fragment is always simply the parent. if (!context.current_container.IsInFragmentationContext() || - (fragment && fragment->IsMonolithic())) { + (fragment && fragment->IsMonolithic() && fragment->IsFirstForNode())) { // Anonymous blocks are not allowed to be containing blocks, so we should // skip over any such elements. if (!fragment || !fragment->IsAnonymousBlock()) {
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index 3f766ac..e429205 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -520,10 +520,6 @@ if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) return; - // Hack around libxml2's lack of encoding overide support by manually - // resetting the encoding to UTF-16 before every chunk. Otherwise libxml - // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks and - // switch encodings, causing the parse to fail. if (is_8bit) { xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1); return; @@ -538,6 +534,7 @@ static void ParseChunk(xmlParserCtxtPtr ctxt, const String& chunk) { bool is_8bit = chunk.Is8Bit(); + // Reset the encoding for each chunk to reflect if it is Latin-1 or UTF-16. SwitchEncoding(ctxt, is_8bit); if (is_8bit) xmlParseChunk(ctxt, reinterpret_cast<const char*>(chunk.Characters8()), @@ -1500,6 +1497,11 @@ static void StartDocumentHandler(void* closure) { xmlParserCtxt* ctxt = static_cast<xmlParserCtxt*>(closure); XMLDocumentParser* parser = GetParser(closure); + // Reset the encoding back to match that of the current data block (Latin-1 / + // UTF-16), since libxml may switch encoding based on the XML declaration - + // which it has now seen - causing the parse to fail. We could use the + // XML_PARSE_IGNORE_ENC option to avoid this, but we're relying on populating + // the 'xmlEncoding' property with the value it yields. SwitchEncoding(ctxt, parser->IsCurrentlyParsing8BitChunk()); parser->StartDocument(ToString(ctxt->version), ToString(ctxt->encoding), ctxt->standalone);
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 6df1e86..0799581 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -184,6 +184,7 @@ deps = [ ":make_modules_generated", + "//cc", "//components/webrtc:thread_wrapper", "//gin", "//net:net",
diff --git a/third_party/blink/renderer/modules/DEPS b/third_party/blink/renderer/modules/DEPS index aa82aa38..49b549c 100644 --- a/third_party/blink/renderer/modules/DEPS +++ b/third_party/blink/renderer/modules/DEPS
@@ -36,6 +36,9 @@ "+testing/libfuzzer/proto/lpm_interface.h", "+third_party/protobuf/src/google/protobuf/repeated_field.h", ], + "modules_initializer.cc": [ + "+cc/raster/categorized_worker_pool.h", + ], ".*_decoder_fuzzer.cc": [ "+base/run_loop.h", ],
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl index e10e0ce0..7bdc2b9 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
@@ -10,7 +10,6 @@ // https://w3c.github.io/webauthn/#sctn-appid-exclude-extension USVString appidExclude; - CableRegistrationData cableRegistration; sequence<CableAuthenticationData> cableAuthentication; // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension
diff --git a/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl b/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl deleted file mode 100644 index fd950cb..0000000 --- a/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl +++ /dev/null
@@ -1,8 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -dictionary CableRegistrationData { - required sequence<octet> versions; - required BufferSource rpPublicKey; -};
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc index 9ad9be4..a98efc3 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
@@ -21,7 +21,6 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_prf_values.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_logout_r_ps_request.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_request_options_context.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_provider_config.h" @@ -53,8 +52,6 @@ using blink::mojom::blink::AuthenticatorTransport; using blink::mojom::blink::CableAuthentication; using blink::mojom::blink::CableAuthenticationPtr; -using blink::mojom::blink::CableRegistration; -using blink::mojom::blink::CableRegistrationPtr; using blink::mojom::blink::CredentialInfo; using blink::mojom::blink::CredentialInfoPtr; using blink::mojom::blink::CredentialType; @@ -532,13 +529,6 @@ if (extensions->hasAppidExclude()) { mojo_options->appid_exclude = extensions->appidExclude(); } - if (extensions->hasCableRegistration()) { - CableRegistrationPtr mojo_cable = - CableRegistration::From(*extensions->cableRegistration()); - if (mojo_cable) { - mojo_options->cable_registration_data = std::move(mojo_cable); - } - } if (extensions->hasHmacCreateSecret()) { mojo_options->hmac_create_secret = extensions->hmacCreateSecret(); } @@ -633,20 +623,6 @@ } // static -CableRegistrationPtr -TypeConverter<CableRegistrationPtr, blink::CableRegistrationData>::Convert( - const blink::CableRegistrationData& data) { - auto entity = CableRegistration::New(); - entity->versions = data.versions(); - entity->relying_party_public_key = - ConvertFixedSizeArray(data.rpPublicKey(), 65); - if (entity->relying_party_public_key.empty()) { - return nullptr; - } - return entity; -} - -// static PublicKeyCredentialRequestOptionsPtr TypeConverter<PublicKeyCredentialRequestOptionsPtr, blink::PublicKeyCredentialRequestOptions>::
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h index c715ecd..b8ddb23 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h +++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
@@ -21,7 +21,6 @@ class AuthenticationExtensionsPRFValues; class AuthenticatorSelectionCriteria; class CableAuthenticationData; -class CableRegistrationData; class Credential; class IdentityCredentialLogoutRPsRequest; class IdentityProviderConfig; @@ -177,13 +176,6 @@ }; template <> -struct TypeConverter<blink::mojom::blink::CableRegistrationPtr, - blink::CableRegistrationData> { - static blink::mojom::blink::CableRegistrationPtr Convert( - const blink::CableRegistrationData&); -}; - -template <> struct TypeConverter<blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr, blink::PublicKeyCredentialRequestOptions> { static blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr Convert(
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc index 13f165db..7569719f 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -1191,13 +1191,6 @@ } } } - if (options->publicKey()->extensions()->hasCableRegistration()) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - "The 'cableRegistration' extension is only valid when creating " - "a credential")); - return promise; - } if (options->publicKey()->extensions()->credProps()) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotSupportedError,
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc index 8d72cfd..1c68797 100644 --- a/third_party/blink/renderer/modules/modules_initializer.cc +++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/task/thread_pool.h" #include "build/build_config.h" +#include "cc/raster/categorized_worker_pool.h" #include "mojo/public/cpp/bindings/binder_map.h" #include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h" #include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" @@ -103,7 +104,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h" +#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h" #include "third_party/blink/renderer/platform/widget/frame_widget.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -343,7 +344,8 @@ frame_widget->GetLayerTreeSettings(), base::FeatureList::IsEnabled(kBlinkMediaPlayerUsesBaseThreadPool) ? base::ThreadPool::CreateTaskRunner(base::TaskTraits{}) - : CategorizedWorkerPool::GetOrCreate())); + : cc::CategorizedWorkerPool::GetOrCreate( + &BlinkCategorizedWorkerPoolDelegate::Get()))); } WebRemotePlaybackClient* ModulesInitializer::CreateWebRemotePlaybackClient(
diff --git a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl index 5eb091b4..32c6d45d 100644 --- a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl +++ b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl
@@ -2,5 +2,8 @@ RuntimeEnabled=SharedStorageAPI, ImplementedAs=WindowSharedStorage ] partial interface Window { - [MeasureAs=SharedStorageAPI_SharedStorage_DOMReference] readonly attribute SharedStorage sharedStorage; + [ + MeasureAs=SharedStorageAPI_SharedStorage_DOMReference, + SecureContext + ] readonly attribute SharedStorage sharedStorage; };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 2fb2134..3473589 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1505,8 +1505,8 @@ "webrtc/webrtc_video_frame_adapter.h", "webrtc/webrtc_video_utils.cc", "webrtc/webrtc_video_utils.h", - "widget/compositing/categorized_worker_pool.cc", - "widget/compositing/categorized_worker_pool.h", + "widget/compositing/blink_categorized_worker_pool_delegate.cc", + "widget/compositing/blink_categorized_worker_pool_delegate.h", "widget/compositing/layer_tree_settings.cc", "widget/compositing/layer_tree_settings.h", "widget/compositing/layer_tree_view.cc", @@ -1684,6 +1684,7 @@ "//base/allocator:buildflags", "//build:chromecast_buildflags", "//build:chromeos_buildflags", + "//cc", "//cc/ipc", "//cc/mojo_embedder", "//components/paint_preview/common", @@ -2217,7 +2218,6 @@ "weborigin/security_policy_test.cc", "webrtc/convert_to_webrtc_video_frame_buffer_test.cc", "webrtc/webrtc_video_frame_adapter_test.cc", - "widget/compositing/categorized_worker_pool_unittest.cc", "widget/compositing/layer_tree_settings_unittest.cc", "widget/compositing/layer_tree_view_unittest.cc", "widget/compositing/render_frame_metadata_observer_impl_unittest.cc",
diff --git a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h index ebc0089..489c289 100644 --- a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h +++ b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h
@@ -8,19 +8,15 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "ui/base/mojom/attributed_string.mojom-blink.h" -#if __OBJC__ -@class NSAttributedString; -#else -class NSAttributedString; -#endif +#include <CoreFoundation/CoreFoundation.h> namespace mojo { template <> -struct PLATFORM_EXPORT - TypeConverter<ui::mojom::blink::AttributedStringPtr, NSAttributedString*> { +struct PLATFORM_EXPORT TypeConverter<ui::mojom::blink::AttributedStringPtr, + CFAttributedStringRef> { static ui::mojom::blink::AttributedStringPtr Convert( - const NSAttributedString* ns_attributed_string); + CFAttributedStringRef cf_attributed_string); }; } // namespace mojo
diff --git a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm index da09b2b..8840acc3 100644 --- a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm +++ b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm
@@ -6,21 +6,25 @@ #include <AppKit/AppKit.h> +#include "base/mac/foundation_util.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "ui/gfx/range/range.h" namespace mojo { ui::mojom::blink::AttributedStringPtr -TypeConverter<ui::mojom::blink::AttributedStringPtr, NSAttributedString*>:: - Convert(const NSAttributedString* ns_attributed_string) { +TypeConverter<ui::mojom::blink::AttributedStringPtr, CFAttributedStringRef>:: + Convert(CFAttributedStringRef cf_attributed_string) { + NSAttributedString* ns_attributed_string = + base::mac::CFToNSCast(cf_attributed_string); + // Create the return value. ui::mojom::blink::AttributedStringPtr attributed_string = ui::mojom::blink::AttributedString::New(); - attributed_string->string = String([ns_attributed_string string]); + attributed_string->string = String(ns_attributed_string.string); // Iterate over all the attributes in the string. - NSUInteger length = [ns_attributed_string length]; + NSUInteger length = ns_attributed_string.length; for (NSUInteger i = 0; i < length;) { NSRange effective_range; NSDictionary* ns_attributes = @@ -32,8 +36,8 @@ float font_point_size; // Only encode the attributes if the filtered set contains font information. if (font) { - font_name = String([font fontName]); - font_point_size = [font pointSize]; + font_name = String(font.fontName); + font_point_size = font.pointSize; if (!font_name.empty()) { // Convert the attributes. ui::mojom::blink::FontAttributePtr attrs =
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 4d0551c..62ebc03 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -462,7 +462,6 @@ }, { name: "BlinkLifecycleScriptForbidden", - status: "experimental", }, { name: "BlinkRuntimeCallStats",
diff --git a/third_party/blink/renderer/platform/scheduler/public/main_thread.h b/third_party/blink/renderer/platform/scheduler/public/main_thread.h index 49b11b2..b496a5e 100644 --- a/third_party/blink/renderer/platform/scheduler/public/main_thread.h +++ b/third_party/blink/renderer/platform/scheduler/public/main_thread.h
@@ -16,10 +16,10 @@ class MainThreadTaskRunnerRestricted { private: // Permitted users of `MainThread::GetTaskRunner`. + friend class BlinkCategorizedWorkerPoolDelegate; friend class BlinkInitializer; friend class BlobBytesProvider; friend class CachedStorageArea; - friend class CategorizedWorkerPoolImpl; friend class FontCache; friend class InspectorNetworkAgent; friend class MemoryCache;
diff --git a/third_party/blink/renderer/platform/widget/compositing/DEPS b/third_party/blink/renderer/platform/widget/compositing/DEPS index 663dc26..43cc687b 100644 --- a/third_party/blink/renderer/platform/widget/compositing/DEPS +++ b/third_party/blink/renderer/platform/widget/compositing/DEPS
@@ -24,11 +24,4 @@ "+ui/native_theme/native_theme_features.h", "+ui/native_theme/overlay_scrollbar_constants_aura.h", ], - "categorized_worker_pool\.h": [ - "+base/task/task_runner.h", - "+base/threading/simple_thread.h", - ], - "categorized_worker_pool_unittest\.cc": [ - "+base/threading/simple_thread.h", - ], }
diff --git a/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc new file mode 100644 index 0000000..37010e6 --- /dev/null +++ b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc
@@ -0,0 +1,43 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h" + +#include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" +#include "build/build_config.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/scheduler/public/main_thread.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" + +namespace blink { + +BlinkCategorizedWorkerPoolDelegate::BlinkCategorizedWorkerPoolDelegate() = + default; + +BlinkCategorizedWorkerPoolDelegate::~BlinkCategorizedWorkerPoolDelegate() = + default; + +// static +BlinkCategorizedWorkerPoolDelegate& BlinkCategorizedWorkerPoolDelegate::Get() { + static base::NoDestructor<BlinkCategorizedWorkerPoolDelegate> delegate; + return *delegate; +} + +void BlinkCategorizedWorkerPoolDelegate::NotifyThreadWillRun( + base::PlatformThreadId tid) { +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + scoped_refptr<base::TaskRunner> task_runner = + Thread::MainThread()->GetTaskRunner(MainThreadTaskRunnerRestricted()); + task_runner->PostTask(FROM_HERE, base::BindOnce( + [](base::PlatformThreadId tid) { + Platform::Current()->SetThreadType( + tid, + base::ThreadType::kBackground); + }, + tid)); +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h new file mode 100644 index 0000000..fa2ace8 --- /dev/null +++ b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h
@@ -0,0 +1,28 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_ + +#include "base/functional/callback.h" +#include "cc/raster/categorized_worker_pool.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +class PLATFORM_EXPORT BlinkCategorizedWorkerPoolDelegate + : public cc::CategorizedWorkerPool::Delegate { + public: + BlinkCategorizedWorkerPoolDelegate(); + ~BlinkCategorizedWorkerPoolDelegate() override; + + static BlinkCategorizedWorkerPoolDelegate& Get(); + + // cc::CategorizedWorkerPool::Delegate: + void NotifyThreadWillRun(base::PlatformThreadId tid) override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index e8a1a182..7b92b2c2 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -14,6 +14,7 @@ #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/mojo_embedder/async_layer_tree_frame_sink.h" +#include "cc/raster/categorized_worker_pool.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/paint_holding_reason.h" @@ -42,7 +43,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/widget_scheduler.h" -#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h" +#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h" #include "third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.h" #include "third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h" #include "third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h" @@ -203,7 +204,8 @@ compositing_thread_scheduler ? compositing_thread_scheduler->DefaultTaskRunner() : nullptr, - CategorizedWorkerPool::GetOrCreate()); + cc::CategorizedWorkerPool::GetOrCreate( + &BlinkCategorizedWorkerPoolDelegate::Get())); FrameWidget* frame_widget = client_->FrameWidget();
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index dfee0b6..144db955 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -322,7 +322,8 @@ 'base::TestMockTimeTaskRunner', 'base::TickClock', - # cc painting types. + # cc painting and raster types. + 'cc::CategorizedWorkerPool', 'cc::InspectablePaintRecorder', 'cc::InspectableRecordPaintCanvas', 'cc::PaintCanvas',
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py index 5dfd119..9d781c52 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py +++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
@@ -11,18 +11,18 @@ import optparse import pathlib import urllib.parse -from typing import List, Optional, Set, Tuple, Type, Union +from typing import Collection, List, Optional, Set, Tuple, Type, Union from blinkpy.common import path_finder from blinkpy.common.host import Host from blinkpy.tool.commands.command import Command from blinkpy.w3c.wpt_manifest import WPTManifest -from blinkpy.tool.commands.update_metadata import BUG_PATTERN +from blinkpy.tool.commands.update_metadata import BUG_PATTERN, generate_configs path_finder.bootstrap_wpt_imports() from tools.lint import lint as wptlint from tools.lint import rules -from wptrunner import wptmanifest +from wptrunner import metadata, wptmanifest from wptrunner.manifestexpected import fuzzy_prop from wptrunner.wptmanifest import node as wptnode from wptrunner.wptmanifest.backends.static import Compiler @@ -161,14 +161,34 @@ class MetadataUnnecessaryCondition(MetadataRule): - name = 'META-UNNECESSARY-CONDITION' + name = 'META-CONDITIONS-UNNECESSARY' description = '%(section_type)s key %(key)r always has value %(value)r' to_fix = """ Express the key as an unconditional expression without `if`. """ +class MetadataUnreachableValue(MetadataRule): + name = 'META-UNREACHABLE-VALUE' + description = '%(section_type)s key %(key)r has an unused %(condition)s' + to_fix = """ + Check that at least one test configuration takes the condition branch. + """ + + +class MetadataUnknownProp(MetadataRule): + name = 'META-UNKNOWN-PROP' + description = ('%(section_type)s key %(key)r %(condition)s ' + 'uses unrecognized property %(prop)s') + to_fix = """ + Check that all property names are spelled correctly: + https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/web_platform_tests_wptrunner.md#conditional-values + """ + + LintError = Tuple[str, str, str, Optional[int]] +ValueNode = Union[wptnode.ValueNode, wptnode.AtomNode, wptnode.ListNode] +Condition = Optional[wptnode.Node] class LintWPT(Command): @@ -177,12 +197,15 @@ help_text = __doc__.strip().splitlines()[0] long_help = __doc__ - def __init__(self, tool: Host): + def __init__(self, + tool: Host, + configs: Optional[Collection[metadata.RunInfo]] = None): super().__init__() self._tool = tool self._fs = self._tool.filesystem self._default_port = self._tool.port_factory.get() self._finder = path_finder.PathFinder(self._fs) + self._configs = configs or generate_configs(self._tool) def parse_args(self, args: List[str]) -> Tuple[optparse.Values, List[str]]: # TODO(crbug.com/1431070): Migrate `blink_tool.py` to stdlib's @@ -226,7 +249,7 @@ return [MetadataBadSyntax.error(path, context, error.line)] test_type = manifest.get_test_type(test_path) if test_path else None - linter = MetadataLinter(path, test_type, manifest) + linter = MetadataLinter(path, test_type, manifest, self._configs) return linter.find_errors(ast) def _manifest(self, repo_root: str) -> WPTManifest: @@ -246,10 +269,12 @@ class MetadataLinter(Compiler): - def __init__(self, path: str, test_type: str, manifest: WPTManifest): + def __init__(self, path: str, test_type: str, manifest: WPTManifest, + configs: Collection[metadata.RunInfo]): self.path = path self.test_type = test_type self.manifest = manifest + self.configs = configs # `context` contains information about the current section type, # heading, and key as it becomes available during the traversal. It's # also provided to the error message formatter. @@ -324,20 +349,71 @@ else: self._check_conditions(node) - def _check_conditions(self, key_value_node: wptnode.KeyValueNode): - conditions = [] + def _get_conditional_values( + self, + key_value_node: wptnode.KeyValueNode, + ) -> Tuple[List[Condition], List[ValueNode]]: + conditions, values = [], [] for i, child in enumerate(key_value_node.children): if isinstance(child, wptnode.ConditionalNode): - cond_expr, value = child.children + condition, value = child.children else: assert i == len(key_value_node.children) - 1 - cond_expr, value = None, child - conditions.append((cond_expr, value)) - values = {self.visit(value) for _, value in conditions} - if len(conditions) > 1 and len(values) == 1: - (_, value), *_ = conditions + condition, value = None, child + conditions.append(condition) + values.append(value) + return conditions, values + + def _check_conditions(self, key_value_node: wptnode.KeyValueNode): + conditions, values = self._get_conditional_values(key_value_node) + # Reference conditions by index because they are not hashable. + conditions_not_taken = set(range(len(conditions))) + unique_values = set(map(self.visit, values)) + # Simulate conditional value resolution for each test configuration. + for config in self.configs: + for i, condition in enumerate(conditions): + try: + if self._eval_condition_taken(condition, config): + # Mark this condition as having been exercised. + conditions_not_taken.discard(i) + break + except KeyError as error: + self._error(MetadataUnknownProp, + prop=str(error), + condition=_format_condition(condition)) + # The conditional expression could not be evaluated because + # of an unknown property. Do not show an unactionable + # `META-UNREACHABLE-VALUE` error for this branch, but act + # as if this branch were not taken. + conditions_not_taken.discard(i) + else: + # Add a sentinel object to simulate no default (an empty value). + # This unique value forces `META-CONDITIONS-UNNECESSARY` to + # pass because at least one configuration falls through to the + # end. + # + # TODO(crbug.com/1406669): Add a special rule when + # `unique_values` is `expected: (PASS|OK)`, which can just be + # removed. + unique_values.add(object()) + + if (len([condition for condition in conditions if condition]) > 0 + and len(unique_values) == 1): self._error(MetadataUnnecessaryCondition, - value=_format_node(value)) + value=_format_node(values[0])) + else: + # No need to show that condition branches are unreachable if no + # conditions are necessary in the first place. + for i in conditions_not_taken: + self._error(MetadataUnreachableValue, + condition=_format_condition(conditions[i])) + + def _eval_condition_taken(self, condition: Condition, + run_info: metadata.RunInfo) -> bool: + if not condition: + return True + self.expr_data = run_info.data + return self.visit(condition) def visit_ListNode(self, node: wptnode.ListNode) -> Tuple[Union[bool, str]]: @@ -407,5 +483,12 @@ return MetadataBadValue.test_statuses +def _format_condition(condition: Condition) -> str: + if not condition: + return 'default condition' + formatted_expr = f'if {_format_node(condition)}' + return f'condition {formatted_expr!r}' + + def _format_node(node: wptnode.Node) -> str: return wptmanifest.serialize(node).splitlines()[0].strip()
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py index 733b6365..a8d1511d 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py +++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
@@ -15,6 +15,9 @@ from blinkpy.tool.commands.lint_wpt import LintError, LintWPT from blinkpy.common.system.log_testing import LoggingTestCase +path_finder.bootstrap_wpt_imports() +from wptrunner import metadata + class LintWPTTest(LoggingTestCase): def setUp(self): @@ -23,7 +26,28 @@ self.tool = MockBlinkTool() self.fs = self.tool.filesystem self.finder = path_finder.PathFinder(self.fs) - self.command = LintWPT(self.tool) + configs = [{ + 'os': 'mac', + 'flag_specific': None, + 'product': 'content_shell', + }, { + 'os': 'win', + 'flag_specific': None, + 'product': 'content_shell', + }, { + 'os': 'linux', + 'flag_specific': None, + 'product': 'content_shell', + }, { + 'os': 'linux', + 'flag_specific': None, + 'product': 'chrome', + }, { + 'os': 'linux', + 'flag_specific': 'fake-flag', + 'product': 'content_shell', + }] + self.command = LintWPT(self.tool, set(map(metadata.RunInfo, configs))) self.fs.write_text_file(self.finder.path_from_wpt_tests('lint.ignore'), '') self.fs.write_text_file( @@ -101,7 +125,10 @@ """\ [variant.html?foo=bar/abc] bug: crbug.com/12 - expected: ERROR + expected: + if os == "linux" and product == "chrome": [ERROR, TIMEOUT] + if os == "linux": ERROR + OK [variant.html?foo=baz] disabled: never completes expected: TIMEOUT @@ -334,29 +361,125 @@ self.assertEqual(description, "Subtest key 'expected' has invalid value 'CRASH'") - def test_metadata_unnecessary_conditions(self): - exp_error, fuzzy_error = self._check_metadata("""\ + def test_metadata_conditions_unnecessary(self): + exp_error, fuzzy_error, restart_error = self._check_metadata("""\ [reftest.html] disabled: + # Does not partition all configurations ('linux' falls through). if os == "mac": flaky - if os == "win": @False - flaky + if os == "win": flaky expected: + # Partition all configurations, but without using a default. if os == "mac": FAIL - FAIL + if os == "win": FAIL + if os == "linux": FAIL fuzzy: + # Partition all configurations using a default. if os == "win": [0-1;0-2, reftest-ref.html:20;200-300] [0-1;0-2, reftest-ref.html:20;200-300] + restart-after: + # Captures all configurations, but not using an unconditional + # value. + if os == "mac" or os != "mac": @True """) - # Note that `disabled` is not an error because of `os == "win"`. name, description, path, _ = exp_error - self.assertEqual(name, 'META-UNNECESSARY-CONDITION') + self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY') self.assertEqual(path, 'reftest.html.ini') self.assertEqual(description, "Test key 'expected' always has value 'FAIL'") name, description, path, _ = fuzzy_error - self.assertEqual(name, 'META-UNNECESSARY-CONDITION') + self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY') self.assertEqual(path, 'reftest.html.ini') self.assertEqual( description, "Test key 'fuzzy' always has value " "'[0-1;0-2, reftest-ref.html:20;200-300]'") + name, description, path, _ = restart_error + self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual(description, + "Test key 'restart-after' always has value '@True'") + + def test_metadata_condition_checks_exclusive(self): + conds_unnecessary, unreachable_value = self._check_metadata("""\ + [reftest.html] + disabled: + if os == "win": flaky + if os == "win": flaky + flaky + expected: + if os == "win": FAIL + if os == "win": [FAIL, PASS] + FAIL + """) + # Since the author should rewrite this key unconditionally as + # `disabled: flaky` anyway, there's no need to say that the second + # condition is unreachable. + name, description, path, _ = conds_unnecessary + self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual(description, + "Test key 'disabled' always has value 'flaky'") + # `META-CONDITIONS-UNNECESSARY` should determine necessity using all + # values, even unreachable ones, as unreachable values may become + # reachable if fixed. + name, description, path, _ = unreachable_value + self.assertEqual(name, 'META-UNREACHABLE-VALUE') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, + "Test key 'expected' has an unused condition 'if os == \"win\"'") + + def test_metadata_unreachable_value(self): + shadowed_narrow, always_false, unused_default = self._check_metadata( + """\ + [reftest.html] + expected: + if os == "win" and os == "mac": FAIL # Meant to say `or`. + # This branch shadows the next one, which is narrower. + if os == "linux": FAIL + if os == "linux" and product == "chrome": PASS + if os != "linux": FAIL + FAIL + """) + name, description, path, _ = always_false + self.assertEqual(name, 'META-UNREACHABLE-VALUE') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, "Test key 'expected' has an unused condition " + "'if (os == \"win\") and (os == \"mac\")'") + name, description, path, _ = shadowed_narrow + self.assertEqual(name, 'META-UNREACHABLE-VALUE') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, "Test key 'expected' has an unused condition " + "'if (os == \"linux\") and (product == \"chrome\")'") + name, description, path, _ = unused_default + self.assertEqual(name, 'META-UNREACHABLE-VALUE') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, "Test key 'expected' has an unused default condition") + + def test_metadata_unknown_prop(self): + os_error, product_error = self._check_metadata("""\ + [reftest.html] + disabled: + if oss == "win": wontfix + if os == "mac": wontfix + expected: + if os != "linux": PASS + # Should be detected even if the expression short-circuits. + if os == "linux" or prduct == "chrome": FAIL + """) + name, description, path, _ = os_error + self.assertEqual(name, 'META-UNKNOWN-PROP') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, "Test key 'disabled' condition 'if oss == \"win\"' " + "uses unrecognized property 'oss'") + name, description, path, _ = product_error + self.assertEqual(name, 'META-UNKNOWN-PROP') + self.assertEqual(path, 'reftest.html.ini') + self.assertEqual( + description, "Test key 'expected' condition " + "'if (os == \"linux\") or (prduct == \"chrome\")' " + "uses unrecognized property 'prduct'")
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py index 62fed88a..c19c75c2 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py +++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
@@ -170,7 +170,7 @@ manifests = load_and_update_manifests(self._path_finder) updater = MetadataUpdater.from_manifests( manifests, - self.generate_configs(), + generate_configs(self._tool), self._tool.filesystem, self._explicit_include_patterns(options, args), options.exclude, @@ -473,49 +473,47 @@ '%r is neither a regular file nor a directory' % value) setattr(parser.values, option.dest, reports) - def generate_configs(self) -> Dict[metadata.RunInfo, Port]: - """Construct run info representing all Chromium test environments. - Each property in a config represents a value that metadata keys can be - conditioned on (e.g., 'os'). - """ - configs = {} - wptrunner_builders = { - builder - for builder in self._tool.builders.all_builder_names() - if self._tool.builders.uses_wptrunner(builder) - } +def generate_configs(host: Host) -> Dict[metadata.RunInfo, Port]: + """Construct run info representing all Chromium test environments. - for builder in wptrunner_builders: - port_name = self._tool.builders.port_name_for_builder_name(builder) - _, build_config, *_ = self._tool.builders.specifiers_for_builder( - builder) + Each property in a config represents a value that metadata keys can be + conditioned on (e.g., 'os'). + """ + configs = {} + wptrunner_builders = { + builder + for builder in host.builders.all_builder_names() + if host.builders.uses_wptrunner(builder) + } - for step in self._tool.builders.step_names_for_builder(builder): - flag_specific = self._tool.builders.flag_specific_option( - builder, step) - port = self._tool.port_factory.get( - port_name, - optparse.Values({ - 'configuration': build_config, - 'flag_specific': flag_specific, - })) - product = self._tool.builders.product_for_build_step( - builder, step) - config = metadata.RunInfo({ - 'product': - product, - 'os': - port.operating_system(), - 'port': - port.version(), - 'debug': - port.get_option('configuration') == 'Debug', - 'flag_specific': - flag_specific or '', - }) - configs[config] = port - return configs + for builder in wptrunner_builders: + port_name = host.builders.port_name_for_builder_name(builder) + _, build_config, *_ = host.builders.specifiers_for_builder(builder) + + for step in host.builders.step_names_for_builder(builder): + flag_specific = host.builders.flag_specific_option(builder, step) + port = host.port_factory.get( + port_name, + optparse.Values({ + 'configuration': build_config, + 'flag_specific': flag_specific, + })) + product = host.builders.product_for_build_step(builder, step) + config = metadata.RunInfo({ + 'product': + product, + 'os': + port.operating_system(), + 'port': + port.version(), + 'debug': + port.get_option('configuration') == 'Debug', + 'flag_specific': + flag_specific or '', + }) + configs[config] = port + return configs class UpdateAbortError(Exception):
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py index 94b11da..3d09e1a 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py +++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
@@ -18,6 +18,7 @@ from blinkpy.tool.commands.update_metadata import ( UpdateMetadata, MetadataUpdater, + generate_configs, load_and_update_manifests, sort_metadata_ast, ) @@ -561,7 +562,7 @@ def test_generate_configs(self): linux, linux_highdpi, mac = sorted( - self.command.generate_configs(), + generate_configs(self.tool), key=lambda config: (config['os'], config['flag_specific'])) self.assertEqual(linux['os'], 'linux')
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html new file mode 100644 index 0000000..4edf112e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;"> + <div style="position:relative; overflow-y:clip; height:200px;"> + <div style="position:absolute; width:100%; height:300px;"> + <div style="height:200px; background:green;"></div> + <div style="height:200px; background:red;"></div> + </div> + <div style="height:1000px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html new file mode 100644 index 0000000..1eb1144 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;"> + <div style="position:relative; overflow-y:clip; height:200px;"> + <div style="height:150px;"></div> + <div style="position:absolute; top:0; width:100%; height:300px;"> + <div style="height:200px; background:green;"></div> + <div style="height:200px; background:red;"></div> + </div> + <div style="height:1000px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html new file mode 100644 index 0000000..4314c01 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;"> + <div style="position:relative; overflow-y:clip; height:200px;"> + <div style="height:150px;"></div> + <div style="position:absolute; top:-100px; width:100%; height:300px;"> + <div style="height:100px; background:red;"></div> + <div style="height:200px; background:green;"></div> + <div style="height:200px; background:red;"></div> + </div> + <div style="height:1000px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html b/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html new file mode 100644 index 0000000..1c2bc9e3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html
@@ -0,0 +1,63 @@ +<!DOCTYPE html> +<title> + Element#requestFullscreen() does not affect Screen sizes +</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../trusted-click.js"></script> +<body></body> +<script> + promise_test(async (t) => { + const screenWidth = window.screen.width; + const screenHeight = window.screen.height; + + if ('onchange' in window.screen) { + window.screen.onchange = () => { + assert_equals(window.screen.width, screenWidth); + assert_equals(window.screen.height, screenHeight); + } + t.add_cleanup(() => { window.screen.onchange = null; }); + } + + // Await a test_driver or manual click, fullscreen promise, and change. + await Promise.all([trusted_request(), fullScreenChange()]); + t.add_cleanup(() => { document.exitFullscreen(); }); + assert_not_equals(document.fullscreenElement, null); + + // Ensure the screen size is unchanged during fullscreen. + assert_equals(window.screen.width, screenWidth); + assert_equals(window.screen.height, screenHeight); + }, "Screen size is unchanged during element fullscreen"); + + promise_test(async (t) => { + const screenWidth = window.screen.width; + const screenHeight = window.screen.height; + + if ('onchange' in window.screen) { + window.screen.onchange = () => { + assert_equals(window.screen.width, screenWidth); + assert_equals(window.screen.height, screenHeight); + } + t.add_cleanup(() => { window.screen.onchange = null; }); + } + + // Await a test_driver or manual click to start tab content capture. + await trusted_click(); + const stream = await navigator.mediaDevices.getDisplayMedia( + {video:{displaySurface:"browser"}, selfBrowserSurface:"include"}); + const capabilities = stream.getVideoTracks()[0].getCapabilities(); + assert_equals(capabilities.displaySurface, "browser"); + t.add_cleanup(() => { stream.getTracks().forEach(t => t.stop()) }); + + // Await a test_driver or manual click, fullscreen promise, and change. + await Promise.all([trusted_request(), fullScreenChange()]); + t.add_cleanup(() => { document.exitFullscreen(); }); + assert_not_equals(document.fullscreenElement, null); + + // Ensure the screen size is unchanged during tab-capture fullscreen. + assert_equals(window.screen.width, screenWidth); + assert_equals(window.screen.height, screenHeight); + }, "Screen size is unchanged during tab-capture element fullscreen"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html index 62226d7d..8327b5c 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -4,71 +4,33 @@ <h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1> <p class="desc">Test CanvasFilter() dropShadow object.</p> -<style> - .background { - background-color: teal; - position: absolute; - left: 0px; - width: 620px; - height: 50px; - } +<svg width=620 height=320 xmlns="http://www.w3.org/2000/svg"> + <rect x=0 y=0 width=100% height=50 fill="teal" /> + <rect x=0 y=100 width=100% height=50 fill="teal" /> + <rect x=0 y=200 width=100% height=50 fill="teal" /> - .testcase { - position: absolute; - background-color: crimson; - width: 80px; - height: 80px; - } -</style> + <rect x=10 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(2px 2px 2px black)"/> + <rect x=110 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/> -<div style="position: relative"> - <div class="background" style="top: 0px;"></div> - <div class="background" style="top: 100px;"></div> - <div class="background" style="top: 200px;"></div> + <rect x=10 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 10px 3px purple)"/> + <rect x=110 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px LinkText)"/> + <rect x=210 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 15px 0px purple)"/> + <rect x=310 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/> + <rect x=410 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/> + <rect x=510 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/> - <div class="testcase" - style="left: 10px; top: 10px; - filter: drop-shadow(2px 2px 2px black);"> - </div> - <div class="testcase" - style="left: 110px; top: 10px; - filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));"> - </div> - <div class="testcase" - style="left: 10px; top: 110px; - filter: drop-shadow(10px 10px 3px purple)"> - </div> - <div class="testcase" - style="left: 110px; top: 110px; - filter: drop-shadow(15px 10px 3px LinkText)"> - </div> - <div class="testcase" - style="left: 210px; top: 110px; - filter: drop-shadow(10px 15px 0px purple)"> - </div> - <div class="testcase" - style="left: 310px; top: 110px; - filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"> - </div> - <div class="testcase" - style="left: 410px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"> - </div> - <div class="testcase" - style="left: 510px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"> - </div> - - <div class="testcase" - style="left: 10px; top: 210px; - filter: drop-shadow(-5px 0px 0px purple);"> - </div> - <div class="testcase" - style="left: 110px; top: 210px; - filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));"> - </div> - <div class="testcase" - style="left: 210px; top: 210px; - filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));"> - </div> -</div> + <rect x=10 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(-5px 0px 0px purple)"/> + <rect x=110 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/> + <rect x=210 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html index 62226d7d..8327b5c 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -4,71 +4,33 @@ <h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1> <p class="desc">Test CanvasFilter() dropShadow object.</p> -<style> - .background { - background-color: teal; - position: absolute; - left: 0px; - width: 620px; - height: 50px; - } +<svg width=620 height=320 xmlns="http://www.w3.org/2000/svg"> + <rect x=0 y=0 width=100% height=50 fill="teal" /> + <rect x=0 y=100 width=100% height=50 fill="teal" /> + <rect x=0 y=200 width=100% height=50 fill="teal" /> - .testcase { - position: absolute; - background-color: crimson; - width: 80px; - height: 80px; - } -</style> + <rect x=10 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(2px 2px 2px black)"/> + <rect x=110 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/> -<div style="position: relative"> - <div class="background" style="top: 0px;"></div> - <div class="background" style="top: 100px;"></div> - <div class="background" style="top: 200px;"></div> + <rect x=10 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 10px 3px purple)"/> + <rect x=110 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px LinkText)"/> + <rect x=210 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 15px 0px purple)"/> + <rect x=310 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/> + <rect x=410 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/> + <rect x=510 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/> - <div class="testcase" - style="left: 10px; top: 10px; - filter: drop-shadow(2px 2px 2px black);"> - </div> - <div class="testcase" - style="left: 110px; top: 10px; - filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));"> - </div> - <div class="testcase" - style="left: 10px; top: 110px; - filter: drop-shadow(10px 10px 3px purple)"> - </div> - <div class="testcase" - style="left: 110px; top: 110px; - filter: drop-shadow(15px 10px 3px LinkText)"> - </div> - <div class="testcase" - style="left: 210px; top: 110px; - filter: drop-shadow(10px 15px 0px purple)"> - </div> - <div class="testcase" - style="left: 310px; top: 110px; - filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"> - </div> - <div class="testcase" - style="left: 410px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"> - </div> - <div class="testcase" - style="left: 510px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"> - </div> - - <div class="testcase" - style="left: 10px; top: 210px; - filter: drop-shadow(-5px 0px 0px purple);"> - </div> - <div class="testcase" - style="left: 110px; top: 210px; - filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));"> - </div> - <div class="testcase" - style="left: 210px; top: 210px; - filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));"> - </div> -</div> + <rect x=10 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(-5px 0px 0px purple)"/> + <rect x=110 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/> + <rect x=210 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml index 46171c1..246b73e 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
@@ -420,74 +420,36 @@ floodColor: 'purple', floodOpacity: ['0.4']}); ctx.fillRect(210, 210, 80, 80); html_reference: | - <style> - .background { - background-color: teal; - position: absolute; - left: 0px; - width: 620px; - height: 50px; - } + <svg width=620 height=320 xmlns="http://www.w3.org/2000/svg"> + <rect x=0 y=0 width=100% height=50 fill="teal" /> + <rect x=0 y=100 width=100% height=50 fill="teal" /> + <rect x=0 y=200 width=100% height=50 fill="teal" /> - .testcase { - position: absolute; - background-color: crimson; - width: 80px; - height: 80px; - } - </style> + <rect x=10 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(2px 2px 2px black)"/> + <rect x=110 y=10 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/> - <div style="position: relative"> - <div class="background" style="top: 0px;"></div> - <div class="background" style="top: 100px;"></div> - <div class="background" style="top: 200px;"></div> + <rect x=10 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 10px 3px purple)"/> + <rect x=110 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px LinkText)"/> + <rect x=210 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(10px 15px 0px purple)"/> + <rect x=310 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/> + <rect x=410 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/> + <rect x=510 y=110 width=80 height=80 fill="crimson" + style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/> - <div class="testcase" - style="left: 10px; top: 10px; - filter: drop-shadow(2px 2px 2px black);"> - </div> - <div class="testcase" - style="left: 110px; top: 10px; - filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));"> - </div> - <div class="testcase" - style="left: 10px; top: 110px; - filter: drop-shadow(10px 10px 3px purple)"> - </div> - <div class="testcase" - style="left: 110px; top: 110px; - filter: drop-shadow(15px 10px 3px LinkText)"> - </div> - <div class="testcase" - style="left: 210px; top: 110px; - filter: drop-shadow(10px 15px 0px purple)"> - </div> - <div class="testcase" - style="left: 310px; top: 110px; - filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"> - </div> - <div class="testcase" - style="left: 410px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"> - </div> - <div class="testcase" - style="left: 510px; top: 110px; - filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"> - </div> - - <div class="testcase" - style="left: 10px; top: 210px; - filter: drop-shadow(-5px 0px 0px purple);"> - </div> - <div class="testcase" - style="left: 110px; top: 210px; - filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));"> - </div> - <div class="testcase" - style="left: 210px; top: 210px; - filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));"> - </div> - </div> + <rect x=10 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(-5px 0px 0px purple)"/> + <rect x=110 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/> + <rect x=210 y=210 width=80 height=80 fill="crimson" + style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> + </svg> - name: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative desc: Test exceptions on CanvasFilter() dropShadow object
diff --git a/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html b/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html new file mode 100644 index 0000000..7ddf02f86 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html
@@ -0,0 +1,10 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script> + test(t => { + assert_equals(window.sharedStorage, undefined); + }, 'test window.sharedStorage in insecure context'); + </script> +</body>
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html index b256266..3d18d61 100644 --- a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html +++ b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html
@@ -5,7 +5,7 @@ <script type="module"> import {AuthenticatorStatus} from '/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom.m.js'; import {MockAuthenticator} from './resources/mock-navigator-credentials.js'; -import {assertValidMakeCredentialResponse, ATTESTATION_OBJECT, CABLE_AUTHENTICATION, CABLE_REGISTRATION, CLIENT_DATA_JSON, deepCopy, ID, MAKE_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js'; +import {assertValidMakeCredentialResponse, ATTESTATION_OBJECT, CABLE_AUTHENTICATION, CLIENT_DATA_JSON, deepCopy, ID, MAKE_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js'; if (document.location.host != "subdomain.example.test:8443") { document.location = "https://subdomain.example.test:8443/credentialmanagement/credentialscontainer-create-basics.html"; @@ -227,16 +227,6 @@ mockAuthenticator.reset(); mockAuthenticator.setDefaultsForSuccessfulMakeCredential(); var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS); - customMakeCredOptions.extensions = {cableRegistration: CABLE_REGISTRATION}; - return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => { - assertValidMakeCredentialResponse(r); - }); -}, "navigator.credentials.create() with cableRegistration extension"); - -promise_test(t => { - mockAuthenticator.reset(); - mockAuthenticator.setDefaultsForSuccessfulMakeCredential(); - var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS); customMakeCredOptions.extensions = {cableAuthentication: [CABLE_AUTHENTICATION]}; return promise_rejects_dom(t, "NotSupportedError", navigator.credentials.create({publicKey : customMakeCredOptions}));
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html index 08347df..f191fe2 100644 --- a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html +++ b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html
@@ -6,7 +6,7 @@ import {SmsStatus} from '/gen/third_party/blink/public/mojom/sms/webotp_service.mojom.m.js'; import {AuthenticatorStatus} from '/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom.m.js'; import {MockAuthenticator, MockCredentialManager, MockWebOTPService} from './resources/mock-navigator-credentials.js'; -import {assertValidGetCredentialResponse, CABLE_AUTHENTICATION, CABLE_REGISTRATION, deepCopy, GET_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js'; +import {assertValidGetCredentialResponse, CABLE_AUTHENTICATION, deepCopy, GET_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js'; if (document.location.host != "subdomain.example.test:8443") { document.location = "https://subdomain.example.test:8443/credentialmanagement/credentialscontainer-get-basics.html"; @@ -242,15 +242,6 @@ }); }, "navigator.credentials.get() with missing user verification requirement"); -promise_test(t => { - mockAuthenticator.reset(); - mockAuthenticator.setDefaultsForSuccessfulGetAssertion(); - var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS); - customGetCredentialOptions.extensions = {cableRegistration: CABLE_REGISTRATION}; - return promise_rejects_dom(t, "NotSupportedError", - navigator.credentials.get({ publicKey : customGetCredentialOptions})); -}, "navigator.credentials.get() with cableRegistration extension not supported"); - promise_test(_ => { mockAuthenticator.reset(); mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js b/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js index 04d30e2a..83c351f 100644 --- a/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js +++ b/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js
@@ -57,10 +57,6 @@ export const AUTHENTICATOR_DATA = new TextEncoder("utf-8").encode("authenticatorData"); export const SIGNATURE = new TextEncoder("utf-8").encode("signature"); -export const CABLE_REGISTRATION = { - versions: [1], - rpPublicKey: new TextEncoder("utf-8").encode("SixteenByteRpKey"), -}; export const CABLE_AUTHENTICATION = { version: 1,
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/add-module.html b/third_party/blink/web_tests/wpt_internal/shared_storage/add-module.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/add-module.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/add-module.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/setters.html b/third_party/blink/web_tests/wpt_internal/shared_storage/setters.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/shared_storage/setters.html rename to third_party/blink/web_tests/wpt_internal/shared_storage/setters.https.html
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index be0c3b4..8b413d6 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby -Version: 472a1d847b581b73bb577de6a063214606d9a685 +Version: b023a666b95f94be4f9b2070c4d0055ced78ea19 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/tools/clang/scripts/upload_revision.py b/tools/clang/scripts/upload_revision.py index d904c2e1f..acbb5c27 100755 --- a/tools/clang/scripts/upload_revision.py +++ b/tools/clang/scripts/upload_revision.py
@@ -49,6 +49,10 @@ 'mac_upload_clang', 'mac_upload_clang_arm', 'win_upload_clang', + 'linux_upload_rust', + 'mac_upload_rust', + 'mac_upload_rust_arm', + 'win_upload_rust', ] # Keep lines in here at <= 72 columns, else they wrap in gerrit.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index c5544856..c4de8e5 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -47,6 +47,11 @@ 'linux-password-manager-captured-sites-rel': 'release_bot', }, + 'chrome.gpu.fyi': { + 'Lacros FYI Release (eve)': 'gpu_fyi_tests_lacros_eve_release_trybot_dcheck_off_no_symbols_reclient', + 'Lacros FYI Release (jacuzzi)': 'gpu_fyi_tests_lacros_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient', + }, + 'chrome.pgo': { 'android-arm32-pgo': 'official_reclient_android_arm32_pgo', 'android-arm64-pgo': 'official_reclient_android_arm64_pgo', @@ -385,7 +390,7 @@ 'build2': 'ios_simulator_debug_static_bot_xctest_reclient', }, 'Linux Builder (j-500) (reclient)': 'gpu_tests_release_bot_reclient', - 'Linux Builder (reclient compare)': 'gpu_tests_release_bot_remote_links_small_reclient', + 'Linux Builder (reclient compare)': 'gpu_tests_release_bot_reclient', 'Linux Viz': 'release_trybot_minimal_symbols_reclient', # TODO(crbug.com/1260232): remove this after the migration. 'Mac Builder (reclient compare)': 'gpu_tests_release_bot_minimal_symbols_reclient', @@ -921,10 +926,6 @@ 'fuchsia-x64': 'official_fuchsia_x64', }, - 'official.chrome.continuous': { - 'chromeos-amd64-generic-lacros-internal': 'chromeos_amd64-generic_lacros_official', - }, - 'tryserver.blink': { # Most tryservers should have '_trybot' in their config names, but # 'release_trybot' includes 'dcheck_always_on', and the blink @@ -2636,6 +2637,16 @@ 'gpu_fyi_tests', 'dx12vk', 'release_trybot_minimal_symbols_reclient', 'disable_nacl', ], + 'gpu_fyi_tests_lacros_eve_release_trybot_dcheck_off_no_symbols_reclient': [ + 'chromeos', 'eve', 'official', 'release_bot_reclient','no_symbols', + 'chromeos_device_reclient', 'also_build_lacros_chrome_for_architecture_amd64', + ], + + 'gpu_fyi_tests_lacros_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient': [ + 'chromeos', 'jacuzzi', 'official', 'release_bot_reclient', 'no_symbols', + 'chromeos_device_reclient', 'also_build_lacros_chrome_for_architecture_arm', + ], + 'gpu_fyi_tests_release_trybot_arm64_reclient': [ 'gpu_fyi_tests', 'release_trybot_minimal_symbols_reclient', 'arm64', 'disable_nacl', ],
diff --git a/tools/mb/mb_config_expectations/chrome.gpu.fyi.json b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json new file mode 100644 index 0000000..9fb2cdb --- /dev/null +++ b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json
@@ -0,0 +1,32 @@ +{ + "Lacros FYI Release (eve)": { + "args_file": "//build/args/chromeos/eve.gni", + "gn_args": { + "also_build_lacros_chrome_for_architecture": "amd64", + "dcheck_always_on": false, + "is_chrome_branded": true, + "is_chromeos_device": true, + "is_component_build": false, + "is_debug": false, + "is_official_build": true, + "symbol_level": 0, + "target_os": "chromeos", + "use_remoteexec": true + } + }, + "Lacros FYI Release (jacuzzi)": { + "args_file": "//build/args/chromeos/jacuzzi.gni", + "gn_args": { + "also_build_lacros_chrome_for_architecture": "arm", + "dcheck_always_on": false, + "is_chrome_branded": true, + "is_chromeos_device": true, + "is_component_build": false, + "is_debug": false, + "is_official_build": true, + "symbol_level": 0, + "target_os": "chromeos", + "use_remoteexec": true + } + } +} \ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 83745eee8..27a2e7a 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -243,15 +243,12 @@ }, "Linux Builder (reclient compare)": { "gn_args": { - "concurrent_links": 50, "dcheck_always_on": false, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, - "rbe_link_cfg_file": "../../buildtools/reclient_cfgs/rewrapper_linux_link.cfg", - "use_remoteexec": true, - "use_remoteexec_links": true + "use_remoteexec": true } }, "Linux Viz": {
diff --git a/tools/mb/mb_config_expectations/official.chrome.continuous.json b/tools/mb/mb_config_expectations/official.chrome.continuous.json deleted file mode 100644 index 080a886..0000000 --- a/tools/mb/mb_config_expectations/official.chrome.continuous.json +++ /dev/null
@@ -1,18 +0,0 @@ -{ - "chromeos-amd64-generic-lacros-internal": { - "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni", - "gn_args": { - "chromeos_is_browser_only": true, - "dcheck_always_on": false, - "is_cfi": true, - "is_chrome_branded": true, - "is_chromeos_device": true, - "is_official_build": true, - "ozone_platform_headless": true, - "symbol_level": 1, - "target_os": "chromeos", - "use_goma": true, - "use_thin_lto": true - } - } -} \ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c4e6c9f..e3d87b5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -11925,9 +11925,9 @@ <enum name="BookmarksSidePanelSortType"> <int value="0" label="Newest"/> <int value="1" label="Oldest"/> - <int value="2" label="Alphabetical"/> - <int value="3" label="Reverse Alphabetical"/> - <int value="4" label="Last Opened"/> + <int value="2" label="Last Opened"/> + <int value="3" label="Alphabetical"/> + <int value="4" label="Reverse Alphabetical"/> </enum> <enum name="BookmarksSidePanelViewType"> @@ -94505,29 +94505,13 @@ <int value="1" label="Fail to create shortcut"/> </enum> -<enum name="ShortcutsMenuRegistrationWinResult"> - <obsolete> - Removed January 2021. - </obsolete> - <summary> - Result of registering app icon shortcuts menu for PWA on Windows - </summary> +<enum name="ShortcutsMenuWinRegistrationResult"> <int value="0" label="Success"/> - <int value="1" label="Failed to write ico files to disk"/> - <int value="2" label="Failed to BeginUpdate"/> - <int value="3" label="Failed to AddTasks"/> - <int value="4" label="Failed to CommitUpdate"/> -</enum> - -<enum name="ShortcutsMenuUnregistrationWinResult"> - <obsolete> - Removed January 2021. - </obsolete> - <summary> - Result of registering app icon shortcuts menu for PWA on Windows - </summary> - <int value="0" label="Success"/> - <int value="1" label="Failed to DeleteJumpList"/> + <int value="1" label="Failed to create shortcuts menu icons directory"/> + <int value="2" label="Failed to create icon from image family"/> + <int value="3" label="Failed to begin jump list update"/> + <int value="4" label="Failed to add link items to jump list"/> + <int value="5" label="Failed to commit update to jump list"/> </enum> <enum name="ShortProcessType">
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 89fe8ca..9c0db18d 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -357,13 +357,13 @@ <histogram name="Compositing.Display.HardwareDisplayController.SchedulePageFlipResult" - enum="PageFlipResult" expires_after="2023-03-02"> - <owner>jshargo@chromium.org</owner> + enum="PageFlipResult" expires_after="2024-03-02"> <owner>seanpaul@chromium.org</owner> <owner>chromeos-gfx-compositor@chromium.org</owner> <summary> Logged once per frame, represents whether we could successfully schedule a - page flip, or what error we encountered along the way. + page flip, or what error we encountered along the way. Note: this metric was + expired from 2023-03-02 to 2023-04-13. </summary> </histogram> @@ -461,10 +461,14 @@ <histogram name="Compositing.Display.OverlayProcessorUsingStrategy.NumOverlays{Counted}" - units="overlay candidates" expires_after="2022-11-30"> + units="overlay candidates" expires_after="2023-11-30"> <owner>khaslett@chromium.org</owner> <owner>kylechar@chromium.org</owner> - <summary>Logged once per frame, the number of overlays {Counted}</summary> + <owner>chromeos-gfx-compositor@chromium.org</owner> + <summary> + Logged once per frame, the number of overlays {Counted}. Note: this metric + was expired from 2022-11-30 to 2023-04-13. + </summary> <token key="Counted"> <variant name="Attempted" summary="attempted. This is only logged when using the @@ -510,6 +514,17 @@ </summary> </histogram> +<histogram name="Compositing.Display.PendingSwaps" units="swaps" + expires_after="2024-04-11"> + <owner>sashamcintosh@chromium.org</owner> + <owner>chromeos-gfx@chromium.org</owner> + <summary> + Records the count of pending swaps in the display scheduler. Length of the + swap chain can be used as a rough approximation for input latency. Recorded + before the swap executes. Refer to Display::DrawAndSwap for details. + </summary> +</histogram> + <histogram name="Compositing.Display.VizDependencyResolvedToGpuStartedDrawUs" units="microseconds" expires_after="2022-12-18"> <owner>vasilyt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index f479274b..39e9326 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1701,6 +1701,20 @@ </token> </histogram> +<histogram name="Viz.FrameSink.GpuBusyDuration" units="microseconds" + expires_after="2024-04-11"> + <owner>sashamcintosh@chromium.org</owner> + <owner>chromeos-gfx@chromium.org</owner> + <summary> + The time that a begin frame is throttled due to max pending swaps. Recorded + when draw and swap executes (only when a frame is throttled). Refer to + BeginFrameSource::SetIsGpuBusy for details. + + Warning: This metric does not include reports from clients with + low-resolution clocks. + </summary> +</histogram> + <histogram name="Viz.FrameSinkVideoCapturer.CaptureDuration" units="ms" expires_after="2023-07-15"> <owner>bialpio@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index d14ea260..4f5c0dc 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -300,6 +300,17 @@ </summary> </histogram> +<histogram name="SafeBrowsing.BrowserThrottle.RedirectedOriginalUrlScheme" + enum="SafeBrowsingUrlScheme" expires_after="2023-07-12"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Logs the scheme of the original URL that is redirected. Logged each time + browser URL loader throttle receives a redirect request. This histogram can + help us determine what scheme is safe to skip when the request starts. + </summary> +</histogram> + <histogram name="SafeBrowsing.BrowserThrottle.TotalDelay" units="ms" expires_after="2023-09-17"> <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml index 33a4427..acb44aa 100644 --- a/tools/metrics/histograms/metadata/webapps/histograms.xml +++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -1384,6 +1384,16 @@ </summary> </histogram> +<histogram name="WebApp.ShortcutsMenu.Win.Results" + enum="ShortcutsMenuWinRegistrationResult" expires_after="2024-04-10"> + <owner>dibyapal@chromium.org</owner> + <owner>desktop-pwas-team@google.com</owner> + <summary> + Records the different results (both failure and success) that contributes to + shortcuts menu registration on Windows. + </summary> +</histogram> + <histogram name="WebApp.ShortcutsMenuRegistration.Result" enum="BooleanSuccess" expires_after="2023-09-10"> <owner>dibyapal@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index e9f31cf..6096b69 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -1180,6 +1180,9 @@ </metric> <metric name="SubFrame.LayoutInstability.CumulativeShiftScore"> <summary> + Deprecated as of 04/23. It is still reported, but most users should use + AmpPageLoad.SubFrame.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms. + Measures the cumulative layout shift (bit.ly/lsm-explainer) that has occurred during the session, in the AMP subframe. This metric's integral value is 100x the fractional cumulative layout shift score described in @@ -10698,6 +10701,9 @@ </metric> <metric name="CumulativeShiftScoreAfterBackForwardCacheRestore"> <summary> + Deprecated as of 04/23. It is still reported, but most users should use + PageLoad.LayoutInstability.MaxCumulativeShiftScore.AfterBackForwardCacheRestore.SessionWindow.Gap1000ms.Max5000ms. + Measures the cumulative layout shift (bit.ly/3fQz29y) that has occurred during the session, after the page is restored from the back-forward cache. This metric's integral value is 100x the fractional cumulative @@ -16016,6 +16022,9 @@ </metric> <metric name="LayoutInstability.CumulativeShiftScore"> <summary> + Deprecated as of 04/23. It is still reported, but most users should use + PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms. + Measures the cumulative layout shift (bit.ly/lsm-explainer) that has occurred on the page (including all subframes) during the session. This metric's integral value is 100x the fractional cumulative layout shift
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index c089caf0..98e1ef1 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@ "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm64/trace_processor_shell" }, "win": { - "hash": "82a32facded20e5c34bf09833eed3c66fc0bcbbc", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell.exe" + "hash": "daedf5a7cc393fcae54504ad1e553bbaa6df7865", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1c46d9577664f7cd811b4fe9c884f66a99697615/trace_processor_shell.exe" }, "linux_arm": { "hash": "1d229abc94dea54ab4bb4327e78e18f942d08bf9", "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm/trace_processor_shell" }, "mac": { - "hash": "6edc909e16765b71ac1cee1879f128cefd462588", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell" + "hash": "75f30b60b6f93968be7e00e147841d6c2a450fa2", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/1c46d9577664f7cd811b4fe9c884f66a99697615/trace_processor_shell" }, "mac_arm64": { "hash": "7a4026b8718994145a52586fdec6e9447573345a", "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "dfe4c313e49ac49d4d631f444f2a95d9dd27055f", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell" + "hash": "da16e9da095315beeb331c2736f4933b48938dbe", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/fe416a62fd4b3a04c0efa38dcfe365fd1611ae6d/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index ee38f17..958bed82 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -43,6 +43,9 @@ "screen_android.h", "toast_manager.cc", "ui_android_export.h", + "ui_android_feature_list.cc", + "ui_android_features.cc", + "ui_android_features.h", "view_android.cc", "view_android.h", "view_android_observer.h", @@ -79,6 +82,18 @@ ] } +java_cpp_features("java_features_srcjar") { + # External code should depend on ":android_java" instead. + visibility = [ ":*" ] + sources = [ "//ui/android/ui_android_features.cc" ] + template = "//ui/android/java_templates/UiAndroidFeatures.java.tmpl" +} + +# A minimal library used to expose ui features to webview +android_library("ui_android_features_java") { + srcjar_deps = [ ":java_features_srcjar" ] +} + static_library("test_support") { testonly = true sources = [ @@ -96,6 +111,7 @@ sources = [ "java/src/org/chromium/ui/OverscrollRefreshHandler.java", "java/src/org/chromium/ui/base/EventForwarder.java", + "java/src/org/chromium/ui/base/UiAndroidFeatureList.java", "java/src/org/chromium/ui/base/ViewAndroidDelegate.java", "java/src/org/chromium/ui/base/WindowAndroid.java", "java/src/org/chromium/ui/display/DisplayAndroidManager.java", @@ -273,6 +289,7 @@ "java/src/org/chromium/ui/base/SPenSupport.java", "java/src/org/chromium/ui/base/SelectFileDialog.java", "java/src/org/chromium/ui/base/TouchDevice.java", + "java/src/org/chromium/ui/base/UiAndroidFeatureList.java", "java/src/org/chromium/ui/base/ViewAndroidDelegate.java", "java/src/org/chromium/ui/base/ViewUtils.java", "java/src/org/chromium/ui/base/ViewportInsets.java", @@ -381,6 +398,7 @@ "java/src/org/chromium/ui/widget/ViewRectProvider.java", ] deps = [ + ":ui_android_features_java", ":ui_java_resources", ":ui_utils_java", "//base:base_java", @@ -504,6 +522,7 @@ "junit/src/org/chromium/ui/AsyncViewStubTest.java", "junit/src/org/chromium/ui/base/ApplicationViewportInsetSupplierTest.java", "junit/src/org/chromium/ui/base/ClipboardTest.java", + "junit/src/org/chromium/ui/base/EventForwarderTest.java", "junit/src/org/chromium/ui/base/EventOffsetHandlerTest.java", "junit/src/org/chromium/ui/base/LocalizationUtilsTest.java", "junit/src/org/chromium/ui/base/MimeTypeUtilsTest.java",
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java index cef17b0..bc9d60e 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java +++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -28,13 +28,12 @@ import java.lang.reflect.UndeclaredThrowableException; -/** - * Class used to forward view, input events down to native. - */ +/** Class used to forward view, input events down to native. */ @JNINamespace("ui") public class EventForwarder { private static final String TAG = "EventForwarder"; private final boolean mIsDragDropEnabled; + private final boolean mConvertTrackpadEventsToMouse; private long mNativeEventForwarder; @@ -50,9 +49,7 @@ // Delegate to call WebContents functionality. private StylusWritingDelegate mStylusWritingDelegate; - /** - * Interface to provide stylus writing functionality. - */ + /** Interface to provide stylus writing functionality. */ public interface StylusWritingDelegate { /** * Handle touch events for stylus handwriting. @@ -80,12 +77,16 @@ @CalledByNative private static EventForwarder create(long nativeEventForwarder, boolean isDragDropEnabled) { - return new EventForwarder(nativeEventForwarder, isDragDropEnabled); + return new EventForwarder(nativeEventForwarder, isDragDropEnabled, + UiAndroidFeatureList.isEnabled(UiAndroidFeatures.CONVERT_TRACKPAD_EVENTS_TO_MOUSE)); } - private EventForwarder(long nativeEventForwarder, boolean isDragDropEnabled) { + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + EventForwarder(long nativeEventForwarder, boolean isDragDropEnabled, + boolean convertTrackpadEventsToMouse) { mNativeEventForwarder = nativeEventForwarder; mIsDragDropEnabled = isDragDropEnabled; + mConvertTrackpadEventsToMouse = convertTrackpadEventsToMouse; } @CalledByNative @@ -141,18 +142,40 @@ logActionDown(event); } - if (mStylusWritingDelegate != null && mStylusWritingDelegate.handleTouchEvent(event)) { - // Stylus writing system can consume the touch events once writing is started. + if (touchEventRequiresSpecialHandling(event)) { return true; } - // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here? - // crbug.com/592082 - if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { - // Skip firing mouse events in the follwoing cases: + final boolean isTouchHandleEvent = false; + return sendTouchEvent(event, isTouchHandleEvent); + } + + /** + * Called by PopupWindow-based touch handles. + * + * @param event the MotionEvent targeting the handle. + */ + public boolean onTouchHandleEvent(MotionEvent event) { + final boolean isTouchHandleEvent = true; + return sendTouchEvent(event, isTouchHandleEvent); + } + + private boolean touchEventRequiresSpecialHandling(MotionEvent event) { + if (mStylusWritingDelegate != null && mStylusWritingDelegate.handleTouchEvent(event)) { + // Stylus writing system can consume the touch events once writing is started. + return true; + } else if (isTrackpadToMouseEventConversionEnabled() + && isTrackpadClickOrClickAndDragEvent(event)) { + return onMouseEvent(event); + } else if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { + // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here? + // crbug.com/592082 + + // Skip firing mouse events in the following cases: // - In Android L and below, where mouse button info is incomplete. // - A move w/o a button press, which represents a trackpad scroll. Real mouse moves w/o // buttons goes to onHoverEvent. + // TODO(mustaq): Look into the relevancy of this code path final boolean isTouchpadScroll = event.getButtonState() == 0 && (event.getActionMasked() == MotionEvent.ACTION_DOWN || event.getActionMasked() == MotionEvent.ACTION_MOVE @@ -163,18 +186,7 @@ return onMouseEvent(event); } } - - final boolean isTouchHandleEvent = false; - return sendTouchEvent(event, isTouchHandleEvent); - } - - /** - * Called by PopupWindow-based touch handles. - * @param event the MotionEvent targeting the handle. - */ - public boolean onTouchHandleEvent(MotionEvent event) { - final boolean isTouchHandleEvent = true; - return sendTouchEvent(event, isTouchHandleEvent); + return false; } private boolean sendTouchEvent(MotionEvent event, boolean isTouchHandleEvent) { @@ -250,8 +262,9 @@ /** * Sets the current amount to offset incoming touch events by (including MotionEvent and - * DragEvent). This is used to handle content moving and not lining up properly with the - * android input system. + * DragEvent). This is used to handle content moving and not lining up properly with the android + * input system. + * * @param dx The X offset in pixels to shift touch events. * @param dy The Y offset in pixels to shift touch events. */ @@ -261,8 +274,9 @@ } /** - * Creates a new motion event differed from the given event by current touch offset - * if the offset is not zero. + * Creates a new motion event differed from the given event by current touch offset if the + * offset is not zero. + * * @param src Source motion event. * @return A new motion event if we have non-zero touch offset. Otherwise return the same event. */ @@ -345,8 +359,8 @@ } /** - * Sends mouse event to native. Hover event is also converted to mouse event, - * only differentiated by an internal flag. + * Sends mouse event to native. Hover event is also converted to mouse event, only + * differentiated by an internal flag. */ private boolean sendNativeMouseEvent(MotionEvent event) { assert mNativeEventForwarder != 0; @@ -362,18 +376,20 @@ // is provided using ACTION_MOVE touch events. return true; } - + boolean shouldConvertToMouseEvent = isTrackpadToMouseEventConversionEnabled() + && isTrackpadClickOrClickAndDragEvent(event); EventForwarderJni.get().onMouseEvent(mNativeEventForwarder, EventForwarder.this, MotionEventUtils.getEventTimeNano(event), eventAction, event.getX(), event.getY(), event.getPointerId(0), event.getPressure(0), event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), getMouseEventActionButton(event), - event.getButtonState(), event.getMetaState(), event.getToolType(0)); + event.getButtonState(), event.getMetaState(), + shouldConvertToMouseEvent ? MotionEvent.TOOL_TYPE_MOUSE : event.getToolType(0)); return true; } /** - * Manages internal state to work around a device-specific issue. Needs to be called per - * every mouse event to update the state. + * Manages internal state to work around a device-specific issue. Needs to be called per every + * mouse event to update the state. */ private void updateMouseEventState(MotionEvent event) { int eventAction = event.getActionMasked(); @@ -388,6 +404,36 @@ return ApiHelperForM.getActionButton(event); } + public boolean isTrackpadToMouseEventConversionEnabled() { + return mConvertTrackpadEventsToMouse; + } + + /** + * Returns true if a {@link MotionEvent} is a trackpad click and or click & drag event. + * Trackpad hover events and non-click gestures (i.e two-finger scroll) should return + * false here as they do have an action button pressed. Also we want to make sure we + * return true for button release events as well. + */ + public static boolean isTrackpadClickOrClickAndDragEvent(MotionEvent event) { + return isTrackpadEvent(event) + && (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE + || event.getButtonState() != 0); + } + + /** + * Returns true if a {@link MotionEvent} is detected to be a trackpad event. + * Note that {@link MotionEvent.TOOL_TYPE_FINGER} is used here along with + * {@link InputDevice.SOURCE_MOUSE} instead of {@link InputDevice.SOURCE_TOUCHPAD} + * because {@link InputDevice.SOURCE_TOUCHPAD} is used when an app + * captures the touchpad meaning that it gets access to the raw finger locations, + * dimensions etc. reported by the touchpad rather than those being used for pointer movements + * and gestures. + */ + private static boolean isTrackpadEvent(MotionEvent event) { + return event.isFromSource(InputDevice.SOURCE_MOUSE) + && event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER; + } + /** * @see View#onDragEvent(DragEvent) * @param event {@link DragEvent} instance. @@ -453,9 +499,8 @@ * * @param type Type of the gesture event. * @param timeMs Time the event occurred in milliseconds. - * @param delta Scale factor for pinch gesture relative to the current state, - * 1.0 being 100%. If negative, has the effect of reverting - * pinch scale to default. + * @param delta Scale factor for pinch gesture relative to the current state, 1.0 being 100%. If + * negative, has the effect of reverting pinch scale to default. */ public boolean onGestureEvent(@GestureEventType int type, long timeMs, float delta) { if (mNativeEventForwarder == 0) return false; @@ -468,8 +513,11 @@ */ public boolean onGenericMotionEvent(MotionEvent event) { if (mNativeEventForwarder == 0) return false; - if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 - && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { + boolean isMouseEvent = (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 + && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE; + boolean shouldConvertToMouseEvent = isTrackpadToMouseEventConversionEnabled() + && isTrackpadClickOrClickAndDragEvent(event); + if (isMouseEvent || shouldConvertToMouseEvent) { updateMouseEventState(event); } @@ -519,13 +567,14 @@ /** * Flings the viewport with velocity vector (velocityX, velocityY). + * * @param timeMs the current time. * @param velocityX fling speed in x-axis. * @param velocityY fling speed in y-axis. * @param syntheticScroll true if generated by gamepad (which will make this fixed-velocity - * fling) + * fling) * @param preventBoost if false, this fling may boost an existing fling. Otherwise, ends the - * current fling and starts a new one. + * current fling and starts a new one. */ public void startFling(long timeMs, float velocityX, float velocityY, boolean syntheticScroll, boolean preventBoosting) { @@ -536,6 +585,7 @@ /** * Cancel any fling gestures active. + * * @param timeMs Current time (in milliseconds). */ public void cancelFling(long timeMs) { @@ -544,6 +594,7 @@ mNativeEventForwarder, EventForwarder.this, timeMs, /*preventBoosting*/ true); } + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) @NativeMethods interface Natives { WindowAndroid getJavaWindowAndroid(long nativeEventForwarder, EventForwarder caller); @@ -559,20 +610,30 @@ void onMouseEvent(long nativeEventForwarder, EventForwarder caller, long timeNs, int action, float x, float y, int pointerId, float pressure, float orientation, float tilt, int changedButton, int buttonState, int metaState, int toolType); + void onDragEvent(long nativeEventForwarder, EventForwarder caller, int action, float x, float y, float screenX, float screenY, String[] mimeTypes, String content); + boolean onGestureEvent(long nativeEventForwarder, EventForwarder caller, int type, long timeMs, float delta); + boolean onGenericMotionEvent( long nativeEventForwarder, EventForwarder caller, MotionEvent event, long timeNs); + boolean onKeyUp( long nativeEventForwarder, EventForwarder caller, KeyEvent event, int keyCode); + boolean dispatchKeyEvent(long nativeEventForwarder, EventForwarder caller, KeyEvent event); + void scrollBy(long nativeEventForwarder, EventForwarder caller, float deltaX, float deltaY); + void scrollTo(long nativeEventForwarder, EventForwarder caller, float x, float y); + void doubleTap(long nativeEventForwarder, EventForwarder caller, long timeMs, int x, int y); + void startFling(long nativeEventForwarder, EventForwarder caller, long timeMs, float velocityX, float velocityY, boolean syntheticScroll, boolean preventBoosting); + void cancelFling(long nativeEventForwarder, EventForwarder caller, long timeMs, boolean preventBoosting); }
diff --git a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java new file mode 100644 index 0000000..15732b1 --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java
@@ -0,0 +1,37 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.base; + +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.build.annotations.MainDex; + +/** + * Java accessor for ui/android/ui_android_feature_list.cc state + */ +@JNINamespace("ui") +@MainDex +public class UiAndroidFeatureList { + // Do not instantiate this class + private UiAndroidFeatureList() {} + + /** + * Returns whether the specified feature is enabled or not. + * + * Note: Features queried through this API must be added to the array + * |kFeaturesExposedToJava| in ui/android/ui_android_feature_list.cc + * + * @param featureName The name of the feature to query. + * @return Whether the feature is enabled or not. + */ + public static boolean isEnabled(String featureName) { + return UiAndroidFeatureListJni.get().isEnabled(featureName); + } + + @NativeMethods + public interface Natives { + boolean isEnabled(String featureName); + } +}
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/OWNERS b/ui/android/java/src/org/chromium/ui/modelutil/OWNERS index 38d75be..3a72bd0 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/OWNERS +++ b/ui/android/java/src/org/chromium/ui/modelutil/OWNERS
@@ -1,2 +1,3 @@ +mdjones@chromium.org twellington@chromium.org tedchoc@chromium.org
diff --git a/ui/android/java_templates/UiAndroidFeatures.java.tmpl b/ui/android/java_templates/UiAndroidFeatures.java.tmpl new file mode 100644 index 0000000..85eaa97 --- /dev/null +++ b/ui/android/java_templates/UiAndroidFeatures.java.tmpl
@@ -0,0 +1,16 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.base; + +/** + * Constants for the names of Ui Android Features. + */ +public final class UiAndroidFeatures {{ + +{NATIVE_FEATURES} + + // Do not instantiate this class. + private UiAndroidFeatures() {{}} +}}
diff --git a/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java b/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java new file mode 100644 index 0000000..dabc2df --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java
@@ -0,0 +1,171 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.base; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.view.InputDevice; +import android.view.MotionEvent; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.JniMocker; +import org.chromium.ui.MotionEventUtils; + +/** Tests logic in the {@link EventForwarder} class. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class EventForwarderTest { + @Rule + public JniMocker mocker = new JniMocker(); + + @Mock + EventForwarder.Natives mNativeMock; + + private static final long NATIVE_EVENT_FORWARDER_ID = 1; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mocker.mock(EventForwarderJni.TEST_HOOKS, mNativeMock); + } + + @Test + public void testSendTrackpadClicksAsMouseEventToNative() { + EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true); + + // Left click + MotionEvent leftClickEvent = getTrackpadLeftClickEvent(); + eventForwarder.onTouchEvent(leftClickEvent); + verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, leftClickEvent, eventForwarder, 1); + + // Right click + MotionEvent rightClickEvent = getTrackRightClickEvent(); + eventForwarder.onTouchEvent(rightClickEvent); + verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, rightClickEvent, eventForwarder, 1); + } + + @Test + public void testSendTrackpadClickReleaseAsMouseEventToNative() { + EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true); + + // Left click + MotionEvent leftClickReleaseEvent = + getTrackpadEvent(MotionEvent.ACTION_BUTTON_RELEASE, MotionEvent.BUTTON_PRIMARY); + eventForwarder.onTouchEvent(leftClickReleaseEvent); + verifyNativeMouseEventSent( + NATIVE_EVENT_FORWARDER_ID, leftClickReleaseEvent, eventForwarder, 1); + + // Right click + MotionEvent rightClickReleaseEvent = + getTrackpadEvent(MotionEvent.ACTION_BUTTON_RELEASE, MotionEvent.BUTTON_SECONDARY); + eventForwarder.onTouchEvent(rightClickReleaseEvent); + verifyNativeMouseEventSent( + NATIVE_EVENT_FORWARDER_ID, rightClickReleaseEvent, eventForwarder, 1); + } + + @Test + public void testSendTrackpadClickAndDragAsMouseEventToNative() { + EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true); + MotionEvent clickAndDragEvent = + getTrackpadEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY); + eventForwarder.onTouchEvent(clickAndDragEvent); + verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, clickAndDragEvent, eventForwarder, 1); + } + + @Test + public void testSendTrackEventAsTouchEventWhenButtonIsNotClicked() { + EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true); + MotionEvent trackpadTouchDownEventNoClick = getTrackpadTouchDownEventNoClick(); + eventForwarder.onTouchEvent(trackpadTouchDownEventNoClick); + verify(mNativeMock, times(1)) + .onTouchEvent(anyLong(), any(EventForwarder.class), any(MotionEvent.class), + anyLong(), anyInt(), anyInt(), anyInt(), anyInt(), anyFloat(), anyFloat(), + anyFloat(), anyFloat(), anyInt(), anyInt(), anyFloat(), anyFloat(), + anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), + anyFloat(), anyFloat(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), + anyBoolean()); + verify(mNativeMock, never()) + .onMouseEvent(anyLong(), any(EventForwarder.class), anyLong(), anyInt(), anyFloat(), + anyFloat(), anyInt(), anyFloat(), anyFloat(), anyFloat(), anyInt(), + anyInt(), anyInt(), anyInt()); + } + + @Test + public void testNotSendTrackpadClickAsMouseEventWhenFeatureDisabled() { + EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, false); + MotionEvent trackpadClickDownEvent = getTrackpadLeftClickEvent(); + eventForwarder.onTouchEvent(trackpadClickDownEvent); + verify(mNativeMock, never()) + .onMouseEvent(anyLong(), any(EventForwarder.class), anyLong(), anyInt(), anyFloat(), + anyFloat(), anyInt(), anyFloat(), anyFloat(), anyFloat(), anyInt(), + anyInt(), anyInt(), anyInt()); + } + + private void verifyNativeMouseEventSent(long nativeEventForwarder, MotionEvent event, + EventForwarder eventForwarder, int times) { + verify(mNativeMock, times(times)) + .onMouseEvent(nativeEventForwarder, eventForwarder, + MotionEventUtils.getEventTimeNano(event), event.getActionMasked(), + event.getX(), event.getY(), event.getPointerId(0), event.getPressure(0), + event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), + EventForwarder.getMouseEventActionButton(event), event.getButtonState(), + event.getMetaState(), MotionEvent.TOOL_TYPE_MOUSE); + } + + private static MotionEvent getTrackpadTouchDownEventNoClick() { + return getTrackpadEvent(MotionEvent.ACTION_DOWN, 0); + } + + private static MotionEvent getTrackpadLeftClickEvent() { + return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_PRIMARY); + } + + private static MotionEvent getTrackRightClickEvent() { + return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_SECONDARY); + } + + private static MotionEvent getTrackpadEvent(int action, int buttonState) { + return MotionEvent.obtain(0, 0, action, 1, getToolTypeFingerProperties(), + getPointerCoords(), 0, buttonState, 0, 0, 0, 0, getTrackpadSource(), 0); + } + + private static MotionEvent.PointerProperties[] getToolTypeFingerProperties() { + MotionEvent.PointerProperties[] pointerPropertiesArray = + new MotionEvent.PointerProperties[1]; + MotionEvent.PointerProperties trackpadProperties = new MotionEvent.PointerProperties(); + trackpadProperties.id = 7; + trackpadProperties.toolType = MotionEvent.TOOL_TYPE_FINGER; + pointerPropertiesArray[0] = trackpadProperties; + return pointerPropertiesArray; + } + + private static MotionEvent.PointerCoords[] getPointerCoords() { + MotionEvent.PointerCoords[] pointerCoordsArray = new MotionEvent.PointerCoords[1]; + MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + coords.x = 14; + coords.y = 21; + pointerCoordsArray[0] = coords; + return pointerCoordsArray; + } + + private static int getTrackpadSource() { + return InputDevice.SOURCE_MOUSE; + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS b/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS new file mode 100644 index 0000000..7cf54c2 --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS
@@ -0,0 +1 @@ +file://ui/android/java/src/org/chromium/ui/modelutil/OWNERS
diff --git a/ui/android/ui_android_feature_list.cc b/ui/android/ui_android_feature_list.cc new file mode 100644 index 0000000..5a2857a --- /dev/null +++ b/ui/android/ui_android_feature_list.cc
@@ -0,0 +1,46 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/jni_string.h" +#include "base/feature_list.h" +#include "base/notreached.h" +#include "ui/android/ui_android_features.h" +#include "ui/android/ui_android_jni_headers/UiAndroidFeatureList_jni.h" + +using base::android::ConvertJavaStringToUTF8; +using base::android::JavaParamRef; + +namespace ui { + +namespace { + +// Array of features exposed through the Java AwFeatureList API. Entries in +// this array may either refer to features defined in the header of this file or +// in other locations in the code base (e.g. content/, components/, etc). +const base::Feature* const kFeaturesExposedToJava[] = { + &features::kConvertTrackpadEventsToMouse, +}; + +const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) { + for (const base::Feature* feature : kFeaturesExposedToJava) { + if (feature->name == feature_name) { + return feature; + } + } + NOTREACHED() << "Queried feature cannot be found in UiAndroidFeatureList: " + << feature_name; + return nullptr; +} + +} // namespace + +static jboolean JNI_UiAndroidFeatureList_IsEnabled( + JNIEnv* env, + const JavaParamRef<jstring>& jfeature_name) { + const base::Feature* feature = + FindFeatureExposedToJava(ConvertJavaStringToUTF8(env, jfeature_name)); + return base::FeatureList::IsEnabled(*feature); +} + +} // namespace ui
diff --git a/ui/android/ui_android_features.cc b/ui/android/ui_android_features.cc new file mode 100644 index 0000000..4749b96e --- /dev/null +++ b/ui/android/ui_android_features.cc
@@ -0,0 +1,13 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/android/ui_android_features.h" + +#include "base/feature_list.h" + +namespace features { +BASE_FEATURE(kConvertTrackpadEventsToMouse, + "ConvertTrackpadEventsToMouse", + base::FEATURE_DISABLED_BY_DEFAULT); +} // namespace features
diff --git a/ui/android/ui_android_features.h b/ui/android/ui_android_features.h new file mode 100644 index 0000000..c74cbe8 --- /dev/null +++ b/ui/android/ui_android_features.h
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_ANDROID_UI_ANDROID_FEATURES_H_ +#define UI_ANDROID_UI_ANDROID_FEATURES_H_ + +#include "base/component_export.h" +#include "base/feature_list.h" + +namespace features { + +// Keep sorted! + +// Enables converting trackpad click gestures to mouse events in +// order for them to be interpreted similar to a desktop +// experience (i.e. double-click to select word.) +COMPONENT_EXPORT(UI_ANDROID_FEATURES) +BASE_DECLARE_FEATURE(kConvertTrackpadEventsToMouse); +} // namespace features + +#endif // UI_ANDROID_UI_ANDROID_FEATURES_H_
diff --git a/ui/base/mojom/attributed_string.mojom b/ui/base/mojom/attributed_string.mojom index 41fe5be..2807049d 100644 --- a/ui/base/mojom/attributed_string.mojom +++ b/ui/base/mojom/attributed_string.mojom
@@ -7,22 +7,21 @@ import "mojo/public/mojom/base/string16.mojom"; import "ui/gfx/range/mojom/range.mojom"; -// This will serialize the font information of an NSAttributedString so that -// it can be sent over mojo. This only stores the information of the -// NSFontAttributeName. The motive is that of security: using NSArchiver and -// friends to send objects from the renderer to the browser could lead to -// deserialization of arbitrary objects. This restricts serialization to a -// specific object class and specific attributes of that object. +// This will serialize the font information of a CFAttributedString so that it +// can be sent over mojo. This only stores the information of the font name and +// font size. The motive is that of security: using NSArchiver and friends to +// send objects from the renderer to the browser could lead to deserialization +// of arbitrary objects. This restricts serialization to a specific object class +// and specific attributes of that object. -// A C++ mojo-friendly representation of the NSFontAttributeName attribute -// set. +// A C++ mojo-friendly representation of the font and font size attribute set. struct FontAttribute { mojo_base.mojom.String16 font_name; float font_point_size; gfx.mojom.Range effective_range; }; -// A struct that contains the pertinent information from an NSAttributedString, +// A struct that contains the pertinent information from a CFAttributedString, // which can be serialized over mojo. struct AttributedString { // The plain-text string.
diff --git a/ui/display/display_util.cc b/ui/display/display_util.cc index f6a1cb0..81c0bf9 100644 --- a/ui/display/display_util.cc +++ b/ui/display/display_util.cc
@@ -41,7 +41,7 @@ screen_info->orientation_angle = 90; #endif -#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) screen_info->orientation_type = GetOrientationTypeForMobile(display); #else screen_info->orientation_type = GetOrientationTypeForDesktop(display);
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 1108473a..682c22c5 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h
@@ -13,10 +13,7 @@ #if BUILDFLAG(IS_ANDROID) #include "base/android/scoped_java_ref.h" -#elif BUILDFLAG(IS_IOS) -#include <objc/objc.h> #elif BUILDFLAG(IS_MAC) -#include <objc/objc.h> #include <string> #elif BUILDFLAG(IS_WIN) #include "base/win/windows_types.h" @@ -63,6 +60,7 @@ #elif BUILDFLAG(IS_IOS) struct CGContext; #ifdef __OBJC__ +struct objc_object; @class UIEvent; @class UIFont; @class UIImage; @@ -88,6 +86,7 @@ @class NSWindow; @class NSTextField; #else +struct objc_object; class NSCursor; class NSEvent; class NSFont; @@ -140,8 +139,6 @@ // function call (GetNativeNSView or GetNativeNSWindow) to retrieve the // underlying NSView or NSWindow <https://crbug.com/893719>. These are wrapper // classes only and do not maintain any ownership, thus the __unsafe_unretained. -// (__unsafe_unretained is defined in <objc/objc.h> for non-Obj-C so it's OK to -// use in C++ code.) class GFX_EXPORT NativeView { public: constexpr NativeView() = default; @@ -153,7 +150,7 @@ // is easily grep-able. NSView* GetNativeNSView() const { return ns_view_; } - explicit operator bool() const { return ns_view_ != nil; } + explicit operator bool() const { return ns_view_ != nullptr; } bool operator==(const NativeView& other) const { return ns_view_ == other.ns_view_; } @@ -166,7 +163,11 @@ std::string ToString() const; private: - __unsafe_unretained NSView* ns_view_ = nil; +#if defined(__has_feature) && __has_feature(objc_arc) + __unsafe_unretained NSView* ns_view_ = nullptr; +#else + NSView* ns_view_ = nullptr; +#endif }; class GFX_EXPORT NativeWindow { public: @@ -179,7 +180,7 @@ // is easily grep-able. NSWindow* GetNativeNSWindow() const { return ns_window_; } - explicit operator bool() const { return ns_window_ != nil; } + explicit operator bool() const { return ns_window_ != nullptr; } bool operator==(const NativeWindow& other) const { return ns_window_ == other.ns_window_; } @@ -192,7 +193,11 @@ std::string ToString() const; private: - __unsafe_unretained NSWindow* ns_window_ = nil; +#if defined(__has_feature) && __has_feature(objc_arc) + __unsafe_unretained NSWindow* ns_window_ = nullptr; +#else + NSWindow* ns_window_ = nullptr; +#endif }; constexpr NativeView kNullNativeView = NativeView(nullptr); constexpr NativeWindow kNullNativeWindow = NativeWindow(nullptr); @@ -212,10 +217,18 @@ using NativeViewAccessible = IAccessible*; #elif BUILDFLAG(IS_IOS) using NativeFont = UIFont*; +#ifdef __OBJC__ using NativeViewAccessible = id; +#else +using NativeViewAccessible = struct objc_object*; +#endif #elif BUILDFLAG(IS_MAC) using NativeFont = NSFont*; +#ifdef __OBJC__ using NativeViewAccessible = id; +#else +using NativeViewAccessible = struct objc_object*; +#endif // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/ui/gfx/x/gen_xproto.py b/ui/gfx/x/gen_xproto.py index 6986842..e5a71190 100644 --- a/ui/gfx/x/gen_xproto.py +++ b/ui/gfx/x/gen_xproto.py
@@ -1544,7 +1544,7 @@ self.write() for name, event, proto in self.events: self.gen_event(name, event, proto) - self.write('NOTREACHED();') + self.write('// Leave `event` default-initialized.') self.write() self.write('} // namespace x11')
diff --git a/ui/gfx/x/generated_protos/read_event.cc b/ui/gfx/x/generated_protos/read_event.cc index b9827997..8b7466d4 100644 --- a/ui/gfx/x/generated_protos/read_event.cc +++ b/ui/gfx/x/generated_protos/read_event.cc
@@ -1372,7 +1372,7 @@ return; } - NOTREACHED(); + // Leave `event` default-initialized. } } // namespace x11
diff --git a/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc b/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc index c1c6c81..d954c17d 100644 --- a/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc +++ b/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc
@@ -118,7 +118,7 @@ DRM_FORMAT_NV12, DRM_FORMAT_YVU420}; wl::TestWaylandServerThread server; - CHECK(server.Start({})); + CHECK(server.Start()); std::unique_ptr<ui::WaylandConnection> connection = std::make_unique<ui::WaylandConnection>();
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc index 681b417..b357a0b 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
@@ -1454,6 +1454,7 @@ INSTANTIATE_TEST_SUITE_P( CompositorVersionV3Test, WaylandSurfaceFactoryCompositorV3, - Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV3})); + Values(wl::ServerConfig{ + .compositor_version = wl::TestCompositor::Version::kV3})); } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc index d4332e98..c7b6d591 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc
@@ -27,15 +27,8 @@ TEST_P(WaylandConnectionTest, CompositorVersionTest) { wl::ServerConfig config = GetParam(); - uint32_t expected_compositor_version = 0; - switch (config.compositor_version) { - case wl::CompositorVersion::kV3: - expected_compositor_version = 3; - break; - case wl::CompositorVersion::kV4: - expected_compositor_version = 4; - break; - } + uint32_t expected_compositor_version = + static_cast<uint32_t>(config.compositor_version); EXPECT_EQ(expected_compositor_version, wl::get_version_of_object(connection_->compositor())); @@ -44,10 +37,12 @@ INSTANTIATE_TEST_SUITE_P( XdgVersionStableTest, WaylandConnectionTest, - Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV3})); + Values(wl::ServerConfig{ + .compositor_version = wl::TestCompositor::Version::kV3})); INSTANTIATE_TEST_SUITE_P( XdgVersionStableTestCompositorV4, WaylandConnectionTest, - Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV4})); + Values(wl::ServerConfig{ + .compositor_version = wl::TestCompositor::Version::kV4})); } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_output_unittest.cc b/ui/ozone/platform/wayland/host/wayland_output_unittest.cc index 5b88d18..97cff7edd 100644 --- a/ui/ozone/platform/wayland/host/wayland_output_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_output_unittest.cc
@@ -8,6 +8,7 @@ #include "ui/base/wayland/wayland_display_util.h" #include "ui/ozone/platform/wayland/host/wayland_output_manager.h" #include "ui/ozone/platform/wayland/host/xdg_output.h" +#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/test/wayland_test.h" using ::testing::Values; @@ -138,14 +139,12 @@ EXPECT_TRUE(new_output->IsReady()); } -class WaylandOutpuWithAuraOutputManagerTest - : public WaylandTestSimpleWithAuraShell { +class WaylandOutputWithAuraOutputManagerTest : public WaylandTestSimple { protected: - // WaylandTestSimpleWithAuraShell: - void SetUp() override { - SetUseAuraOutputManager(true); - WaylandTestSimpleWithAuraShell::SetUp(); - } + WaylandOutputWithAuraOutputManagerTest() + : WaylandTestSimple(wl::ServerConfig{ + .enable_aura_shell = wl::EnableAuraShellProtocol::kEnabled, + .use_aura_output_manager = true}) {} WaylandOutputManager* wayland_output_manager() { auto* wayland_output_manager = connection_->wayland_output_manager(); @@ -160,7 +159,7 @@ // Tests that WaylandOutput only reports as ready if metrics has been set when // the aura output manager is bound. -TEST_F(WaylandOutpuWithAuraOutputManagerTest, WaylandOutputIsReady) { +TEST_F(WaylandOutputWithAuraOutputManagerTest, WaylandOutputIsReady) { auto* output_manager = connection_->wayland_output_manager(); const auto* primary_output = output_manager->GetPrimaryOutput(); @@ -197,7 +196,8 @@ // Tests that delegate notifications are not triggered when the wl_output.done // event is received. It is instead expected to be triggered by the aura output // manager. -TEST_F(WaylandOutpuWithAuraOutputManagerTest, SuppressesDelegateNotifications) { +TEST_F(WaylandOutputWithAuraOutputManagerTest, + SuppressesDelegateNotifications) { testing::NiceMock<MockWaylandOutputDelegate> output_delegate; EXPECT_CALL(output_delegate, OnOutputHandleMetrics(testing::_)).Times(0); primary_output()->set_delegate_for_testing(&output_delegate);
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc b/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc index 957208f..55194ee 100644 --- a/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc
@@ -45,14 +45,14 @@ } // namespace -class WaylandZAuraOutputManagerTest : public WaylandTestSimpleWithAuraShell { - protected: - // WaylandTestSimpleWithAuraShell: - void SetUp() override { - SetUseAuraOutputManager(true); - WaylandTestSimpleWithAuraShell::SetUp(); - } +class WaylandZAuraOutputManagerTest : public WaylandTestSimple { + public: + WaylandZAuraOutputManagerTest() + : WaylandTestSimple(wl::ServerConfig{ + .enable_aura_shell = wl::EnableAuraShellProtocol::kEnabled, + .use_aura_output_manager = true}) {} + protected: // Sends sample metrics to the primary output configured for this fixture. void SendSampleMetrics(const WaylandOutput::Metrics& metrics) { const auto wayland_display_id =
diff --git a/ui/ozone/platform/wayland/test/test_compositor.cc b/ui/ozone/platform/wayland/test/test_compositor.cc index 4e0b306..f70043a 100644 --- a/ui/ozone/platform/wayland/test/test_compositor.cc +++ b/ui/ozone/platform/wayland/test/test_compositor.cc
@@ -39,10 +39,10 @@ CreateRegion, // create_region }; -TestCompositor::TestCompositor(uint32_t intended_version) +TestCompositor::TestCompositor(TestCompositor::Version intended_version) : GlobalObject(&wl_compositor_interface, &kTestCompositorImpl, - intended_version), + static_cast<uint32_t>(intended_version)), version_(intended_version) {} TestCompositor::~TestCompositor() = default;
diff --git a/ui/ozone/platform/wayland/test/test_compositor.h b/ui/ozone/platform/wayland/test/test_compositor.h index 8e2e7b8..24d18d0 100644 --- a/ui/ozone/platform/wayland/test/test_compositor.h +++ b/ui/ozone/platform/wayland/test/test_compositor.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_COMPOSITOR_H_ #define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_COMPOSITOR_H_ +#include <cstdint> #include <vector> #include "ui/ozone/platform/wayland/test/global_object.h" @@ -16,7 +17,11 @@ // Manage wl_compositor object. class TestCompositor : public GlobalObject { public: - explicit TestCompositor(uint32_t intended_version); + enum class Version : uint32_t { + kV3 = 3, + kV4 = 4, + }; + explicit TestCompositor(Version intended_version); TestCompositor(const TestCompositor&) = delete; TestCompositor& operator=(const TestCompositor&) = delete; @@ -24,10 +29,10 @@ ~TestCompositor() override; void AddSurface(MockSurface* surface); - uint32_t GetVersion() { return version_; } + Version GetVersion() { return version_; } private: - uint32_t version_; + Version version_; std::vector<MockSurface*> surfaces_; };
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc index 6e7e5df..b61a5174 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
@@ -43,10 +43,13 @@ } TestWaylandServerThread::TestWaylandServerThread() + : TestWaylandServerThread(ServerConfig{}) {} + +TestWaylandServerThread::TestWaylandServerThread(const ServerConfig& config) : Thread("test_wayland_server"), client_destroy_listener_(this), - compositor_v4_(4), - compositor_v3_(3), + config_(config), + compositor_(config.compositor_version), output_(base::BindRepeating( &TestWaylandServerThread::OnTestOutputMetricsFlush, base::Unretained(this))), @@ -81,7 +84,7 @@ client_ = nullptr; } -bool TestWaylandServerThread::Start(const ServerConfig& config) { +bool TestWaylandServerThread::Start() { display_.reset(wl_display_create()); if (!display_) return false; @@ -95,12 +98,8 @@ if (wl_display_init_shm(display_.get()) < 0) return false; - if (config.compositor_version == CompositorVersion::kV3) { - if (!compositor_v3_.Initialize(display_.get())) - return false; - } else { - if (!compositor_v4_.Initialize(display_.get())) - return false; + if (!compositor_.Initialize(display_.get())) { + return false; } if (!sub_compositor_.Initialize(display_.get())) return false; @@ -109,8 +108,8 @@ if (!alpha_compositing_.Initialize(display_.get())) return false; - if (config.enable_aura_shell == EnableAuraShellProtocol::kEnabled) { - if (config.use_aura_output_manager) { + if (config_.enable_aura_shell == EnableAuraShellProtocol::kEnabled) { + if (config_.use_aura_output_manager) { // zaura_output_manager should be initialized before any wl_output // globals. if (!zaura_output_manager_.Initialize(display_.get())) { @@ -133,8 +132,9 @@ if (!data_device_manager_.Initialize(display_.get())) return false; - if (!SetupPrimarySelectionManager(config.primary_selection_protocol)) + if (!SetupPrimarySelectionManager(config_.primary_selection_protocol)) { return false; + } if (!seat_.Initialize(display_.get())) return false; @@ -145,7 +145,7 @@ if (!zcr_stylus_.Initialize(display_.get())) return false; - switch (config.text_input_extension_version) { + switch (config_.text_input_extension_version) { case TextInputExtensionVersion::kV7: zcr_text_input_extension_v1_ = std::make_unique<TestZcrTextInputExtensionV1>(7); @@ -162,8 +162,9 @@ if (!zwp_text_input_manager_v1_.Initialize(display_.get())) return false; if (!SetupExplicitSynchronizationProtocol( - config.use_explicit_synchronization)) + config_.use_explicit_synchronization)) { return false; + } if (!zwp_linux_dmabuf_v1_.Initialize(display_.get())) return false; if (!overlay_prioritizer_.Initialize(display_.get()))
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h index 8771fbb..d5e9b75c 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
@@ -53,7 +53,6 @@ // Server configuration related enums and structs. enum class PrimarySelectionProtocol { kNone, kGtk, kZwp }; -enum class CompositorVersion { kV3, kV4 }; enum class TextInputExtensionVersion { kV7, kV8 }; enum class ShouldUseExplicitSynchronizationProtocol { kNone, kUse }; enum class EnableAuraShellProtocol { kEnabled, kDisabled }; @@ -61,7 +60,7 @@ struct ServerConfig { TextInputExtensionVersion text_input_extension_version = TextInputExtensionVersion::kV8; - CompositorVersion compositor_version = CompositorVersion::kV4; + TestCompositor::Version compositor_version = TestCompositor::Version::kV4; PrimarySelectionProtocol primary_selection_protocol = PrimarySelectionProtocol::kNone; ShouldUseExplicitSynchronizationProtocol use_explicit_synchronization = @@ -91,6 +90,7 @@ class OutputDelegate; TestWaylandServerThread(); + explicit TestWaylandServerThread(const ServerConfig& config); TestWaylandServerThread(const TestWaylandServerThread&) = delete; TestWaylandServerThread& operator=(const TestWaylandServerThread&) = delete; @@ -102,9 +102,7 @@ // descriptor that a client can connect to. The caller is responsible for // ensuring that this file descriptor gets closed (for example, by calling // wl_display_connect). - // Instantiates an xdg_shell of version |shell_version|; versions 6 and 7 - // (stable) are supported. - bool Start(const ServerConfig& config); + bool Start(); // Runs 'callback' or 'closure' on the server thread; blocks until the // callable is run and all pending Wayland requests and events are delivered. @@ -225,13 +223,11 @@ raw_ptr<wl_event_loop> event_loop_ = nullptr; raw_ptr<wl_protocol_logger> protocol_logger_ = nullptr; + ServerConfig config_; + // Represent Wayland global objects - // Compositor version is selected dynamically by server config but version is - // actually set on construction thus both compositor version objects appear - // here. - // TODO(crbug.com/1315587): Refactor this pattern when required. - TestCompositor compositor_v4_; - TestCompositor compositor_v3_; + TestCompositor compositor_; + TestSubCompositor sub_compositor_; TestViewporter viewporter_; TestAlphaCompositing alpha_compositing_;
diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc index a2bd1d9..3b692e1 100644 --- a/ui/ozone/platform/wayland/test/wayland_test.cc +++ b/ui/ozone/platform/wayland/test/wayland_test.cc
@@ -36,7 +36,7 @@ WaylandTestBase::WaylandTestBase(wl::ServerConfig config) : task_environment_(base::test::TaskEnvironment::MainThreadType::UI, base::test::TaskEnvironment::TimeSource::MOCK_TIME), - config_(config) { + server_(config) { #if BUILDFLAG(USE_XKBCOMMON) auto keyboard_layout_engine = std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_); @@ -66,7 +66,7 @@ DeviceDataManager::CreateInstance(); } - ASSERT_TRUE(server_.Start(config_)); + ASSERT_TRUE(server_.Start()); ASSERT_TRUE(connection_->Initialize()); screen_ = connection_->wayland_output_manager()->CreateWaylandScreen(); connection_->wayland_output_manager()->InitWaylandScreen(screen_.get()); @@ -122,13 +122,6 @@ wl::SyncDisplay(connection_->display_wrapper(), *connection_->display()); } -void WaylandTestBase::SetUseAuraOutputManager(bool use_aura_output_manager) { - // Must be called before the test server is started and the global display has - // been created. - DCHECK(!server_.display()); - config_.use_aura_output_manager = use_aura_output_manager; -} - void WaylandTestBase::DisableSyncOnTearDown() { initialized_ = false; }
diff --git a/ui/ozone/platform/wayland/test/wayland_test.h b/ui/ozone/platform/wayland/test/wayland_test.h index 88b92981..02acdf2 100644 --- a/ui/ozone/platform/wayland/test/wayland_test.h +++ b/ui/ozone/platform/wayland/test/wayland_test.h
@@ -64,10 +64,6 @@ } protected: - // Sets the test server `config_` to use the zaura_output_manager global. This - // must be called before WaylandTestBase::SetUp(). - void SetUseAuraOutputManager(bool use_aura_output_manager); - // Disables client-server sync during the teardown. Used by tests that // intentionally spoil the client-server communication. void DisableSyncOnTearDown(); @@ -133,8 +129,6 @@ std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_; base::test::ScopedFeatureList feature_list_; - - wl::ServerConfig config_; }; // Version of WaylandTestBase that uses parametrised tests (TEST_P).
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc index 9e87c2c4..9e5d6736 100644 --- a/ui/views/controls/button/image_button.cc +++ b/ui/views/controls/button/image_button.cc
@@ -40,6 +40,7 @@ // implementation is flipped horizontally so that the button's images are // mirrored when the UI directionality is right-to-left. SetFlipCanvasOnPaintForRTLUI(true); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); } ImageButton::~ImageButton() = default;
diff --git a/ui/views/controls/button/radio_button.cc b/ui/views/controls/button/radio_button.cc index 4b61c2d1..a570846e 100644 --- a/ui/views/controls/button/radio_button.cc +++ b/ui/views/controls/button/radio_button.cc
@@ -33,6 +33,7 @@ RadioButton::RadioButton(const std::u16string& label, int group_id) : Checkbox(label) { SetGroup(group_id); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); } RadioButton::~RadioButton() = default;
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index e6938f3..b42ffa0 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc
@@ -143,13 +143,8 @@ UpdateBorder(); - // The combobox uses the ink drop on the TransparentButton, but the focus ring - // needs to be set on the combobox itself. To ensure that the ink drop fills - // the entire bounds of the combobox including the portion of the combobox - // bounds that the focus ring paints over, we need to install the focus ring - // first so that the focus ring is added as a child before the - // TransparentButton and therefore painted before the ink drop. FocusRing::Install(this); + views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); arrow_button_ = AddChildView(std::make_unique<TransparentButton>(base::BindRepeating(
diff --git a/ui/views/controls/editable_combobox/editable_combobox.cc b/ui/views/controls/editable_combobox/editable_combobox.cc index dd11a329..111cbec 100644 --- a/ui/views/controls/editable_combobox/editable_combobox.cc +++ b/ui/views/controls/editable_combobox/editable_combobox.cc
@@ -376,6 +376,7 @@ textfield_->set_controller(this); textfield_->SetFontList(GetFontList()); AddChildView(textfield_.get()); + views::FocusRing::Get(textfield_)->SetOutsetFocusRingDisabled(true); control_elements_container_ = AddChildView(std::make_unique<BoxLayoutView>()); if (features::IsChromeRefresh2023()) {
diff --git a/ui/views/controls/focus_ring.cc b/ui/views/controls/focus_ring.cc index f22aa01..7f00d4a 100644 --- a/ui/views/controls/focus_ring.cc +++ b/ui/views/controls/focus_ring.cc
@@ -172,6 +172,13 @@ OnPropertyChanged(&halo_inset_, PropertyEffects::kPropertyEffectsPaint); } +void FocusRing::SetOutsetFocusRingDisabled(bool disable) { + outset_focus_ring_disabled_ = disable; +} +bool FocusRing::GetOutsetFocusRingDisabled() const { + return outset_focus_ring_disabled_; +} + bool FocusRing::ShouldPaintForTesting() { return ShouldPaint(); } @@ -409,6 +416,7 @@ ADD_PROPERTY_METADATA(absl::optional<ui::ColorId>, ColorId) ADD_PROPERTY_METADATA(float, HaloInset) ADD_PROPERTY_METADATA(float, HaloThickness) +ADD_PROPERTY_METADATA(bool, OutsetFocusRingDisabled) END_METADATA } // namespace views
diff --git a/ui/views/controls/focus_ring.h b/ui/views/controls/focus_ring.h index 581afa5..50d3a09 100644 --- a/ui/views/controls/focus_ring.h +++ b/ui/views/controls/focus_ring.h
@@ -90,8 +90,8 @@ // Explicitly disable using style of focus ring that is drawn with a 2dp gap // between the focus ring and component. - void SetOutsetFocusRingDisabled() { outset_focus_ring_disabled_ = true; } - bool GetOutsetFocusRingDisabled() { return outset_focus_ring_disabled_; } + void SetOutsetFocusRingDisabled(bool disable); + bool GetOutsetFocusRingDisabled() const; bool ShouldPaintForTesting();
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 726695b..2920ccd 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -242,7 +242,7 @@ views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(), GetCornerRadius()); FocusRing::Install(this); - FocusRing::Get(this)->SetOutsetFocusRingDisabled(); + FocusRing::Get(this)->SetOutsetFocusRingDisabled(true); if (::features::IsChromeRefresh2023()) { InkDrop::Install(this, std::make_unique<views::InkDropHost>(this));