diff --git a/DEPS b/DEPS
index 52fee8f..52970a3 100644
--- a/DEPS
+++ b/DEPS
@@ -306,7 +306,7 @@
   # 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': '1952a3edba24b927f32150de88925e482835786d',
+  'skia_revision': '7f385b0ae4345975693950d86be0a55baf25efbe',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -314,11 +314,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'b6a15123758f86c0235867d9acb1315c4c5fab0b',
+  'angle_revision': '2dde73576aa07cacb11737df339b5e5576bd7899',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': 'dbdf74996a2c8182e842651726d5ba75b3725ffb',
+  'swiftshader_revision': 'dd35c62aef803501ca34453a48da76a298daaeee',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -333,7 +333,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:10.20221116.1.1',
+  'fuchsia_version': 'version:10.20221116.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.
@@ -377,7 +377,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'c8506af0cfa33512b54d5cba38eec42d9b731165',
+  'catapult_revision': 'db897bb206c1e7e6dee6d6df56a76858f7a06628',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -385,7 +385,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': '1aa5347ad5a44acc32633c154495d79f59c5f049',
+  'devtools_frontend_revision': '74d6ca1430994da985f6acc748059920cfcb2d70',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -421,7 +421,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'fad31fe74aaf84b1627364b206f7fd49941a39ee',
+  'dawn_revision': '99796361add4c7d7c452121bd01e46f5777df359',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -489,7 +489,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       '81925935fdd2102dbe94aa6aadfa5203a6f11dba',
+  'libcxx_revision':       'cd0a05047451dfbdef5ba85f97ac4888e432a377',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:1c4151ff5c1d6fbf7fa800b8d4bb34d3abc03a41',
@@ -816,12 +816,12 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    '96e7b73b2da29a845781c3c840612ee4ca50cd3e',
+    '8d6d5f4dd5440fc6f728c0823940e041e8b7e81f',
     'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'c146923049235a0bcd3b71c1e98aa24892e95a7a',
+    'url': Var('chromium_git') + '/website.git' + '@' + '102fcefea116b0e8c2c80307dbf3a0997640d2cf',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1000,7 +1000,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'krelcrYOcHkMcS_4oxzOl4ya1ady7UK4lOj118kjMTEC',
+          'version': 'EVyo1fY0G8ksQeheveyA3ozISCvDG5fejcsZrQ53EZgC',
       },
     ],
     'condition': 'checkout_android',
@@ -1243,13 +1243,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '63fea808b00889ca603f083febe010a8fa7dded7',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '25cf78395cd77e11b13c1bd26124e0a586c19166',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '65411bbd9e93a9d7be940ee4aa3bc4fd476534f2',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '32eb448f823abde257e9267e1909e5cf6a4aded2',
     'condition': 'checkout_src_internal',
   },
 
@@ -1525,7 +1525,7 @@
   },
 
   'src/third_party/libvpx/source/libvpx':
-    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '5245f6e9cb7e6bb68ab45fe4d8b00bc9b16857e1',
+    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '605350bd5b68ac47f595d60cc8ef346588e773c0',
 
   'src/third_party/libwebm/source':
     Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da',
@@ -1849,7 +1849,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '8c74caae35d253e20d294ed1c3d035726282587b',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '52b0ef792602250f1aa841cbc867ea00bfba1d5a',
+    Var('webrtc_git') + '/src.git' + '@' + 'cb2b133bf0a9c014ebff2753e3f82175cbaf0eb3',
 
   # 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.
@@ -1919,7 +1919,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f61b58e0b171e01527667c2f65f65faa6ee1ff4f',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3ca4c2a36d15b70059b635cc928f50980e871a93',
     'condition': 'checkout_src_internal',
   },
 
@@ -1960,7 +1960,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': '31PilC0ywCBZAk6Fagl2FfAW1lfKZbHz3c76FSzIohcC',
+        'version': 'zmiBpjkt4VMEbMwulYceFXxVUBIcN62gEmLqXGvVyXUC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4567,7 +4567,7 @@
     ],
   },
   {
-    'name': 'gvr_static_shim_android_arm_Cr',
+    'name': 'gvr_static_shim_android',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
     'action': [ 'python3',
@@ -4575,19 +4575,7 @@
                 '--no_resume',
                 '--no_auth',
                 '--bucket', 'chromium-gvr-static-shim',
-                '-s', 'src/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1',
-    ],
-  },
-  {
-    'name': 'gvr_static_shim_android_arm64_Cr',
-    'pattern': '\\.sha1',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                '--no_resume',
-                '--no_auth',
-                '--bucket', 'chromium-gvr-static-shim',
-                '-s', 'src/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1',
+                '-d', 'src/third_party/gvr-android-sdk',
     ],
   },
   {
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 86d5e3d..d2d99bb 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
@@ -174,9 +174,6 @@
                     "Enables Autofill to use its new method to retrieve parsing patterns."),
             Flag.baseFeature(AutofillFeatures.AUTOFILL_PAGE_LANGUAGE_DETECTION,
                     "Enables Autofill to retrieve the page language for form parsing."),
-            Flag.baseFeature(AutofillFeatures.AUTOFILL_PARSE_MERCHANT_PROMO_CODE_FIELDS,
-                    "When enabled, Autofill will attempt to find merchant promo/coupon/gift code "
-                            + "fields when parsing forms."),
             Flag.baseFeature(AutofillFeatures.AUTOFILL_RATIONALIZE_STREET_ADDRESS_AND_HOUSE_NUMBER,
                     "Rationalizes (street address, house number) field sequences to "
                             + "(street name, house number)."),
diff --git a/android_webview/tools/run_cts.py b/android_webview/tools/run_cts.py
index 7167b89..bb7cb407 100755
--- a/android_webview/tools/run_cts.py
+++ b/android_webview/tools/run_cts.py
@@ -423,8 +423,9 @@
       avd_config.Install()
       emulator_instance = avd_config.CreateInstance()
       # Start the emulator w/ -writable-system s.t. we can remount the system
-      # partition r/w and install our own webview provider.
-      emulator_instance.Start(writable_system=True)
+      # partition r/w and install our own webview provider. Require fast start
+      # to avoid startup regressions.
+      emulator_instance.Start(writable_system=True, require_fast_start=True)
 
     devices = script_common.GetDevices(args.devices, args.denylist_file)
     device = devices[0]
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc
index 60d89f7..75669cd6 100644
--- a/ash/accelerators/accelerator_controller_impl.cc
+++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -567,6 +567,11 @@
     case CYCLE_BACKWARD_MRU:
     case CYCLE_FORWARD_MRU:
       return accelerators::CanCycleMru();
+    case CYCLE_SAME_APP_WINDOWS_BACKWARD:
+    case CYCLE_SAME_APP_WINDOWS_FORWARD:
+      // TODO(b/250698986): Implement window switching functionality.
+      NOTIMPLEMENTED();
+      return false;
     case DESKS_ACTIVATE_DESK_LEFT:
     case DESKS_ACTIVATE_DESK_RIGHT:
     case DESKS_MOVE_ACTIVE_ITEM_LEFT:
@@ -799,6 +804,14 @@
       RecordCycleForwardMru(accelerator);
       accelerators::CycleForwardMru();
       break;
+    case CYCLE_SAME_APP_WINDOWS_BACKWARD:
+      // TODO(b/250698986): Implement window switching functionality.
+      NOTIMPLEMENTED();
+      break;
+    case CYCLE_SAME_APP_WINDOWS_FORWARD:
+      // TODO(b/250698986): Implement window switching functionality.
+      NOTIMPLEMENTED();
+      break;
     case DESKS_ACTIVATE_DESK_LEFT:
       // UMA metrics are recorded in the function.
       accelerators::ActivateDesk(/*activate_left=*/true);
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 452a608..49c9dccd 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -131,8 +131,10 @@
 
 const AcceleratorAction kPreferredActions[] = {
     // Window cycling accelerators.
-    CYCLE_BACKWARD_MRU,  // Shift+Alt+Tab
-    CYCLE_FORWARD_MRU,   // Alt+Tab
+    CYCLE_BACKWARD_MRU,               // Shift+Alt+Tab
+    CYCLE_FORWARD_MRU,                // Alt+Tab
+    CYCLE_SAME_APP_WINDOWS_BACKWARD,  // Shift+Alt+Backtick
+    CYCLE_SAME_APP_WINDOWS_FORWARD,   // Alt+Backtick
 };
 
 const size_t kPreferredActionsLength = std::size(kPreferredActions);
diff --git a/ash/accelerators/ash_accelerator_configuration.cc b/ash/accelerators/ash_accelerator_configuration.cc
index 91c2263e..d3b9234a 100644
--- a/ash/accelerators/ash_accelerator_configuration.cc
+++ b/ash/accelerators/ash_accelerator_configuration.cc
@@ -117,6 +117,12 @@
         base::make_span(kDisableWithNewMappingAcceleratorData,
                         kDisableWithNewMappingAcceleratorDataLength));
   }
+  if (ash::features::IsSameAppWindowCycleEnabled()) {
+    AppendAcceleratorData(
+        accelerators,
+        base::make_span(kEnableWithSameAppWindowCycleAcceleratorData,
+                        kEnableWithSameAppWindowCycleAcceleratorDataLength));
+  }
 
   // Debug accelerators.
   if (debug::DebugAcceleratorsEnabled()) {
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc
index b19dc33..fea947b 100644
--- a/ash/ambient/ambient_controller.cc
+++ b/ash/ambient/ambient_controller.cc
@@ -216,13 +216,6 @@
       DCHECK(!start_time_);
       start_time_ = base::Time::Now();
 
-      multi_screen_metrics_recorder_ =
-          std::make_unique<AmbientMultiScreenMetricsRecorder>(
-              GetCurrentTheme());
-      frame_rate_controller_ =
-          std::make_unique<AmbientAnimationFrameRateController>(
-              Shell::Get()->frame_throttling_controller());
-
       // Cancels the timer upon shown.
       inactivity_timer_.Stop();
 
@@ -235,16 +228,12 @@
       if (!power_status_observer_.IsObserving())
         power_status_observer_.Observe(PowerStatus::Get());
 
-      if (!user_activity_observer_.IsObserving())
-        user_activity_observer_.Observe(ui::UserActivityDetector::Get());
-
-      // Add observer for assistant interaction model
-      AssistantInteractionController::Get()->GetModel()->AddObserver(this);
-
-      Shell::Get()->AddPreTargetHandler(this);
-
-      StartRefreshingImages();
+      MaybeStartScreenSaver();
       break;
+    case AmbientUiVisibility::kPreview: {
+      MaybeStartScreenSaver();
+      break;
+    }
     case AmbientUiVisibility::kHidden:
     case AmbientUiVisibility::kClosed: {
       bool ambient_ui_was_rendering =
@@ -503,6 +492,15 @@
   ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kShown);
 }
 
+void AmbientController::StartScreenSaverPreview() {
+  if (!IsAmbientModeEnabled()) {
+    LOG(WARNING) << "Ambient mode is not allowed.";
+    return;
+  }
+
+  ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kPreview);
+}
+
 void AmbientController::ShowHiddenUi() {
   DVLOG(1) << __func__;
 
@@ -538,7 +536,8 @@
 }
 
 bool AmbientController::IsShown() const {
-  return ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kShown;
+  return ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kShown ||
+         ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kPreview;
 }
 
 void AmbientController::AcquireWakeLock() {
@@ -838,9 +837,11 @@
 
   widget->Show();
 
-  DCHECK(start_time_);
-  ambient::RecordAmbientModeStartupTime(base::Time::Now() - *start_time_,
-                                        current_theme);
+  if (ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kShown) {
+    DCHECK(start_time_);
+    ambient::RecordAmbientModeStartupTime(base::Time::Now() - *start_time_,
+                                          current_theme);
+  }
 
   // Only announce for the primary window.
   if (Shell::GetPrimaryRootWindow() == container->GetRootWindow()) {
@@ -896,6 +897,27 @@
   ambient_photo_controller_->StopScreenUpdate();
 }
 
+void AmbientController::MaybeStartScreenSaver() {
+  // The screensaver may have already been started.
+  if (ambient_photo_controller_->IsScreenUpdateActive())
+    return;
+
+  if (!user_activity_observer_.IsObserving())
+    user_activity_observer_.Observe(ui::UserActivityDetector::Get());
+
+  // Add observer for assistant interaction model
+  AssistantInteractionController::Get()->GetModel()->AddObserver(this);
+
+  multi_screen_metrics_recorder_ =
+      std::make_unique<AmbientMultiScreenMetricsRecorder>(GetCurrentTheme());
+  frame_rate_controller_ =
+      std::make_unique<AmbientAnimationFrameRateController>(
+          Shell::Get()->frame_throttling_controller());
+
+  Shell::Get()->AddPreTargetHandler(this);
+  StartRefreshingImages();
+}
+
 AmbientAnimationTheme AmbientController::GetCurrentTheme() const {
   DCHECK(current_theme_from_pref_);
   return *current_theme_from_pref_;
diff --git a/ash/ambient/ambient_controller.h b/ash/ambient/ambient_controller.h
index 9fe1eb7..bebc460a7 100644
--- a/ash/ambient/ambient_controller.h
+++ b/ash/ambient/ambient_controller.h
@@ -113,6 +113,7 @@
   void OnInteractionStateChanged(InteractionState interaction_state) override;
 
   void ShowUi();
+  void StartScreenSaverPreview();
   // Ui will be enabled but not shown immediately. If there is no user activity
   // Ui will be shown after a short delay.
   void ShowHiddenUi();
@@ -175,6 +176,7 @@
 
   void StartRefreshingImages();
   void StopRefreshingImages();
+  void MaybeStartScreenSaver();
   AmbientAnimationTheme GetCurrentTheme() const;
 
   // Invoked when the auto-show timer in |InactivityMonitor| gets fired after
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc
index f6043d8..705dccf 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -68,8 +68,9 @@
 
 constexpr int kContinueColumnCount = 2;
 
-// Insets for the vertical scroll bar.
-constexpr auto kVerticalScrollInsets = gfx::Insets::TLBR(1, 0, 1, 1);
+// Insets for the vertical scroll bar. The bottom is pushed up slightly to keep
+// the scroll bar from being clipped by the rounded corners.
+constexpr auto kVerticalScrollInsets = gfx::Insets::TLBR(1, 0, 16, 1);
 
 // The padding between different sections within the apps page. Also used for
 // interior apps page container margin.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 1b6b495..d8822136 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -77,12 +77,6 @@
              "ChromeOSAmbientMode",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Allows Cryptohome to migrate existing VaultKeysets to AuthFactors and
-// UserSecretStash.
-BASE_FEATURE(kMigrateToUserSecretStash,
-             "MigrateToUserSecretStash",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 constexpr base::FeatureParam<bool> kAmbientModeCapturedOnPixelAlbumEnabled{
     &kAmbientModeFeature, "CapturedOnPixelAlbumEnabled", false};
 
@@ -816,7 +810,7 @@
 // e.g. available KMS hardware planes.
 BASE_FEATURE(kExoLinuxDmabufV4,
              "ExoLinuxDmabufV4",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Enable or disable use of ordinal (unaccelerated) motion by Exo clients.
 BASE_FEATURE(kExoOrdinalMotion,
@@ -1531,12 +1525,6 @@
 // currently active desk.
 BASE_FEATURE(kPerDeskShelf, "PerDeskShelf", base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Allows tablet mode split screen to resize by moving windows instead of
-// resizing. This reduces jank on low end devices.
-BASE_FEATURE(kPerformantSplitViewResizing,
-             "PerformantSplitViewResizing",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Provides a UI for users to view information about their Android phone
 // and perform phone-side actions within ChromeOS.
 BASE_FEATURE(kPhoneHub, "PhoneHub", base::FEATURE_ENABLED_BY_DEFAULT);
@@ -2231,10 +2219,6 @@
   return base::FeatureList::IsEnabled(kEnable16Desks);
 }
 
-bool IsMigrateToUserSecretStashEnabled() {
-  return base::FeatureList::IsEnabled(kMigrateToUserSecretStash);
-}
-
 bool IsAdaptiveChargingEnabled() {
   return base::FeatureList::IsEnabled(kAdaptiveCharging);
 }
@@ -2874,10 +2858,6 @@
   return base::FeatureList::IsEnabled(kPhoneHubPingOnBubbleOpen);
 }
 
-bool IsPerformantSplitViewResizingEnabled() {
-  return base::FeatureList::IsEnabled(kPerformantSplitViewResizing);
-}
-
 bool IsPhoneHubEnabled() {
   return base::FeatureList::IsEnabled(kPhoneHub);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 1a10270c..f9218f4 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -398,8 +398,6 @@
 BASE_DECLARE_FEATURE(kEducationEnrollmentOobeFlow);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMicMuteNotifications);
 COMPONENT_EXPORT(ASH_CONSTANTS)
-BASE_DECLARE_FEATURE(kMigrateToUserSecretStash);
-COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kDisableMessagesCrossDeviceIntegration);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMinimumChromeVersion);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMojoDBusRelay);
@@ -438,8 +436,6 @@
 BASE_DECLARE_FEATURE(kPcieBillboardNotification);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerDeskShelf);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerUserMetrics);
-COMPONENT_EXPORT(ASH_CONSTANTS)
-BASE_DECLARE_FEATURE(kPerformantSplitViewResizing);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPhoneHub);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPhoneHubCameraRoll);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -748,7 +744,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMacAddressRandomizationEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsManagedTermsOfServiceEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMicMuteNotificationsEnabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMigrateToUserSecretStashEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMinimumChromeVersionEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNearbyKeepAliveFixEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNetworkingInDiagnosticsAppEnabled();
@@ -785,7 +780,6 @@
 bool IsPhoneHubMonochromeNotificationIconsEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsPhoneHubPingOnBubbleOpenEnabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPerformantSplitViewResizingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPhoneHubEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPhoneHubCallNotificationEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPinAutosubmitBackfillFeatureEnabled();
diff --git a/ash/display/screen_ash.cc b/ash/display/screen_ash.cc
index cdb6fdd..b03493f 100644
--- a/ash/display/screen_ash.cc
+++ b/ash/display/screen_ash.cc
@@ -157,6 +157,13 @@
   return display_manager->GetDisplayForId(id);
 }
 
+void ScreenAsh::SetDisplayForNewWindows(int64_t display_id) {
+  if (display_id_for_new_windows() == display_id)
+    return;
+  Screen::SetDisplayForNewWindows(display_id);
+  Shell::Get()->NotifyDisplayForNewWindowsChanged();
+}
+
 display::Display ScreenAsh::GetDisplayNearestPoint(
     const gfx::Point& point) const {
   const display::Display& display =
diff --git a/ash/display/screen_ash.h b/ash/display/screen_ash.h
index 7196ca7..f4205bd 100644
--- a/ash/display/screen_ash.h
+++ b/ash/display/screen_ash.h
@@ -49,6 +49,7 @@
   display::Display GetDisplayMatching(
       const gfx::Rect& match_rect) const override;
   display::Display GetPrimaryDisplay() const override;
+  void SetDisplayForNewWindows(int64_t display_id) override;
   void AddObserver(display::DisplayObserver* observer) override;
   void RemoveObserver(display::DisplayObserver* observer) override;
   display::TabletState GetTabletState() const override;
diff --git a/ash/public/cpp/accelerators.cc b/ash/public/cpp/accelerators.cc
index 7c1dc6d..9e0d9e71 100644
--- a/ash/public/cpp/accelerators.cc
+++ b/ash/public/cpp/accelerators.cc
@@ -349,6 +349,15 @@
 const size_t kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorDataLength =
     std::size(kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorData);
 
+const AcceleratorData kEnableWithSameAppWindowCycleAcceleratorData[] = {
+    {true, ui::VKEY_OEM_3, ui::EF_ALT_DOWN, CYCLE_SAME_APP_WINDOWS_FORWARD},
+    {true, ui::VKEY_OEM_3, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
+     CYCLE_SAME_APP_WINDOWS_BACKWARD},
+};
+
+const size_t kEnableWithSameAppWindowCycleAcceleratorDataLength =
+    std::size(kEnableWithSameAppWindowCycleAcceleratorData);
+
 // static
 AcceleratorController* AcceleratorController::Get() {
   return g_instance;
diff --git a/ash/public/cpp/accelerators.h b/ash/public/cpp/accelerators.h
index 17c6daf..ddf7fbe 100644
--- a/ash/public/cpp/accelerators.h
+++ b/ash/public/cpp/accelerators.h
@@ -27,6 +27,8 @@
   BRIGHTNESS_UP,
   CYCLE_BACKWARD_MRU,
   CYCLE_FORWARD_MRU,
+  CYCLE_SAME_APP_WINDOWS_BACKWARD,
+  CYCLE_SAME_APP_WINDOWS_FORWARD,
   DESKS_ACTIVATE_DESK_LEFT,
   DESKS_ACTIVATE_DESK_RIGHT,
   DESKS_MOVE_ACTIVE_ITEM_LEFT,
@@ -212,6 +214,12 @@
 ASH_PUBLIC_EXPORT extern const size_t
     kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorDataLength;
 
+// Accelerators that are enabled with same app window cycling experiment.
+ASH_PUBLIC_EXPORT extern const AcceleratorData
+    kEnableWithSameAppWindowCycleAcceleratorData[];
+ASH_PUBLIC_EXPORT extern const size_t
+    kEnableWithSameAppWindowCycleAcceleratorDataLength;
+
 // The public-facing interface for accelerator handling, which is Ash's duty to
 // implement.
 class ASH_PUBLIC_EXPORT AcceleratorController {
diff --git a/ash/public/cpp/ambient/ambient_ui_model.cc b/ash/public/cpp/ambient/ambient_ui_model.cc
index b94e066f..3e4ea19 100644
--- a/ash/public/cpp/ambient/ambient_ui_model.cc
+++ b/ash/public/cpp/ambient/ambient_ui_model.cc
@@ -105,6 +105,9 @@
     case AmbientUiVisibility::kShown:
       out << "kShown";
       break;
+    case AmbientUiVisibility::kPreview:
+      out << "kPreview";
+      break;
     case AmbientUiVisibility::kHidden:
       out << "kHidden";
       break;
diff --git a/ash/public/cpp/ambient/ambient_ui_model.h b/ash/public/cpp/ambient/ambient_ui_model.h
index 8831203..fb2f4d3 100644
--- a/ash/public/cpp/ambient/ambient_ui_model.h
+++ b/ash/public/cpp/ambient/ambient_ui_model.h
@@ -14,9 +14,13 @@
 
 // Enumeration of UI visibility states.
 enum class AmbientUiVisibility {
-  kShown,
-  kHidden,
-  kClosed,
+  kShown,    // Screen saver is shown.
+  kPreview,  // Same as kShown, but do not lock screen or acquire wake lock.
+             // kPreview state is used to show a preview of the screensaver.
+             // Users should be able to exit from the preview mode directly
+             // into. Hence, no need to lock the screen or acquire wake lock.
+  kHidden,   // Screen saver is closed; start inactivity timer to restart it.
+  kClosed,   // Screen saver is closed; all observers and timers are cancelled.
 };
 
 // Enumeration of ambient UI modes. This is used for metrics reporting and
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc
index 65a65c3..dd5b761 100644
--- a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc
+++ b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc
@@ -45,6 +45,20 @@
              nearby::fastpair::DeviceType::DEVICE_TYPE_UNSPECIFIED;
 }
 
+bool IsSupportedNotificationType(const nearby::fastpair::Device& device) {
+  // We only allow-list notification types that should trigger a pairing
+  // notification, since we currently only support pairing. We include
+  // NOTIFICATION_TYPE_UNSPECIFIED to handle the case where a Provider is
+  // advertising incorrectly and conservatively allow it to show a notification,
+  // matching Android behavior.
+  return device.notification_type() == nearby::fastpair::NotificationType::
+                                           NOTIFICATION_TYPE_UNSPECIFIED ||
+         device.notification_type() ==
+             nearby::fastpair::NotificationType::FAST_PAIR ||
+         device.notification_type() ==
+             nearby::fastpair::NotificationType::FAST_PAIR_ONE;
+}
+
 }  // namespace
 
 namespace ash {
@@ -186,6 +200,16 @@
     return;
   }
 
+  // Ignore advertisements for unsupported notification types, such as
+  // APP_LAUNCH which should launch a companion app instead of beginning Fast
+  // Pair.
+  if (!IsSupportedNotificationType(device_metadata->GetDetails())) {
+    QP_LOG(WARNING) << __func__
+                    << ": Unsupported notification type for Fast Pair. "
+                       "Ignoring this advertisement";
+    return;
+  }
+
   auto device = base::MakeRefCounted<Device>(model_id, address,
                                              Protocol::kFastPairInitial);
 
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl_unittest.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl_unittest.cc
index af213f6f..fc6240d 100644
--- a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl_unittest.cc
+++ b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl_unittest.cc
@@ -259,6 +259,74 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(FastPairDiscoverableScannerImplTest, UnspecifiedNotificationType) {
+  // Set metadata to mimic a device that doesn't specify the notification
+  // or device type. Since we aren't sure what this device is, we'll show
+  // the notification to be safe.
+  nearby::fastpair::Device metadata;
+  metadata.set_trigger_distance(2);
+  metadata.set_device_type(
+      nearby::fastpair::DeviceType::DEVICE_TYPE_UNSPECIFIED);
+  metadata.set_notification_type(
+      nearby::fastpair::NotificationType::NOTIFICATION_TYPE_UNSPECIFIED);
+  repository_->SetFakeMetadata(kValidModelId, metadata);
+
+  EXPECT_CALL(found_device_callback_, Run).Times(1);
+  device::BluetoothDevice* device = GetDevice(kValidModelId);
+  scanner_->NotifyDeviceFound(device);
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(FastPairDiscoverableScannerImplTest, V1NotificationType) {
+  // Set metadata to mimic a V1 device which advertises with no device
+  // type and a notification type of FAST_PAIR_ONE.
+  nearby::fastpair::Device metadata;
+  metadata.set_trigger_distance(2);
+  metadata.set_device_type(
+      nearby::fastpair::DeviceType::DEVICE_TYPE_UNSPECIFIED);
+  metadata.set_notification_type(
+      nearby::fastpair::NotificationType::FAST_PAIR_ONE);
+  repository_->SetFakeMetadata(kValidModelId, metadata);
+
+  EXPECT_CALL(found_device_callback_, Run).Times(1);
+  device::BluetoothDevice* device = GetDevice(kValidModelId);
+  scanner_->NotifyDeviceFound(device);
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(FastPairDiscoverableScannerImplTest, V2NotificationType) {
+  // Set metadata to mimic a V2 device which advertises with a device
+  // type of TRUE_WIRELESS_HEADPHONES and a notification type of FAST_PAIR.
+  nearby::fastpair::Device metadata;
+  metadata.set_trigger_distance(2);
+  metadata.set_device_type(
+      nearby::fastpair::DeviceType::TRUE_WIRELESS_HEADPHONES);
+  metadata.set_notification_type(nearby::fastpair::NotificationType::FAST_PAIR);
+  repository_->SetFakeMetadata(kValidModelId, metadata);
+
+  EXPECT_CALL(found_device_callback_, Run).Times(1);
+  device::BluetoothDevice* device = GetDevice(kValidModelId);
+  scanner_->NotifyDeviceFound(device);
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(FastPairDiscoverableScannerImplTest, WrongNotificationType) {
+  // Set metadata to mimic a Fitbit wearable which advertises with no
+  // device type and a notification type of APP_LAUNCH.
+  nearby::fastpair::Device metadata;
+  metadata.set_trigger_distance(2);
+  metadata.set_device_type(
+      nearby::fastpair::DeviceType::DEVICE_TYPE_UNSPECIFIED);
+  metadata.set_notification_type(
+      nearby::fastpair::NotificationType::APP_LAUNCH);
+  repository_->SetFakeMetadata(kValidModelId, metadata);
+
+  EXPECT_CALL(found_device_callback_, Run).Times(0);
+  device::BluetoothDevice* device = GetDevice(kValidModelId);
+  scanner_->NotifyDeviceFound(device);
+  base::RunLoop().RunUntilIdle();
+}
+
 TEST_F(FastPairDiscoverableScannerImplTest, DeviceLost) {
   EXPECT_CALL(found_device_callback_, Run).Times(0);
   device::BluetoothDevice* device = GetDevice(kValidModelId);
diff --git a/ash/shell.cc b/ash/shell.cc
index 86af072..cc0e7b9 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -571,6 +571,11 @@
     observer.OnShelfAlignmentChanged(root_window, old_alignment);
 }
 
+void Shell::NotifyDisplayForNewWindowsChanged() {
+  for (auto& observer : shell_observers_)
+    observer.OnDisplayForNewWindowsChanged();
+}
+
 void Shell::AddAccessibilityEventHandler(
     ui::EventHandler* handler,
     AccessibilityEventHandlerManager::HandlerType type) {
diff --git a/ash/shell.h b/ash/shell.h
index c0b20b99..1d93d09 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -756,6 +756,9 @@
   void NotifyShelfAlignmentChanged(aura::Window* root_window,
                                    ShelfAlignment old_alignment);
 
+  // Notifies observers that the display for new windows has changed.
+  void NotifyDisplayForNewWindowsChanged();
+
   // Adds the |handler| based on its |type| to receive events, ensuring that
   // event handlers continue to be called in their HandlerType order.
   void AddAccessibilityEventHandler(
diff --git a/ash/shell_observer.h b/ash/shell_observer.h
index 20f6b01..ac10425 100644
--- a/ash/shell_observer.h
+++ b/ash/shell_observer.h
@@ -43,6 +43,8 @@
   // Invoked when |pinned_window| enter or exit pinned mode.
   virtual void OnPinnedStateChanged(aura::Window* pinned_window) {}
 
+  virtual void OnDisplayForNewWindowsChanged() {}
+
   // Called when dictation is activated.
   virtual void OnDictationStarted() {}
 
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc
index 143177e8..b734436 100644
--- a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc
+++ b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc
@@ -15,10 +15,13 @@
 #include "ash/system/keyboard_brightness/keyboard_backlight_color_nudge_controller.h"
 #include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h"
+#include "base/functional/bind.h"
 #include "base/metrics/histogram_functions.h"
+#include "chromeos/dbus/power/power_manager_client.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/session_manager/session_manager_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace ash {
@@ -67,6 +70,7 @@
     const AccountId& account_id) {
   DisplayBacklightColor(backlight_color);
   SetBacklightColorPref(backlight_color, account_id);
+  MaybeToggleOnKeyboardBrightness();
 }
 
 personalization_app::mojom::BacklightColor
@@ -189,4 +193,21 @@
                    static_cast<int>(backlight_color));
 }
 
+void KeyboardBacklightColorController::MaybeToggleOnKeyboardBrightness() {
+  DVLOG(1) << __func__ << " getting keyboard brightness";
+  chromeos::PowerManagerClient::Get()->GetKeyboardBrightnessPercent(
+      base::BindOnce(
+          &KeyboardBacklightColorController::KeyboardBrightnessPercentReceived,
+          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void KeyboardBacklightColorController::KeyboardBrightnessPercentReceived(
+    absl::optional<double> percentage) {
+  if (!percentage.has_value() || percentage.value() == 0.0) {
+    DVLOG(1) << __func__ << " Toggling on the keyboard brightness.";
+    // TODO(b/244139677): Calls API to turn on the keyboard brightness.
+    keyboard_brightness_on_for_testing_ = true;
+  }
+}
+
 }  // namespace ash
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.h b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.h
index 7809662..d1cc90c 100644
--- a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.h
+++ b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.h
@@ -15,6 +15,7 @@
 #include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h"
 #include "base/scoped_observation.h"
 #include "components/session_manager/session_manager_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 class PrefRegistrySimple;
@@ -77,7 +78,14 @@
       personalization_app::mojom::BacklightColor backlight_color,
       const AccountId& account_id);
 
+  // Toggles on the keyboard brightness at 40% if the backlight is off.
+  void MaybeToggleOnKeyboardBrightness();
+
+  // Callbacks:
+  void KeyboardBrightnessPercentReceived(absl::optional<double> percentage);
+
   SkColor displayed_color_for_testing_ = SK_ColorTRANSPARENT;
+  bool keyboard_brightness_on_for_testing_ = false;
 
   base::ScopedObservation<SessionControllerImpl, SessionObserver>
       session_observer_{this};
@@ -87,6 +95,9 @@
 
   std::unique_ptr<KeyboardBacklightColorNudgeController>
       keyboard_backlight_color_nudge_controller_;
+
+  base::WeakPtrFactory<KeyboardBacklightColorController> weak_ptr_factory_{
+      this};
 };
 
 }  // namespace ash
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc b/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc
index 731c662d..1799b5aa 100644
--- a/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc
+++ b/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc
@@ -103,6 +103,14 @@
     return controller_->displayed_color_for_testing_;
   }
 
+  bool keyboard_brightness_on_for_testing() const {
+    return controller_->keyboard_brightness_on_for_testing_;
+  }
+
+  void set_keyboard_brightness_off_for_testing() const {
+    controller_->keyboard_brightness_on_for_testing_ = false;
+  }
+
   void clear_displayed_color() {
     controller_->displayed_color_for_testing_ = SK_ColorTRANSPARENT;
   }
@@ -221,4 +229,16 @@
   controller_->OnRgbKeyboardSupportedChanged(true);
   EXPECT_EQ(kDefaultColor, displayed_color());
 }
+
+TEST_F(KeyboardBacklightColorControllerTest, TurnsOnKeyboardBrightnessWhenOff) {
+  SimulateUserLogin(account_id_1);
+  set_keyboard_brightness_off_for_testing();
+  controller_->SetBacklightColor(
+      personalization_app::mojom::BacklightColor::kBlue, account_id_1);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(personalization_app::mojom::BacklightColor::kBlue,
+            controller_->GetBacklightColor(account_id_1));
+  EXPECT_TRUE(keyboard_brightness_on_for_testing());
+}
+
 }  // namespace ash
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc
index 55309ab..120efd40 100644
--- a/ash/system/tray/tray_detailed_view.cc
+++ b/ash/system/tray/tray_detailed_view.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "ash/constants/ash_features.h"
+#include "ash/controls/rounded_scroll_bar.h"
 #include "ash/public/cpp/ash_view_ids.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_provider.h"
@@ -61,6 +62,10 @@
 
 constexpr int kQsScrollViewCornerRadius = 16;
 
+// Inset the scroll bar to avoid the rounded corners at top and bottom.
+constexpr auto kQsScrollBarInsets =
+    gfx::Insets::VH(kQsScrollViewCornerRadius, 0);
+
 // Configures the TriView used for the title in a detailed view.
 void ConfigureTitleTriView(TriView* tri_view, TriView::Container container) {
   std::unique_ptr<views::BoxLayout> layout;
@@ -432,6 +437,10 @@
   // TODO(varkha): Make the sticky rows work with EnableViewPortLayer().
 
   if (features::IsQsRevampEnabled()) {
+    auto vertical_scroll = std::make_unique<RoundedScrollBar>(
+        /*horizontal=*/false);
+    vertical_scroll->SetInsets(kQsScrollBarInsets);
+    scroller_->SetVerticalScrollBar(std::move(vertical_scroll));
     scroller_->SetProperty(views::kMarginsKey,
                            delegate_->GetScrollViewMargin());
     scroller_->SetPaintToLayer();
diff --git a/ash/test/pixel/ash_pixel_test_helper.cc b/ash/test/pixel/ash_pixel_test_helper.cc
index 09b914f..8c6f2bc 100644
--- a/ash/test/pixel/ash_pixel_test_helper.cc
+++ b/ash/test/pixel/ash_pixel_test_helper.cc
@@ -12,7 +12,6 @@
 #include "base/i18n/base_i18n_switches.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
-#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
 #include "ui/gfx/image/image_skia.h"
 
 namespace ash {
@@ -74,11 +73,15 @@
     case pixel_test::WallpaperInitType::kRegular: {
       gfx::ImageSkia wallpaper_image =
           CreateImage(wallpaper_size, kWallPaperColor);
+      controller->set_allow_blur_or_shield_for_testing();
+
+      // Use the one shot wallpaper to ensure that the custom wallpaper set by
+      // pixel tests does not go away after changing display metrics.
       controller->ShowWallpaperImage(
           wallpaper_image,
           WallpaperInfo{/*in_location=*/std::string(),
                         /*in_layout=*/WALLPAPER_LAYOUT_STRETCH,
-                        /*in_type=*/WallpaperType::kDefault,
+                        /*in_type=*/WallpaperType::kOneShot,
                         /*in_date=*/base::Time::Now().LocalMidnight()},
           /*preview_mode=*/false, /*always_on_top=*/false);
       break;
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 30ab22c..fb821d8 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -904,11 +904,13 @@
     needs_shield = true;
   }
 
-  return needs_shield && !IsOneShotWallpaper();
+  return needs_shield &&
+         (!IsOneShotWallpaper() || allow_blur_or_shield_for_testing_);
 }
 
 bool WallpaperControllerImpl::IsBlurAllowedForLockState() const {
-  return !IsDevicePolicyWallpaper() && !IsOneShotWallpaper();
+  return !IsDevicePolicyWallpaper() &&
+         (!IsOneShotWallpaper() || allow_blur_or_shield_for_testing_);
 }
 
 bool WallpaperControllerImpl::SetUserWallpaperInfo(const AccountId& account_id,
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h
index 8f0e55d..a71c723 100644
--- a/ash/wallpaper/wallpaper_controller_impl.h
+++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -381,6 +381,10 @@
 
   void set_bypass_decode_for_testing() { bypass_decode_for_testing_ = true; }
 
+  void set_allow_blur_or_shield_for_testing() {
+    allow_blur_or_shield_for_testing_ = true;
+  }
+
   // Exposed for testing.
   void UpdateDailyRefreshWallpaperForTesting();
   base::WallClockTimer& GetUpdateWallpaperTimerForTesting();
@@ -862,6 +866,9 @@
   // Tracks how many wallpapers have been set.
   int wallpaper_count_for_testing_ = 0;
 
+  // If true, the one shot wallpaper is allowed to be blurred or shielded.
+  bool allow_blur_or_shield_for_testing_ = false;
+
   // The file paths of decoding requests that have been initiated. Must be a
   // list because more than one decoding requests may happen during a single
   // 'set wallpaper' request. (e.g. when a custom wallpaper decoding fails, a
diff --git a/ash/webui/common/resources/BUILD.gn b/ash/webui/common/resources/BUILD.gn
index 95fcdab..bccb20e 100644
--- a/ash/webui/common/resources/BUILD.gn
+++ b/ash/webui/common/resources/BUILD.gn
@@ -84,6 +84,7 @@
   "network/network_select.js",
   "network/network_siminfo.js",
   "network/sim_lock_dialogs.js",
+  "network/apn_detail_dialog.js",
   "quick_unlock/pin_keyboard.js",
   "quick_unlock/setup_pin_keyboard.js",
   "smb_shares/add_smb_share_dialog.js",
@@ -389,6 +390,7 @@
   "network/network_proxy.d.ts",
   "network/network_siminfo.d.ts",
   "network/sim_lock_dialogs.d.ts",
+  "network/apn_detail_dialog.d.ts",
 ]
 
 copy("copy_checked_in_dts_files") {
diff --git a/ash/webui/common/resources/network/BUILD.gn b/ash/webui/common/resources/network/BUILD.gn
index 9bf0d9a..d16a12d 100644
--- a/ash/webui/common/resources/network/BUILD.gn
+++ b/ash/webui/common/resources/network/BUILD.gn
@@ -11,6 +11,7 @@
   closure_flags = default_closure_args + mojom_js_args
 
   deps = [
+    ":apn_detail_dialog",
     ":apn_list",
     ":apn_list_item",
     ":cellular_utils",
@@ -115,6 +116,17 @@
       [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
+js_library("apn_detail_dialog") {
+  deps = [
+    "//ash/webui/common/resources:i18n_behavior",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
+}
+
 js_library("network_config") {
   deps = [
     ":mojo_interface_provider",
diff --git a/ash/webui/common/resources/network/apn_detail_dialog.d.ts b/ash/webui/common/resources/network/apn_detail_dialog.d.ts
new file mode 100644
index 0000000..983fe59
--- /dev/null
+++ b/ash/webui/common/resources/network/apn_detail_dialog.d.ts
@@ -0,0 +1,5 @@
+// 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.
+
+export {};
diff --git a/ash/webui/common/resources/network/apn_detail_dialog.html b/ash/webui/common/resources/network/apn_detail_dialog.html
new file mode 100644
index 0000000..9f89147
--- /dev/null
+++ b/ash/webui/common/resources/network/apn_detail_dialog.html
@@ -0,0 +1,14 @@
+<cr-dialog id="apnDetailDialog"
+    close-text="[[i18n('close')]]" show-on-attach>
+  <div id="apnDetailDialogTitle" slot="title">
+    [[i18n('apnDetailAddApnDialogTitle')]]
+  </div>
+  <div slot="body">
+  </div>
+  <div slot="button-container">
+    <cr-button id="apnDetailCancelBtn" class="cancel-button"
+        on-click="onCancelClicked_">
+      [[i18n('cancel')]]
+    </cr-button>
+  </div>
+</cr-dialog>
\ No newline at end of file
diff --git a/ash/webui/common/resources/network/apn_detail_dialog.js b/ash/webui/common/resources/network/apn_detail_dialog.js
new file mode 100644
index 0000000..5f60684
--- /dev/null
+++ b/ash/webui/common/resources/network/apn_detail_dialog.js
@@ -0,0 +1,48 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * UI element which will show a dialog to create, view or edit APNs.
+ */
+
+import '//resources/cr_elements/cr_button/cr_button.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.js';
+
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/ash/common/i18n_behavior.js';
+import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './apn_detail_dialog.html.js';
+
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ */
+const ApnDetailDialogElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement);
+
+/** @polymer */
+class ApnDetailDialog extends ApnDetailDialogElementBase {
+  static get is() {
+    return 'apn-detail-dialog';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  /**
+   * @param {!Event} event
+   * @private
+   */
+  onCancelClicked_(event) {
+    event.stopPropagation();
+    if (this.$.apnDetailDialog.open) {
+      this.$.apnDetailDialog.close();
+    }
+  }
+}
+
+customElements.define(ApnDetailDialog.is, ApnDetailDialog);
diff --git a/ash/webui/diagnostics_ui/backend/input/input_data_provider_keyboard.cc b/ash/webui/diagnostics_ui/backend/input/input_data_provider_keyboard.cc
index a8e6209..f82d46e 100644
--- a/ash/webui/diagnostics_ui/backend/input/input_data_provider_keyboard.cc
+++ b/ash/webui/diagnostics_ui/backend/input/input_data_provider_keyboard.cc
@@ -207,9 +207,10 @@
 mojom::MechanicalLayout GetSystemMechanicalLayout() {
   chromeos::system::StatisticsProvider* stats_provider =
       chromeos::system::StatisticsProvider::GetInstance();
-  std::string layout_string;
-  if (!stats_provider->GetMachineStatistic(
-          chromeos::system::kKeyboardMechanicalLayoutKey, &layout_string)) {
+  const absl::optional<base::StringPiece> layout_string =
+      stats_provider->GetMachineStatistic(
+          chromeos::system::kKeyboardMechanicalLayoutKey);
+  if (!layout_string) {
     LOG(ERROR) << "Couldn't determine mechanical layout";
     return mojom::MechanicalLayout::kUnknown;
   }
@@ -220,7 +221,7 @@
   } else if (layout_string == "JIS") {
     return mojom::MechanicalLayout::kJis;
   } else {
-    LOG(ERROR) << "Unknown mechanical layout " << layout_string;
+    LOG(ERROR) << "Unknown mechanical layout " << layout_string.value();
     return mojom::MechanicalLayout::kUnknown;
   }
 }
@@ -228,14 +229,14 @@
 absl::optional<std::string> GetRegionCode() {
   chromeos::system::StatisticsProvider* stats_provider =
       chromeos::system::StatisticsProvider::GetInstance();
-  std::string layout_string;
-  if (!stats_provider->GetMachineStatistic(chromeos::system::kRegionKey,
-                                           &layout_string)) {
+  const absl::optional<base::StringPiece> layout_string =
+      stats_provider->GetMachineStatistic(chromeos::system::kRegionKey);
+  if (!layout_string) {
     LOG(ERROR) << "Couldn't determine region";
     return absl::nullopt;
   }
 
-  return layout_string;
+  return std::string(layout_string.value());
 }
 
 }  // namespace
diff --git a/ash/webui/diagnostics_ui/resources/input_list.html b/ash/webui/diagnostics_ui/resources/input_list.html
index 5bf2fd3..65cd59de 100644
--- a/ash/webui/diagnostics_ui/resources/input_list.html
+++ b/ash/webui/diagnostics_ui/resources/input_list.html
@@ -6,13 +6,13 @@
     flex-direction: column;
   }
 </style>
-<div id="inputListContainer">
+<div id="inputListContainer" tabindex="0">
   <div class="diagnostics-cards-container-nav">
     <div class="card-width">
       <template is="dom-if" if="[[keyboards_.length]]">
-        <input-card device-type="keyboard" devices="[[keyboards_]]"
+        <input-card device-type="keyboard" devices="[[keyboards_]]" id="keyboardInputCard"
             on-test-button-click="handleKeyboardTestButtonClick_">
-          <div slot="title">[[i18n('inputCategoryKeyboard')]]</div>
+          <div slot="title" id="keyboardTitle" tabindex="0">[[i18n('inputCategoryKeyboard')]]</div>
         </input-card>
       </template>
       <template is="dom-if" if="[[showTouchpads_]]">
diff --git a/ash/webui/diagnostics_ui/resources/input_list.ts b/ash/webui/diagnostics_ui/resources/input_list.ts
index 079fedd4..0c2f9f29f 100644
--- a/ash/webui/diagnostics_ui/resources/input_list.ts
+++ b/ash/webui/diagnostics_ui/resources/input_list.ts
@@ -10,9 +10,10 @@
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {DiagnosticsBrowserProxy, DiagnosticsBrowserProxyImpl} from './diagnostics_browser_proxy.js';
+import {InputCardElement} from './input_card.js';
 import {ConnectedDevicesObserverReceiver, ConnectionType, InputDataProviderInterface, InternalDisplayPowerStateObserverReceiver, KeyboardInfo, TouchDeviceInfo, TouchDeviceType} from './input_data_provider.mojom-webui.js';
 import {getTemplate} from './input_list.html.js';
 import {KeyboardTesterElement} from './keyboard_tester.js';
@@ -273,6 +274,24 @@
    */
   onNavigationPageChanged({isActive}: {isActive: boolean}): void {
     if (isActive) {
+      // Focus the first visible card title. If no cards are present,
+      // fallback to focusing the element's main container.
+      afterNextRender(this, () => {
+        if (this.keyboards_) {
+          const keyboard: InputCardElement|null =
+              this.shadowRoot!.querySelector('#keyboardInputCard');
+          assert(keyboard);
+          const keyboardTitle: HTMLDivElement|null =
+              keyboard.querySelector('#keyboardTitle');
+          assert(keyboardTitle);
+          keyboardTitle.focus();
+        } else {
+          const inputListContainer: HTMLDivElement|null =
+              this.shadowRoot!.querySelector('#inputListContainer');
+          assert(inputListContainer);
+          inputListContainer.focus();
+        }
+      });
       // TODO(ashleydp): Remove when a call can be made at a higher component
       // to avoid duplicate code in all navigatable pages.
       this.browserProxy_.recordNavigation('input');
diff --git a/ash/wm/desks/desk_mini_view_animations.cc b/ash/wm/desks/desk_mini_view_animations.cc
index 39d1e347..89a14011 100644
--- a/ash/wm/desks/desk_mini_view_animations.cc
+++ b/ash/wm/desks/desk_mini_view_animations.cc
@@ -24,9 +24,7 @@
 
 namespace {
 
-gfx::Transform GetEndTransform() {
-  return gfx::Transform();
-}
+constexpr gfx::Transform kEndTransform;
 
 constexpr base::TimeDelta kExistingMiniViewsAnimationDuration =
     base::Milliseconds(250);
@@ -57,7 +55,7 @@
 
   ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
   InitScopedAnimationSettings(&settings, kExistingMiniViewsAnimationDuration);
-  layer->SetTransform(GetEndTransform());
+  layer->SetTransform(kEndTransform);
 }
 
 // See details at AnimateView.
@@ -98,7 +96,7 @@
 
   ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
   InitScopedAnimationSettings(&settings, kZeroStateAnimationDuration);
-  layer->SetTransform(GetEndTransform());
+  layer->SetTransform(kEndTransform);
   layer->SetOpacity(1.f);
 }
 
@@ -138,7 +136,7 @@
       layer->SetTransform(GetScaleTransformForView(
           removed_mini_view, bar_view->bounds().CenterPoint().x()));
     } else {
-      layer->SetTransform(GetEndTransform());
+      layer->SetTransform(kEndTransform);
     }
     layer->SetOpacity(0);
   }
@@ -258,7 +256,7 @@
     ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
     InitScopedAnimationSettings(&settings, kExistingMiniViewsAnimationDuration);
     layer->SetOpacity(1);
-    layer->SetTransform(GetEndTransform());
+    layer->SetTransform(kEndTransform);
   }
 
   AnimateMiniViews(mini_views_left, mini_views_left_begin_transform);
@@ -382,7 +380,7 @@
   // Animate movement.
   ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
   InitScopedAnimationSettings(&settings, kExistingMiniViewsAnimationDuration);
-  layer->SetTransform(GetEndTransform());
+  layer->SetTransform(kEndTransform);
 }
 
 void PerformDesksTemplatesButtonVisibilityAnimation(
diff --git a/ash/wm/desks/templates/saved_desk_grid_view.cc b/ash/wm/desks/templates/saved_desk_grid_view.cc
index 3b58dfb..acc144f 100644
--- a/ash/wm/desks/templates/saved_desk_grid_view.cc
+++ b/ash/wm/desks/templates/saved_desk_grid_view.cc
@@ -49,9 +49,7 @@
 // when the grid was first shown.
 constexpr std::size_t kMaxTemplateCount = 6u;
 
-gfx::Transform GetEndTransform() {
-  return gfx::Transform();
-}
+constexpr gfx::Transform kEndTransform;
 
 // Scale for adding/deleting grid items.
 constexpr float kAddOrDeleteItemScale = 0.75f;
@@ -319,7 +317,7 @@
           .Once()
           .Offset(kBoundsChangeAnimationDuration -
                   kTemplateViewsScaleAndFadeDuration)
-          .SetTransform(layer, GetEndTransform())
+          .SetTransform(layer, kEndTransform)
           .SetOpacity(layer, 1.f)
           .SetDuration(kTemplateViewsScaleAndFadeDuration);
       continue;
diff --git a/ash/wm/float/float_controller.cc b/ash/wm/float/float_controller.cc
index fd06ed1..c53efe4 100644
--- a/ash/wm/float/float_controller.cc
+++ b/ash/wm/float/float_controller.cc
@@ -26,6 +26,7 @@
 #include "ash/wm/workspace/workspace_event_handler.h"
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/metrics/histogram_functions.h"
 #include "chromeos/ui/base/window_properties.h"
 #include "chromeos/ui/wm/constants.h"
 #include "chromeos/ui/wm/window_util.h"
@@ -192,7 +193,11 @@
     OnRootWindowAdded(root);
 }
 
-FloatController::~FloatController() = default;
+FloatController::~FloatController() {
+  // Record how many windows are floated per session.
+  base::UmaHistogramCounts100(kFloatWindowCountsPerSessionHistogramName,
+                              floated_window_counter_);
+}
 
 // static
 gfx::Rect FloatController::GetPreferredFloatWindowClamshellBounds(
@@ -638,6 +643,11 @@
   if (!desk->is_active())
     HideFloatedWindow(window);
 
+  // Update floated window counts.
+  // Note that if the same window gets floated 2 times in the same session, it's
+  // counted as 2 floated windows.
+  ++floated_window_counter_;
+
   if (!tablet_mode_observation_.IsObserving())
     tablet_mode_observation_.Observe(Shell::Get()->tablet_mode_controller());
   if (!desks_controller_observation_.IsObserving())
diff --git a/ash/wm/float/float_controller.h b/ash/wm/float/float_controller.h
index e749150..4cdcdcb2 100644
--- a/ash/wm/float/float_controller.h
+++ b/ash/wm/float/float_controller.h
@@ -49,6 +49,10 @@
     kBottomRight,
   };
 
+  // Public so it can be used by unit tests.
+  constexpr static char kFloatWindowCountsPerSessionHistogramName[] =
+      "Ash.Float.FloatWindowCountsPerSession";
+
   FloatController();
   FloatController(const FloatController&) = delete;
   FloatController& operator=(const FloatController&) = delete;
@@ -139,6 +143,7 @@
   friend class DefaultState;
   friend class TabletModeWindowState;
   friend class WindowFloatTest;
+  FRIEND_TEST_ALL_PREFIXES(WindowFloatTest, FloatWindowCountPerSession);
 
   // Calls `FloatImpl()` and additionally updates the magnetism if needed.
   void FloatForTablet(aura::Window* window,
@@ -175,6 +180,10 @@
   base::flat_map<aura::Window*, std::unique_ptr<WorkspaceEventHandler>>
       workspace_event_handlers_;
 
+  // Float window counter within a session, used for
+  // `kFloatWindowCountsPerSessionHistogramName`.
+  int floated_window_counter_ = 0;
+
   base::ScopedObservation<TabletModeController, TabletModeObserver>
       tablet_mode_observation_{this};
 
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc
index 8854e60..5d04b41e 100644
--- a/ash/wm/float/float_controller_unittest.cc
+++ b/ash/wm/float/float_controller_unittest.cc
@@ -644,6 +644,23 @@
   EXPECT_EQ(window.get(), overview_items[0]->GetWindow());
 }
 
+// Tests the float window counts.
+TEST_F(WindowFloatTest, FloatWindowCountPerSession) {
+  // Float a window, Tests that it counts properly.
+  std::unique_ptr<aura::Window> window = CreateFloatedWindow();
+
+  // Unfloat and float the window again, it should count 2.
+  PressAndReleaseKey(ui::VKEY_F, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
+  ASSERT_FALSE(WindowState::Get(window.get())->IsFloated());
+  PressAndReleaseKey(ui::VKEY_F, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
+  ASSERT_TRUE(WindowState::Get(window.get())->IsFloated());
+  // Float a new window on a new desk, it should count 3.
+  NewDesk();
+  std::unique_ptr<aura::Window> window_2 = CreateFloatedWindow();
+  // Check total counts.
+  DCHECK_EQ(Shell::Get()->float_controller()->floated_window_counter_, 3);
+}
+
 class TabletWindowFloatTest : public WindowFloatTest {
  public:
   TabletWindowFloatTest() = default;
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 2d37aa60..9eb0a529 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -96,15 +96,13 @@
 constexpr float kBlackScrimFadeInRatio = 0.1f;
 constexpr float kBlackScrimOpacity = 0.4f;
 
-// If performant split view resizing is enabled, the speed at which the divider
-// is moved controls whether windows are scaled or translated. If the divider is
-// moved more than this many pixels per second, the "fast" mode is enabled.
-constexpr int kPerformantSplitViewThresholdPixelsPerSec = 72;
+// The speed at which the divider is moved controls whether windows are scaled
+// or translated. If the divider is moved more than this many pixels per second,
+// the "fast" mode is enabled.
+constexpr int kSplitViewThresholdPixelsPerSec = 72;
 
-// If performant split view resizing is enabled, this is how often the divider
-// drag speed is checked.
-constexpr base::TimeDelta kPerformantSplitViewChunkTime =
-    base::Milliseconds(500);
+// This is how often the divider drag speed is checked.
+constexpr base::TimeDelta kSplitViewChunkTime = base::Milliseconds(500);
 
 // Records the animation smoothness when the divider is released during a resize
 // and animated to a fixed position ratio.
@@ -1278,7 +1276,7 @@
   // normal mode if the user stops dragging. Note: if the timer is already
   // active, this will simply move the deadline forward.
   if (tablet_resize_mode_ == TabletResizeMode::kFast) {
-    resize_timer_.Start(FROM_HERE, kPerformantSplitViewChunkTime, this,
+    resize_timer_.Start(FROM_HERE, kSplitViewChunkTime, this,
                         &SplitViewController::OnResizeTimer);
   }
 
@@ -2176,9 +2174,6 @@
 }
 
 void SplitViewController::UpdateResizeBackdrop() {
-  if (!features::IsPerformantSplitViewResizingEnabled())
-    return;
-
   // Creates a backdrop layer. It is stacked below the snapped window.
   auto create_backdrop = [](aura::Window* window) {
     auto resize_backdrop_layer =
@@ -2728,9 +2723,6 @@
 void SplitViewController::UpdateTabletResizeMode(
     base::TimeTicks event_time_ticks,
     const gfx::Point& event_location) {
-  if (!features::IsPerformantSplitViewResizingEnabled())
-    return;
-
   if (IsLayoutHorizontal(root_window_)) {
     accumulated_drag_distance_ +=
         std::abs(event_location.x() - previous_event_location_.x());
@@ -2746,13 +2738,12 @@
   // the divider has been dragged. When the chunk gone on for long enough, we
   // calculate the drag speed based on `accumulated_drag_distance_` and update
   // the resize mode accordingly.
-  if (chunk_time_ticks >= kPerformantSplitViewChunkTime) {
+  if (chunk_time_ticks >= kSplitViewChunkTime) {
     int drag_per_second =
         accumulated_drag_distance_ / chunk_time_ticks.InSecondsF();
-    tablet_resize_mode_ =
-        drag_per_second > kPerformantSplitViewThresholdPixelsPerSec
-            ? TabletResizeMode::kFast
-            : TabletResizeMode::kNormal;
+    tablet_resize_mode_ = drag_per_second > kSplitViewThresholdPixelsPerSec
+                              ? TabletResizeMode::kFast
+                              : TabletResizeMode::kNormal;
 
     accumulated_drag_time_ticks_ = event_time_ticks;
     accumulated_drag_distance_ = 0;
diff --git a/base/BUILD.gn b/base/BUILD.gn
index d5745e8..440798b9 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -4246,6 +4246,7 @@
       "android/java/src/org/chromium/base/Features.java",
       "android/java/src/org/chromium/base/FieldTrialList.java",
       "android/java/src/org/chromium/base/FileUtils.java",
+      "android/java/src/org/chromium/base/Flag.java",
       "android/java/src/org/chromium/base/ImportantFileWriterAndroid.java",
       "android/java/src/org/chromium/base/IntStringCallback.java",
       "android/java/src/org/chromium/base/IntentUtils.java",
@@ -4475,6 +4476,7 @@
       "test/android/javatests/src/org/chromium/base/test/LoadNative.java",
       "test/android/javatests/src/org/chromium/base/test/MockitoErrorHandler.java",
       "test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java",
+      "test/android/javatests/src/org/chromium/base/test/ResetCachedFlagValuesTestHook.java",
       "test/android/javatests/src/org/chromium/base/test/ScreenshotOnFailureStatement.java",
       "test/android/javatests/src/org/chromium/base/test/SetUpStatement.java",
       "test/android/javatests/src/org/chromium/base/test/SetUpTestRule.java",
@@ -4791,6 +4793,11 @@
   deps = [ "//base" ]
 }
 
+fuzzer_test("sys_string_conversions_fuzzer") {
+  sources = [ "strings/sys_string_conversions_fuzzer.cc" ]
+  deps = [ "//base" ]
+}
+
 fuzzer_test("time_delta_from_string_fuzzer") {
   sources = [ "time/time_delta_from_string_fuzzer.cc" ]
   deps = [ "//base" ]
diff --git a/base/android/java/src/org/chromium/base/ApkAssets.java b/base/android/java/src/org/chromium/base/ApkAssets.java
index 4eaf5dd..407438a8 100644
--- a/base/android/java/src/org/chromium/base/ApkAssets.java
+++ b/base/android/java/src/org/chromium/base/ApkAssets.java
@@ -29,8 +29,7 @@
         AssetFileDescriptor afd = null;
         try {
             Context context = ContextUtils.getApplicationContext();
-            if (!TextUtils.isEmpty(splitName)
-                    && BundleUtils.isIsolatedSplitInstalled(context, splitName)) {
+            if (!TextUtils.isEmpty(splitName) && BundleUtils.isIsolatedSplitInstalled(splitName)) {
                 context = BundleUtils.createIsolatedSplitContext(context, splitName);
             }
             AssetManager manager = context.getAssets();
diff --git a/base/android/java/src/org/chromium/base/BundleUtils.java b/base/android/java/src/org/chromium/base/BundleUtils.java
index 75ef2bb8..9d63972 100644
--- a/base/android/java/src/org/chromium/base/BundleUtils.java
+++ b/base/android/java/src/org/chromium/base/BundleUtils.java
@@ -133,7 +133,7 @@
     }
 
     @RequiresApi(api = Build.VERSION_CODES.O)
-    private static String getSplitApkPath(Context context, String splitName) {
+    private static String getSplitApkPath(String splitName) {
         ApplicationInfo appInfo;
         synchronized (sSplitLock) {
             appInfo = sAppInfo;
@@ -142,7 +142,7 @@
                 // the application Context. When modules are installed on-the-fly,
                 // setInstalledSplits() is used to set them from the potentially more up-to-date
                 // PackageManager results.
-                appInfo = context.getApplicationInfo();
+                appInfo = ContextUtils.getApplicationContext().getApplicationInfo();
                 sAppInfo = appInfo;
             }
         }
@@ -158,11 +158,16 @@
      * Returns whether splitName is installed. Note, this will return false on Android versions
      * below O, where isolated splits are not supported.
      */
-    public static boolean isIsolatedSplitInstalled(Context context, String splitName) {
+    public static boolean isIsolatedSplitInstalled(String splitName) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
             return false;
         }
-        return getSplitApkPath(context, splitName) != null;
+        return getSplitApkPath(splitName) != null;
+    }
+
+    // TODO(agrieve): Delete downstream references.
+    public static boolean isIsolatedSplitInstalled(Context unused, String splitName) {
+        return isIsolatedSplitInstalled(splitName);
     }
 
     /**
@@ -213,7 +218,7 @@
                     && !parent.equals(appContext.getClassLoader());
             synchronized (sCachedClassLoaders) {
                 if (shouldReplaceClassLoader && !sCachedClassLoaders.containsKey(splitName)) {
-                    String apkPath = getSplitApkPath(base, splitName);
+                    String apkPath = getSplitApkPath(splitName);
                     // The librarySearchPath argument to PathClassLoader is not needed here
                     // because the framework doesn't pass it either, see b/171269960.
                     sCachedClassLoaders.put(
@@ -328,7 +333,7 @@
      * layouts which reference classes from a split.
      */
     public static Context createContextForInflation(Context context, String splitName) {
-        if (!BundleUtils.isIsolatedSplitInstalled(context, splitName)) {
+        if (!isIsolatedSplitInstalled(splitName)) {
             return context;
         }
         ClassLoader splitClassLoader = registerSplitClassLoaderForInflation(splitName);
@@ -352,10 +357,9 @@
     public static ClassLoader registerSplitClassLoaderForInflation(String splitName) {
         ClassLoader splitClassLoader = sInflationClassLoaders.get(splitName);
         if (splitClassLoader == null) {
-            splitClassLoader = BundleUtils
-                                       .createIsolatedSplitContext(
-                                               ContextUtils.getApplicationContext(), splitName)
-                                       .getClassLoader();
+            splitClassLoader =
+                    createIsolatedSplitContext(ContextUtils.getApplicationContext(), splitName)
+                            .getClassLoader();
             sInflationClassLoaders.put(splitName, splitClassLoader);
         }
         return splitClassLoader;
@@ -453,7 +457,7 @@
             return null;
         }
 
-        String apkPath = getSplitApkPath(ContextUtils.getApplicationContext(), splitName);
+        String apkPath = getSplitApkPath(splitName);
         if (apkPath == null) {
             return null;
         }
diff --git a/base/android/java/src/org/chromium/base/Flag.java b/base/android/java/src/org/chromium/base/Flag.java
new file mode 100644
index 0000000..ac495f1
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/Flag.java
@@ -0,0 +1,60 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import java.util.HashMap;
+
+import javax.annotation.concurrent.NotThreadSafe;
+
+/**
+ * Defines a feature flag for use in Java.
+ *
+ * Duplicate flag definitions are not permitted, so only a single
+ * instance can be created with a given feature name.
+ *
+ * To create a flag, instantiate a concrete subclass, i.e. CachedFlag, MutableFlagWithSafeDefault or
+ * PostNativeFlag.
+ *
+ * This class and its subclasses are not thread safe.
+ */
+@NotThreadSafe
+public abstract class Flag {
+    private static HashMap<String, Flag> sFlagsCreated = new HashMap<>();
+    protected final String mFeatureName;
+    protected Boolean mValue;
+
+    protected Flag(String featureName) {
+        assert !sFlagsCreated.containsKey(featureName);
+        mFeatureName = featureName;
+        sFlagsCreated.put(mFeatureName, this);
+    }
+
+    /**
+     * Checks if a feature flag is enabled.
+     * @return whether the feature should be considered enabled.
+     */
+    public abstract boolean isEnabled();
+
+    protected abstract void clearInMemoryCachedValueForTesting();
+
+    /**
+     * Resets the list of active flag instances. This shouldn't be used directly by individual
+     * tests other than those that exercise Flag subclasses.
+     */
+    public static void resetFlagsForTesting() {
+        resetAllInMemoryCachedValuesForTesting();
+        sFlagsCreated.clear();
+    }
+
+    /**
+     * Resets the in-memory cache of every Flag instance. This shouldn't be used directly by
+     * individual tests other than those that exercise Flag subclasses.
+     */
+    public static void resetAllInMemoryCachedValuesForTesting() {
+        for (Flag flag : sFlagsCreated.values()) {
+            flag.clearInMemoryCachedValueForTesting();
+        }
+    }
+}
diff --git a/base/android/java/src/org/chromium/base/JNIUtils.java b/base/android/java/src/org/chromium/base/JNIUtils.java
index 05b9d13..01943bf 100644
--- a/base/android/java/src/org/chromium/base/JNIUtils.java
+++ b/base/android/java/src/org/chromium/base/JNIUtils.java
@@ -35,9 +35,8 @@
     /** Returns a ClassLoader which can load Java classes from the specified split. */
     @CalledByNative
     public static ClassLoader getSplitClassLoader(String splitName) {
-        Context context = ContextUtils.getApplicationContext();
-        if (!TextUtils.isEmpty(splitName)
-                && BundleUtils.isIsolatedSplitInstalled(context, splitName)) {
+        if (!TextUtils.isEmpty(splitName) && BundleUtils.isIsolatedSplitInstalled(splitName)) {
+            Context context = ContextUtils.getApplicationContext();
             return BundleUtils.createIsolatedSplitContext(context, splitName).getClassLoader();
         }
         return getClassLoader();
diff --git a/base/android/java/src/org/chromium/base/compat/ApiHelperForO.java b/base/android/java/src/org/chromium/base/compat/ApiHelperForO.java
index bb16419d..9f6aa17 100644
--- a/base/android/java/src/org/chromium/base/compat/ApiHelperForO.java
+++ b/base/android/java/src/org/chromium/base/compat/ApiHelperForO.java
@@ -15,7 +15,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.net.ConnectivityManager;
@@ -71,11 +70,6 @@
         return clipDescription.getTimestamp();
     }
 
-    /** See {@link ApplicationInfo#splitNames}. */
-    public static String[] getSplitNames(ApplicationInfo info) {
-        return info.splitNames;
-    }
-
     /**
      * See {@link Context.createContextForSplit(String) }. Be careful about adding new uses of
      * this, most split Contexts should be created through {@link
diff --git a/base/check.cc b/base/check.cc
index d45930c..6d9c1d3 100644
--- a/base/check.cc
+++ b/base/check.cc
@@ -124,16 +124,6 @@
   return CheckError(log_message);
 }
 
-CheckError CheckError::CheckOp(const char* file,
-                               int line,
-                               CheckOpResult* check_op_result) {
-  auto* const log_message = new LogMessage(file, line, LOGGING_FATAL);
-  log_message->stream() << "Check failed: " << check_op_result->message_;
-  free(check_op_result->message_);
-  check_op_result->message_ = nullptr;
-  return CheckError(log_message);
-}
-
 CheckError CheckError::DCheck(const char* file,
                               int line,
                               const char* condition) {
@@ -142,16 +132,6 @@
   return CheckError(log_message);
 }
 
-CheckError CheckError::DCheckOp(const char* file,
-                                int line,
-                                CheckOpResult* check_op_result) {
-  auto* const log_message = new DCheckLogMessage(file, line, LOGGING_DCHECK);
-  log_message->stream() << "Check failed: " << check_op_result->message_;
-  free(check_op_result->message_);
-  check_op_result->message_ = nullptr;
-  return CheckError(log_message);
-}
-
 CheckError CheckError::PCheck(const char* file,
                               int line,
                               const char* condition) {
@@ -216,8 +196,6 @@
   delete log_message_;
 }
 
-CheckError::CheckError(LogMessage* log_message) : log_message_(log_message) {}
-
 void RawCheck(const char* message) {
   RawLog(LOGGING_FATAL, message);
 }
diff --git a/base/check.h b/base/check.h
index 7dfbd3b..19de039 100644
--- a/base/check.h
+++ b/base/check.h
@@ -57,17 +57,17 @@
        : ::logging::VoidifyStream(expr) & (*::logging::g_swallow_stream)
 BASE_EXPORT extern std::ostream* g_swallow_stream;
 
-class CheckOpResult;
 class LogMessage;
 
 // Class used for raising a check error upon destruction.
 class BASE_EXPORT CheckError {
  public:
+  // Used by CheckOp. Takes ownership of `log_message`.
+  explicit CheckError(LogMessage* log_message) : log_message_(log_message) {}
+
   static CheckError Check(const char* file, int line, const char* condition);
-  static CheckError CheckOp(const char* file, int line, CheckOpResult* result);
 
   static CheckError DCheck(const char* file, int line, const char* condition);
-  static CheckError DCheckOp(const char* file, int line, CheckOpResult* result);
 
   static CheckError PCheck(const char* file, int line, const char* condition);
   static CheckError PCheck(const char* file, int line);
@@ -94,8 +94,6 @@
   }
 
  private:
-  explicit CheckError(LogMessage* log_message);
-
   LogMessage* const log_message_;
 };
 
diff --git a/base/check_op.cc b/base/check_op.cc
index d84055b..5ed45ca 100644
--- a/base/check_op.cc
+++ b/base/check_op.cc
@@ -9,6 +9,8 @@
 #include <cstdio>
 #include <sstream>
 
+#include "base/logging.h"
+
 namespace logging {
 
 char* CheckOpValueStr(int v) {
@@ -74,12 +76,19 @@
   return strdup(ss.str().c_str());
 }
 
-CheckOpResult::CheckOpResult(const char* expr_str, char* v1_str, char* v2_str) {
-  std::ostringstream ss;
-  ss << expr_str << " (" << v1_str << " vs. " << v2_str << ")";
-  message_ = strdup(ss.str().c_str());
+LogMessage* CheckOpResult::CreateLogMessage(bool is_dcheck,
+                                            const char* file,
+                                            int line,
+                                            const char* expr_str,
+                                            char* v1_str,
+                                            char* v2_str) {
+  LogMessage* const log_message =
+      new LogMessage(file, line, is_dcheck ? LOGGING_DCHECK : LOGGING_FATAL);
+  log_message->stream() << "Check failed: " << expr_str << " (" << v1_str
+                        << " vs. " << v2_str << ")";
   free(v1_str);
   free(v2_str);
+  return log_message;
 }
 
 }  // namespace logging
diff --git a/base/check_op.h b/base/check_op.h
index 9b07a69..2119365 100644
--- a/base/check_op.h
+++ b/base/check_op.h
@@ -121,23 +121,32 @@
 }
 
 // Captures the result of a CHECK_op and facilitates testing as a boolean.
-class CheckOpResult {
+class BASE_EXPORT CheckOpResult {
  public:
   // An empty result signals success.
   constexpr CheckOpResult() {}
 
-  // A non-success result. expr_str is something like "foo != bar". v1_str and
-  // v2_str are the stringified run-time values of foo and bar. Takes ownership
-  // of v1_str and v2_str.
-  BASE_EXPORT CheckOpResult(const char* expr_str, char* v1_str, char* v2_str);
+  constexpr explicit CheckOpResult(LogMessage* log_message)
+      : log_message_(log_message) {}
 
   // Returns true if the check succeeded.
-  constexpr explicit operator bool() const { return !message_; }
+  constexpr explicit operator bool() const { return !log_message_; }
 
-  friend class CheckError;
+  LogMessage* log_message() { return log_message_; }
+
+  // TODO(pbos): Annotate this ABSL_ATTRIBUTE_RETURNS_NONNULL after solving
+  // compile failure.
+  // Takes ownership of `v1_str` and `v2_str`, destroying them with free(). For
+  // use with CheckOpValueStr() which allocates these strings using strdup().
+  static LogMessage* CreateLogMessage(bool is_dcheck,
+                                      const char* file,
+                                      int line,
+                                      const char* expr_str,
+                                      char* v1_str,
+                                      char* v2_str);
 
  private:
-  char* message_ = nullptr;
+  LogMessage* const log_message_ = nullptr;
 };
 
 // Helper macro for binary operators.
@@ -145,16 +154,17 @@
 // macro is used in an 'if' clause such as:
 // if (a == 1)
 //   CHECK_EQ(2, a);
-#define CHECK_OP_FUNCTION_IMPL(check_function, name, op, val1, val2) \
-  switch (0)                                                         \
-  case 0:                                                            \
-  default:                                                           \
-    if (::logging::CheckOpResult true_if_passed =                    \
-            ::logging::Check##name##Impl((val1), (val2),             \
-                                         #val1 " " #op " " #val2))   \
-      ;                                                              \
-    else                                                             \
-      check_function(__FILE__, __LINE__, &true_if_passed)
+#define CHECK_OP_FUNCTION_IMPL(is_dcheck, name, op, val1, val2)         \
+  switch (0)                                                            \
+  case 0:                                                               \
+  default:                                                              \
+    if (::logging::CheckOpResult true_if_passed =                       \
+            ::logging::Check##name##Impl(is_dcheck, __FILE__, __LINE__, \
+                                         (val1), (val2),                \
+                                         #val1 " " #op " " #val2))      \
+      ;                                                                 \
+    else                                                                \
+      ::logging::CheckError(true_if_passed.log_message())
 
 #if !CHECK_WILL_STREAM()
 
@@ -164,34 +174,38 @@
 #else
 
 #define CHECK_OP(name, op, val1, val2) \
-  CHECK_OP_FUNCTION_IMPL(::logging::CheckError::CheckOp, name, op, val1, val2)
+  CHECK_OP_FUNCTION_IMPL(/*is_dcheck=*/false, name, op, val1, val2)
 
 #endif
 
 // The second overload avoids address-taking of static members for
 // fundamental types.
-#define DEFINE_CHECK_OP_IMPL(name, op)                                         \
-  template <typename T, typename U,                                            \
-            std::enable_if_t<!std::is_fundamental<T>::value ||                 \
-                                 !std::is_fundamental<U>::value,               \
-                             int> = 0>                                         \
-  constexpr ::logging::CheckOpResult Check##name##Impl(                        \
-      const T& v1, const U& v2, const char* expr_str) {                        \
-    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                        \
-      return ::logging::CheckOpResult();                                       \
-    return ::logging::CheckOpResult(expr_str, CheckOpValueStr(v1),             \
-                                    CheckOpValueStr(v2));                      \
-  }                                                                            \
-  template <typename T, typename U,                                            \
-            std::enable_if_t<std::is_fundamental<T>::value &&                  \
-                                 std::is_fundamental<U>::value,                \
-                             int> = 0>                                         \
-  constexpr ::logging::CheckOpResult Check##name##Impl(T v1, U v2,             \
-                                                       const char* expr_str) { \
-    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                        \
-      return ::logging::CheckOpResult();                                       \
-    return ::logging::CheckOpResult(expr_str, CheckOpValueStr(v1),             \
-                                    CheckOpValueStr(v2));                      \
+#define DEFINE_CHECK_OP_IMPL(name, op)                                      \
+  template <typename T, typename U,                                         \
+            std::enable_if_t<!std::is_fundamental<T>::value ||              \
+                                 !std::is_fundamental<U>::value,            \
+                             int> = 0>                                      \
+  constexpr ::logging::CheckOpResult Check##name##Impl(                     \
+      bool is_dcheck, const char* file, int line, const T& v1, const U& v2, \
+      const char* expr_str) {                                               \
+    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                     \
+      return ::logging::CheckOpResult();                                    \
+    return CheckOpResult(CheckOpResult::CreateLogMessage(                   \
+        is_dcheck, file, line, expr_str, CheckOpValueStr(v1),               \
+        CheckOpValueStr(v2)));                                              \
+  }                                                                         \
+  template <typename T, typename U,                                         \
+            std::enable_if_t<std::is_fundamental<T>::value &&               \
+                                 std::is_fundamental<U>::value,             \
+                             int> = 0>                                      \
+  constexpr ::logging::CheckOpResult Check##name##Impl(                     \
+      bool is_dcheck, const char* file, int line, T v1, U v2,               \
+      const char* expr_str) {                                               \
+    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                     \
+      return ::logging::CheckOpResult();                                    \
+    return CheckOpResult(CheckOpResult::CreateLogMessage(                   \
+        is_dcheck, file, line, expr_str, CheckOpValueStr(v1),               \
+        CheckOpValueStr(v2)));                                              \
   }
 
 // clang-format off
@@ -213,7 +227,7 @@
 #if DCHECK_IS_ON()
 
 #define DCHECK_OP(name, op, val1, val2) \
-  CHECK_OP_FUNCTION_IMPL(::logging::CheckError::DCheckOp, name, op, val1, val2)
+  CHECK_OP_FUNCTION_IMPL(/*is_dcheck=*/true, name, op, val1, val2)
 
 #else
 
diff --git a/base/feature_list.cc b/base/feature_list.cc
index 980e165..db7fb60e 100644
--- a/base/feature_list.cc
+++ b/base/feature_list.cc
@@ -50,46 +50,55 @@
   // Invoked when `feature` is accessed before FeatureList registration.
   void AccessedFeature(const Feature& feature) {
     AutoLock lock(lock_);
-    if (feature_)
-      return;
-
-    feature_ = &feature;
-    stack_trace_ = std::make_unique<debug::StackTrace>();
+    if (fail_instantly_)
+      Fail(&feature);
+    else if (!feature_)
+      feature_ = &feature;
   }
 
   // Asserts that no feature was accessed before FeatureList registration.
   void AssertNoAccess() {
     AutoLock lock(lock_);
-    if (!feature_)
-      return;
+    if (feature_)
+      Fail(feature_);
+  }
 
-#if !BUILDFLAG(IS_NACL)
-    // Create a crash key with the name of the feature accessed too early, to
-    // facilitate crash triage.
-    SCOPED_CRASH_KEY_STRING256("FeatureList", "feature-accessed-too-early",
-                               feature_->name);
-#endif  // !BUILDFLAG(IS_NACL)
-    // Fail if DCHECKs are enabled.
-    DCHECK(!feature_) << "Accessed feature " << feature_->name
-                      << " before FeatureList registration, in stack: "
-                      << stack_trace_->ToString();
-    // Report the problem but don't crash if DCHECKs are disabled, to avoid
-    // making Chrome unusable if a feature is accessed too early.
-    //
-    // TODO(crbug.com/1383852): Uncomment this once all known problematic cases
-    // are fixed. We don't want to increase the crash reporting rate while we
-    // work on known problematic cases.
-    // base::debug::DumpWithoutCrashing();
+  // Makes calls to AccessedFeature() fail instantly.
+  void FailOnFeatureAccessWithoutFeatureList() {
+    AutoLock lock(lock_);
+    if (feature_)
+      Fail(feature_);
+    fail_instantly_ = true;
   }
 
   // Resets the state of this tracker.
   void Reset() {
     AutoLock lock(lock_);
     feature_ = nullptr;
-    stack_trace_.reset();
+    fail_instantly_ = false;
   }
 
  private:
+  void Fail(const Feature* feature) {
+    // TODO(crbug.com/1358639): Enable this check on all platforms.
+#if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
+#if !BUILDFLAG(IS_NACL)
+    // Create a crash key with the name of the feature accessed too early, to
+    // facilitate crash triage.
+    SCOPED_CRASH_KEY_STRING256("FeatureList", "feature-accessed-too-early",
+                               feature->name);
+#endif  // !BUILDFLAG(IS_NACL)
+    // Fail if DCHECKs are enabled.
+    DCHECK(!feature) << "Accessed feature " << feature->name
+                     << " before FeatureList registration.";
+    // TODO(crbug.com/1383852): When we believe that all early accesses have
+    // been fixed, add a base::debug::DumpWithoutCrashing(), to get reports from
+    // the field without making Chrome unusable. If we don't get reports, change
+    // the DCHECK above to a CHECK.
+#endif  // !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) &&
+        // !BUILDFLAG(IS_CHROMEOS)
+  }
+
   friend class NoDestructor<EarlyFeatureAccessTracker>;
 
   EarlyFeatureAccessTracker() = default;
@@ -100,8 +109,8 @@
   // First feature to be accessed before FeatureList registration.
   const Feature* feature_ GUARDED_BY(lock_) = nullptr;
 
-  // Stack trace of the first feature access before FeatureList registration.
-  std::unique_ptr<debug::StackTrace> stack_trace_ GUARDED_BY(lock_);
+  // Whether AccessedFeature() should fail instantly.
+  bool fail_instantly_ GUARDED_BY(lock_) = false;
 };
 
 // Controls whether a feature's override state will be cached in
@@ -116,10 +125,6 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 #if DCHECK_IS_ON()
-// Tracks whether the use of base::Feature is allowed for this module.
-// See ForbidUseForCurrentModule().
-bool g_use_allowed = true;
-
 const char* g_reason_overrides_disallowed = nullptr;
 
 void DCheckOverridesAllowed() {
@@ -441,9 +446,6 @@
 
 // static
 bool FeatureList::IsEnabled(const Feature& feature) {
-#if DCHECK_IS_ON()
-  CHECK(g_use_allowed) << "base::Feature not permitted for this module.";
-#endif
   if (!g_feature_list_instance) {
     EarlyFeatureAccessTracker::GetInstance()->AccessedFeature(feature);
     return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
@@ -458,9 +460,6 @@
 
 // static
 absl::optional<bool> FeatureList::GetStateIfOverridden(const Feature& feature) {
-#if DCHECK_IS_ON()
-  CHECK(g_use_allowed) << "base::Feature not permitted for this module.";
-#endif
   if (!g_feature_list_instance) {
     EarlyFeatureAccessTracker::GetInstance()->AccessedFeature(feature);
     // If there is no feature list, there can be no overrides.
@@ -471,10 +470,6 @@
 
 // static
 FieldTrial* FeatureList::GetFieldTrial(const Feature& feature) {
-#if DCHECK_IS_ON()
-  // See documentation for ForbidUseForCurrentModule.
-  CHECK(g_use_allowed) << "base::Feature not permitted for this module.";
-#endif
   if (!g_feature_list_instance) {
     EarlyFeatureAccessTracker::GetInstance()->AccessedFeature(feature);
     return nullptr;
@@ -581,10 +576,7 @@
   // Note: Intentional leak of global singleton.
   g_feature_list_instance = instance.release();
 
-  // TODO(crbug.com/1358639): Enable this check on all platforms.
-#if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
   EarlyFeatureAccessTracker::GetInstance()->AssertNoAccess();
-#endif
 
 #if !BUILDFLAG(IS_NACL)
   // Configured first because it takes precedence over the getrandom() trial.
@@ -635,12 +627,9 @@
 }
 
 // static
-void FeatureList::ForbidUseForCurrentModule() {
-#if DCHECK_IS_ON()
-  // Verify there hasn't been any use prior to being called.
-  EarlyFeatureAccessTracker::GetInstance()->AssertNoAccess();
-  g_use_allowed = false;
-#endif  // DCHECK_IS_ON()
+void FeatureList::FailOnFeatureAccessWithoutFeatureList() {
+  EarlyFeatureAccessTracker::GetInstance()
+      ->FailOnFeatureAccessWithoutFeatureList();
 }
 
 void FeatureList::SetCachingContextForTesting(uint16_t caching_context) {
diff --git a/base/feature_list.h b/base/feature_list.h
index e9388b4..b942f0b5 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -380,12 +380,16 @@
 
   // Returns whether the given `feature` is enabled.
   //
-  // If no `FeatureList` instance is registered, this returns the feature's
-  // default state. Registering a `FeatureList` later will fail.
+  // If no `FeatureList` instance is registered, this will:
+  // - DCHECK(), if FailOnFeatureAccessWithoutFeatureList() was called.
+  //     TODO(crbug.com/1358639): Change the DCHECK to a CHECK when we're
+  //     confident that all early accesses have been fixed. We don't want to
+  //     get many crash reports from the field in the meantime.
+  // - Return the default state, otherwise. Registering a `FeatureList` later
+  //   will fail.
   //
-  // TODO(crbug.com/1358639): Make registering a `FeatureList` later fail on
-  // iOS, Android and ChromeOS. This currently only works on Windows, Mac and
-  // Linux.
+  // TODO(crbug.com/1358639): Make early FeatureList access fail on iOS, Android
+  // and ChromeOS. This currently only works on Windows, Mac and Linux.
   //
   // A feature with a given name must only have a single corresponding Feature
   // instance, which is checked in builds with DCHECKs enabled.
@@ -465,11 +469,16 @@
   // to support base::test::ScopedFeatureList helper class.
   static void RestoreInstanceForTesting(std::unique_ptr<FeatureList> instance);
 
-  // On some platforms, the base::FeatureList singleton might be duplicated to
-  // more than one module. If this function is called, then using base::Feature
-  // API will result in DCHECK if accessed from the same module as the callee.
-  // Has no effect if DCHECKs are not enabled.
-  static void ForbidUseForCurrentModule();
+  // After calling this, an attempt to access feature state when no FeatureList
+  // is registered will DCHECK.
+  //
+  // TODO(crbug.com/1358639): Change the DCHECK to a CHECK when we're confident
+  // that all early accesses have been fixed. We don't want to get many crash
+  // reports from the field in the meantime.
+  //
+  // Note: This isn't the default behavior because accesses are tolerated in
+  // processes that never register a FeatureList.
+  static void FailOnFeatureAccessWithoutFeatureList();
 
   void SetCachingContextForTesting(uint16_t caching_context);
 
diff --git a/base/logging.cc b/base/logging.cc
index 5a432f0..ed86c4c 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -456,7 +456,7 @@
   // LOGGING_VERBOSE levels 3 and higher, or incorrect levels.
   return FUCHSIA_LOG_TRACE;
 }
-#endif  // defined (OS_FUCHSIA)
+#endif  // BUILDFLAG(IS_FUCHSIA)
 
 void WriteToFd(int fd, const char* data, size_t length) {
   size_t bytes_written = 0;
diff --git a/base/logging.h b/base/logging.h
index 0bb84fd..50579d3 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -520,7 +520,7 @@
   LAZY_STREAM(VLOG_STREAM(verbose_level), \
       VLOG_IS_ON(verbose_level) && (condition))
 
-#if defined (OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define VPLOG_STREAM(verbose_level) \
   ::logging::Win32ErrorLogMessage(__FILE__, __LINE__, -(verbose_level), \
     ::logging::GetLastSystemErrorCode()).stream()
diff --git a/base/strings/sys_string_conversions_fuzzer.cc b/base/strings/sys_string_conversions_fuzzer.cc
new file mode 100644
index 0000000..ebe1bea1
--- /dev/null
+++ b/base/strings/sys_string_conversions_fuzzer.cc
@@ -0,0 +1,36 @@
+// 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 <fuzzer/FuzzedDataProvider.h>
+#include <stdint.h>
+
+#include <string>
+#include <tuple>
+
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+
+namespace base {
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+  const std::string text = provider.ConsumeRandomLengthString();
+  const std::wstring wide_text = UTF8ToWide(text);
+
+  std::ignore = SysWideToUTF8(wide_text);
+  std::ignore = SysUTF8ToWide(text);
+  std::ignore = SysWideToNativeMB(wide_text);
+  std::ignore = SysNativeMBToWide(text);
+
+#if BUILDFLAG(IS_WIN)
+  const uint32_t code_page = provider.ConsumeIntegral<uint32_t>();
+  std::ignore = SysMultiByteToWide(text, code_page);
+  std::ignore = SysWideToMultiByte(wide_text, code_page);
+#endif
+
+  return 0;
+}
+
+}  // namespace base
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
index 98f9f58ee..47adda5 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
@@ -199,7 +199,8 @@
      */
     @CallSuper
     protected List<TestHook> getPreTestHooks() {
-        return Arrays.asList(CommandLineFlags.getPreTestHook(), new UnitTestNoBrowserProcessHook());
+        return Arrays.asList(CommandLineFlags.getPreTestHook(), new UnitTestNoBrowserProcessHook(),
+                new ResetCachedFlagValuesTestHook());
     }
 
     /**
diff --git a/base/test/android/javatests/src/org/chromium/base/test/ResetCachedFlagValuesTestHook.java b/base/test/android/javatests/src/org/chromium/base/test/ResetCachedFlagValuesTestHook.java
new file mode 100644
index 0000000..e2ae1369d
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/ResetCachedFlagValuesTestHook.java
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.test;
+
+import android.content.Context;
+
+import org.junit.runners.model.FrameworkMethod;
+
+import org.chromium.base.Flag;
+import org.chromium.base.test.BaseJUnit4ClassRunner.TestHook;
+
+/** Resets any cached values held by active {@link Flag} instances. */
+public class ResetCachedFlagValuesTestHook implements TestHook {
+    @Override
+    public void run(Context targetContext, FrameworkMethod testMethod) {
+        Flag.resetAllInMemoryCachedValuesForTesting();
+    }
+}
\ No newline at end of file
diff --git a/base/test/android/junit/src/org/chromium/base/test/BaseRobolectricTestRunner.java b/base/test/android/junit/src/org/chromium/base/test/BaseRobolectricTestRunner.java
index 8235d5e1..0d0b5b0 100644
--- a/base/test/android/junit/src/org/chromium/base/test/BaseRobolectricTestRunner.java
+++ b/base/test/android/junit/src/org/chromium/base/test/BaseRobolectricTestRunner.java
@@ -14,6 +14,7 @@
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.BundleUtils;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.Flag;
 import org.chromium.base.LifetimeAssert;
 import org.chromium.base.PathUtils;
 import org.chromium.base.library_loader.LibraryLoader;
@@ -46,6 +47,7 @@
             CommandLineFlags.setUpClass(method.getDeclaringClass());
             CommandLineFlags.setUpMethod(method);
             BundleUtils.resetForTesting();
+            Flag.resetAllInMemoryCachedValuesForTesting();
             super.beforeTest(method);
         }
 
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index d7c8821..3870b8133 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -1220,14 +1220,7 @@
 // static
 Time TimeOverride::now_time_;
 
-#if BUILDFLAG(IS_FUCHSIA)
-// TODO(https://crbug.com/1060357): Enable when RTC flake is fixed.
-#define MAYBE_NowOverride DISABLED_NowOverride
-#else
-#define MAYBE_NowOverride NowOverride
-#endif
-
-TEST_F(TimeTest, MAYBE_NowOverride) {
+TEST_F(TimeTest, NowOverride) {
   TimeOverride::now_time_ = Time::UnixEpoch();
 
   // Choose a reference time that we know to be in the past but close to now.
diff --git a/build/android/pylib/local/emulator/avd.py b/build/android/pylib/local/emulator/avd.py
index 0af1cc1..e4f99fe 100644
--- a/build/android/pylib/local/emulator/avd.py
+++ b/build/android/pylib/local/emulator/avd.py
@@ -770,13 +770,14 @@
             writable_system=False,
             gpu_mode=_DEFAULT_GPU_MODE,
             wipe_data=False,
-            debug_tags=None):
+            debug_tags=None,
+            require_fast_start=False):
     """Starts the emulator running an instance of the given AVD.
 
     Note when ensure_system_settings is True, the program will wait until the
     emulator is fully booted, and then update system settings.
     """
-    is_slow_start = False
+    is_slow_start = not require_fast_start
     # Force to load system snapshot if detected.
     if self.HasSystemSnapshot():
       if not writable_system:
@@ -879,7 +880,10 @@
     # turn-around on rolling AVD.
     if ensure_system_settings:
       assert self.device is not None, '`instance.device` not initialized.'
-      self.device.WaitUntilFullyBooted(timeout=120 if is_slow_start else 30)
+      logging.info('Waiting for device to be fully booted.')
+      self.device.WaitUntilFullyBooted(timeout=360 if is_slow_start else 90,
+                                       retries=0)
+      logging.info('Device fully booted, verifying system settings.')
       _EnsureSystemSettings(self.device)
 
   def Stop(self, force=False):
diff --git a/build/android/pylib/local/emulator/local_emulator_environment.py b/build/android/pylib/local/emulator/local_emulator_environment.py
index b57d78e2..730be3c 100644
--- a/build/android/pylib/local/emulator/local_emulator_environment.py
+++ b/build/android/pylib/local/emulator/local_emulator_environment.py
@@ -60,7 +60,8 @@
       def impl(inst):
         try:
           inst.Start(window=self._emulator_window,
-                     writable_system=self._writable_system)
+                     writable_system=self._writable_system,
+                     require_fast_start=True)
         except avd.AvdException:
           logging.exception('Failed to start emulator instance.')
           return None
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn
index f8d2e95c..efdd382 100644
--- a/build/config/android/BUILD.gn
+++ b/build/config/android/BUILD.gn
@@ -45,13 +45,6 @@
     # by shrinking the alignment gap between segments. This also causes all
     # segments to be mapped adjacently, which breakpad relies on.
     ldflags += [ "-Wl,-z,max-page-size=4096" ]
-
-    # Use non-standard (non-Itanium) ABI for Android64. This shrinks vtables
-    # in half and places them to .rodata, which greatly improves memory
-    # footprint. It should be safe, assuming all of C++ in Chromium is
-    # compiled with this flag.
-    cflags_cc = [ "-fexperimental-relative-c++-abi-vtables" ]
-    ldflags += [ "-fexperimental-relative-c++-abi-vtables" ]
   }
 
   if (current_cpu == "arm64") {
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index bd039fc..de425eb9 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -637,6 +637,11 @@
     cflags_cc += [ "-Wno-trigraphs" ]
   }
 
+  if (use_relative_vtables_abi) {
+    cflags_cc += [ "-fexperimental-relative-c++-abi-vtables" ]
+    ldflags += [ "-fexperimental-relative-c++-abi-vtables" ]
+  }
+
   # Add flags for link-time optimization. These flags enable
   # optimizations/transformations that require whole-program visibility at link
   # time, so they need to be applied to all translation units, and we may end up
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index e84f326..e0d44ee 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/c++/c++.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/chromecast_build.gni")
 import("//build/config/chromeos/args.gni")
@@ -29,16 +30,16 @@
 }
 
 declare_args() {
-  # Set to true to use the android unwinder V2 implementation.
-  use_android_unwinder_v2 = true
-}
-
-declare_args() {
   # Set to true to use lld, the LLVM linker.
   # In late bring-up on macOS (see docs/mac_lld.md).
   # Tentatively used on iOS.
   # The default linker everywhere else.
   use_lld = is_clang && current_os != "zos"
+
+  # If true, optimize for size.
+  # Default to favoring speed over size for platforms not listed below.
+  optimize_for_size =
+      !is_high_end_android && (is_android || is_ios || is_castos)
 }
 
 declare_args() {
@@ -133,15 +134,25 @@
   # https://chromium.googlesource.com/chromium/src/+/main/docs/design/sandbox.md#cet-shadow-stack
   enable_cet_shadow_stack = target_cpu == "x64"
 
-  # If true, optimize for size.
-  # Default to favoring speed over size for platforms not listed below.
-  optimize_for_size =
-      !is_high_end_android && (is_android || is_ios || is_castos)
-
   # Set to true to enable using the ML inliner in LLVM. This currently only
   # enables the ML inliner when targeting Android.
   # Currently the ML inliner is only supported on linux hosts
   use_ml_inliner = host_os == "linux" && is_android
+
+  # Set to true to use the android unwinder V2 implementation.
+  use_android_unwinder_v2 = true
+
+  # Whether we should consider the profile we're using to be accurate. Accurate
+  # profiles have the benefit of (potentially substantial) binary size
+  # reductions, by instructing the compiler to optimize cold and uncovered
+  # functions heavily for size. This often comes at the cost of performance.
+  sample_profile_is_accurate = optimize_for_size
+
+  # Use offsets rather than pointers in vtables in order to reduce the number of
+  # relocations. This is safe to enable only when all C++ code is built with the
+  # flag set to the same value.
+  use_relative_vtables_abi = is_android && current_cpu == "arm64" &&
+                             use_custom_libcxx && !is_component_build
 }
 
 assert(!is_cfi || use_thin_lto, "CFI requires ThinLTO")
@@ -153,14 +164,6 @@
         " (is_debug=true) build.")
 }
 
-declare_args() {
-  # Whether we should consider the profile we're using to be accurate. Accurate
-  # profiles have the benefit of (potentially substantial) binary size
-  # reductions, by instructing the compiler to optimize cold and uncovered
-  # functions heavily for size. This often comes at the cost of performance.
-  sample_profile_is_accurate = optimize_for_size
-}
-
 # Determine whether to enable or disable frame pointers, based on the platform
 # and build arguments.
 # TODO(crbug.com/1052397): Consider changing is_chromeos_ash to is_chromeos after
diff --git a/build/fuchsia/test/serve_repo.py b/build/fuchsia/test/serve_repo.py
index f7712b0..7270bb9 100755
--- a/build/fuchsia/test/serve_repo.py
+++ b/build/fuchsia/test/serve_repo.py
@@ -11,21 +11,10 @@
 from typing import Iterator, Optional
 
 from common import REPO_ALIAS, register_device_args, run_ffx_command
-from ffx_integration import get_config
 
 _REPO_NAME = 'chromium-test-package-server'
 
 
-def _ensure_ffx_config(key: str, value: str) -> bool:
-    """Ensures ffx config for a given key is value. Returns True if the config
-    was changed, False otherwise."""
-
-    if get_config(key) == value:
-        return False
-    run_ffx_command(['config', 'set', key, value])
-    return True
-
-
 def _stop_serving(repo_name: str, target: Optional[str]) -> None:
     """Stop serving a repository."""
 
@@ -47,12 +36,7 @@
         target: Fuchsia device the repository is served to.
     """
 
-    # Check ffx configs, restart daemon if the configuration was updated.
-    config_updated = False
-    config_updated |= _ensure_ffx_config('ffx_repository', 'true')
-    config_updated |= _ensure_ffx_config('repository.server.mode', '\"ffx\"')
-    if config_updated:
-        run_ffx_command(['doctor', '--restart-daemon'])
+    run_ffx_command(('config', 'set', 'repository.server.mode', '\"ffx\"'))
 
     run_ffx_command(['repository', 'server', 'start'])
     run_ffx_command(['repository', 'add-from-pm', repo_dir, '-r', repo_name])
diff --git a/build/fuchsia/test/serve_repo_unittests.py b/build/fuchsia/test/serve_repo_unittests.py
index dd61b22..de3fa62 100755
--- a/build/fuchsia/test/serve_repo_unittests.py
+++ b/build/fuchsia/test/serve_repo_unittests.py
@@ -26,33 +26,11 @@
                                              target_id=_TARGET)
 
     @mock.patch('serve_repo.run_ffx_command')
-    @mock.patch('serve_repo.get_config')
-    def test_ffx_config(self, mock_get_config, mock_ffx) -> None:
-        """Test |_ensure_ffx_config| returns True if config is changed,
-        False otherwise."""
-
-        mock_get_config.side_effect = ['true', '\"ffx\"']
-
-        serve_repo.run_serve_cmd('start', self._namespace)
-        self.assertEqual(mock_ffx.call_count, 3)
-
-        mock_ffx.reset_mock()
-        mock_get_config.reset_mock()
-        mock_get_config.side_effect = ['false', '\"not_ffx\"']
-
-        serve_repo.run_serve_cmd('start', self._namespace)
-        self.assertEqual(mock_ffx.call_count, 6)
-
-    @mock.patch('serve_repo.run_ffx_command')
-    @mock.patch('serve_repo._ensure_ffx_config', return_value=True)
-    def test_run_serve_cmd_start(self, mock_config, mock_ffx) -> None:
+    def test_run_serve_cmd_start(self, mock_ffx) -> None:
         """Test |run_serve_cmd| function for start."""
 
         serve_repo.run_serve_cmd('start', self._namespace)
-        self.assertEqual(mock_config.call_count, 2)
         self.assertEqual(mock_ffx.call_count, 4)
-        first_call = mock_ffx.call_args_list[0]
-        self.assertEqual(['doctor', '--restart-daemon'], first_call[0][0])
         second_call = mock_ffx.call_args_list[1]
         self.assertEqual(['repository', 'server', 'start'], second_call[0][0])
         third_call = mock_ffx.call_args_list[2]
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index ff047e6..cb945ea 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "81925935fdd2102dbe94aa6aadfa5203a6f11dba"
+  libcxx_revision = "cd0a05047451dfbdef5ba85f97ac4888e432a377"
 }
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index d73354c..9c42235e 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -72,6 +72,7 @@
 
 base::AtomicSequenceNumber g_next_layer_id;
 
+constexpr gfx::Transform Layer::kIdentityTransform;
 constexpr gfx::RoundedCornersF Layer::kNoRoundedCornersF;
 
 LayerDebugInfo::LayerDebugInfo() = default;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index ffa88e4..ee15ee0 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -410,7 +410,7 @@
   void SetTransform(const gfx::Transform& transform);
   const gfx::Transform& transform() const {
     return layer_tree_inputs() ? layer_tree_inputs()->transform
-                               : gfx::Transform::Identity();
+                               : kIdentityTransform;
   }
 
   // Gets the transform, including transform origin and position, of this layer
@@ -1175,6 +1175,7 @@
 
   ProtectedSequenceWritable<std::unique_ptr<LayerDebugInfo>> debug_info_;
 
+  static constexpr gfx::Transform kIdentityTransform{};
   static constexpr gfx::RoundedCornersF kNoRoundedCornersF{};
 };
 
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index bbe6057..0954291 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -591,6 +591,7 @@
       "//components/messages/android:factory_java",
       "//components/messages/android:java",
       "//components/messages/android:manager_java",
+      "//components/metrics:metrics_java",
       "//components/minidump_uploader:minidump_uploader_java",
       "//components/module_installer/android:module_installer_java",
       "//components/module_installer/android:module_interface_java",
diff --git a/chrome/android/DEPS b/chrome/android/DEPS
index b6a7224d..2d0f5ad 100644
--- a/chrome/android/DEPS
+++ b/chrome/android/DEPS
@@ -44,6 +44,7 @@
   "+components/javascript_dialogs/android",
   "+components/media_router/browser/android",
   "+components/messages/android",
+  "+components/metrics",
   "+components/page_info/android/java",
   "+components/permissions/android/nfc",
   "+components/policy",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 6a1a465..96b3195df 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -17,6 +17,8 @@
   "java/res/anim/stay_hidden.xml",
   "java/res/drawable-hdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-hdpi/bg_tabstrip_tab.9.png",
+  "java/res/drawable-hdpi/bg_tabstrip_tab_detached.9.png",
+  "java/res/drawable-hdpi/bg_tabstrip_tab_folio.9.png",
   "java/res/drawable-hdpi/bookmark_check_gray.png",
   "java/res/drawable-hdpi/bookmark_move_active.png",
   "java/res/drawable-hdpi/btn_bg_holo_active_normal.png",
@@ -86,6 +88,8 @@
   "java/res/drawable-ldrtl/google_pay_with_divider.xml",
   "java/res/drawable-mdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-mdpi/bg_tabstrip_tab.9.png",
+  "java/res/drawable-mdpi/bg_tabstrip_tab_detached.9.png",
+  "java/res/drawable-mdpi/bg_tabstrip_tab_folio.9.png",
   "java/res/drawable-mdpi/bookmark_check_gray.png",
   "java/res/drawable-mdpi/bookmark_move_active.png",
   "java/res/drawable-mdpi/btn_bg_holo_active_normal.png",
@@ -167,6 +171,8 @@
   "java/res/drawable-v31/tab_layout_background.xml",
   "java/res/drawable-xhdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-xhdpi/bg_tabstrip_tab.9.png",
+  "java/res/drawable-xhdpi/bg_tabstrip_tab_detached.9.png",
+  "java/res/drawable-xhdpi/bg_tabstrip_tab_folio.9.png",
   "java/res/drawable-xhdpi/bookmark_check_gray.png",
   "java/res/drawable-xhdpi/bookmark_move_active.png",
   "java/res/drawable-xhdpi/btn_bg_holo_active_normal.png",
@@ -233,6 +239,8 @@
   "java/res/drawable-xhdpi/verify_checkmark.png",
   "java/res/drawable-xxhdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-xxhdpi/bg_tabstrip_tab.9.png",
+  "java/res/drawable-xxhdpi/bg_tabstrip_tab_detached.9.png",
+  "java/res/drawable-xxhdpi/bg_tabstrip_tab_folio.9.png",
   "java/res/drawable-xxhdpi/bookmark_check_gray.png",
   "java/res/drawable-xxhdpi/bookmark_move_active.png",
   "java/res/drawable-xxhdpi/btn_close_white.png",
@@ -296,6 +304,8 @@
   "java/res/drawable-xxhdpi/verify_checkmark.png",
   "java/res/drawable-xxxhdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-xxxhdpi/bg_tabstrip_tab.9.png",
+  "java/res/drawable-xxxhdpi/bg_tabstrip_tab_detached.9.png",
+  "java/res/drawable-xxxhdpi/bg_tabstrip_tab_folio.9.png",
   "java/res/drawable-xxxhdpi/bookmark_check_gray.png",
   "java/res/drawable-xxxhdpi/bookmark_move_active.png",
   "java/res/drawable-xxxhdpi/btn_close_white.png",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index df75116..610a22d 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -76,6 +76,7 @@
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
+  "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTabTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabUsageTrackerTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TestTabModel.java",
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index 69e7c05..a59b3bf 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -618,6 +618,8 @@
     @Feature({"StartSurface"})
     @CommandLineFlags.Add({START_SURFACE_TEST_SINGLE_ENABLED_PARAMS})
     public void testShow_SingleAsHomepage_ResetScrollPosition() {
+        assumeTrue("https://crbug.com/1385547 - Disable for NoInstant.", mUseInstantStart);
+        
         if (!mImmediateReturn) {
             StartSurfaceTestUtils.pressHomePageButton(mActivityTestRule.getActivity());
         }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java
index c8c0509..e0ec536 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java
@@ -28,6 +28,9 @@
  */
 public class TabUiThemeProvider {
     private static final String TAG = "TabUiThemeProvider";
+
+    private static final float DETACHED_TAB_OVERLAY_ALPHA = 0.85f;
+
     /**
      * Returns the color to use for the tab grid card view background based on incognito mode.
      *
@@ -342,6 +345,32 @@
     }
 
     /**
+     * Returns the color for the detached tab container based on the incognito mode.
+     *
+     * @param context {@link Context} used to retrieve color.
+     * @param isIncognito Whether the color is used for incognito mode.
+     * @return The color for the detached tab container.
+     */
+    public static int getTabStripDetachedTabColor(Context context, boolean isIncognito) {
+        assert TabUiFeatureUtilities.isTabStripDetachedEnabled();
+
+        if (isIncognito) return Color.BLACK;
+
+        if (ColorUtils.inNightMode(context)) {
+            final int baseColor =
+                    MaterialColors.getColor(context, org.chromium.chrome.R.attr.colorPrimary, TAG);
+            final int overlayColor = ChromeColors.getSurfaceColor(
+                    context, org.chromium.chrome.R.dimen.default_elevation_0);
+
+            return ColorUtils.getColorWithOverlay(
+                    baseColor, overlayColor, DETACHED_TAB_OVERLAY_ALPHA);
+        } else {
+            return ChromeColors.getSurfaceColor(
+                    context, org.chromium.chrome.R.dimen.default_elevation_5);
+        }
+    }
+
+    /**
      * Returns the color used for tab grid dialog background based on the incognito mode.
      *
      * @param context {@link Context} used to retrieve color.
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index 31fc85de..3d9fa70 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -60,7 +60,6 @@
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.ui.base.ViewUtils;
 import org.chromium.ui.modelutil.MVCListAdapter;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyKey;
@@ -174,6 +173,11 @@
                 FeedSurfaceMediator.this.switchToStream(headerIndex);
             }
         }
+
+        @Override
+        public void refreshStream() {
+            mCoordinator.onRefresh();
+        }
     }
 
     @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
@@ -279,23 +283,31 @@
 
     @Override
     public void onOptionChanged() {
-        updateLayout(true, false);
+        updateLayout(false);
     }
 
-    private void updateLayout(boolean optionsSupported, boolean overrideSingleSpan) {
+    private void updateLayout(boolean isSmallLayoutWidth) {
         ListLayoutHelper listLayoutHelper =
                 mCoordinator.getHybridListRenderer().getListLayoutHelper();
         if (!FeedFeatures.isMultiColumnFeedEnabled(mContext) || listLayoutHelper == null) return;
-        int spanCount = overrideSingleSpan ? SPAN_COUNT_SMALL_WIDTH : SPAN_COUNT_LARGE_WIDTH;
-        if (!overrideSingleSpan && optionsSupported) {
+        int spanCount = shouldUseSingleSpan(isSmallLayoutWidth) ? SPAN_COUNT_SMALL_WIDTH
+                                                                : SPAN_COUNT_LARGE_WIDTH;
+        listLayoutHelper.setSpanCount(spanCount);
+    }
+
+    private boolean shouldUseSingleSpan(boolean isSmallLayoutWidth) {
+        boolean supportsOptions = mCurrentStream != null && mCurrentStream.supportsOptions();
+        boolean isFollowingFeedSortDisabled =
+                (!ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED_SORT)
+                        && mCurrentStream.getStreamKind() == StreamKind.FOLLOWING);
+        boolean isFeedSortedBySite = false;
+        if (supportsOptions) {
             @ContentOrder
             int selectedOption = mOptionsCoordinator.getSelectedOptionId();
-            // Override to single span count when showing following feed sort by site.
-            if (ContentOrder.GROUPED == selectedOption) {
-                spanCount = SPAN_COUNT_SMALL_WIDTH;
-            }
+            // Use single span count when showing following feed sorted by site.
+            isFeedSortedBySite = (ContentOrder.GROUPED == selectedOption);
         }
-        listLayoutHelper.setSpanCount(spanCount);
+        return isFollowingFeedSortDisabled || isSmallLayoutWidth || isFeedSortedBySite;
     }
 
     private void switchToStream(int headerIndex) {
@@ -314,7 +326,7 @@
                     .set(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY,
                             ViewVisibility.VISIBLE);
         }
-        updateLayout(newStream.supportsOptions(), false);
+        updateLayout(false);
         if (!mSettingUpStreams) {
             logSwitchedFeeds(newStream);
             bindStream(newStream, /*shouldScrollToTop=*/true);
@@ -349,14 +361,7 @@
                     int widthDp = (int) ((right - left) / pixelToDp);
                     int heightDp = (int) ((bottom - top) / pixelToDp);
                     mIsStickyHeaderEnabledInLayout = (widthDp >= 360 && heightDp >= 360);
-                    if (FeedFeatures.isMultiColumnFeedEnabled(mContext)) {
-                        boolean useSingleSpan =
-                                (right - left) <= ViewUtils.dpToPx(mContext, SMALL_WIDTH_DP);
-                        Stream stream = mTabToStreamMap.get(mSectionHeaderModel.get(
-                                SectionHeaderListProperties.CURRENT_TAB_INDEX_KEY));
-                        boolean supportsOptions = (stream != null) && stream.supportsOptions();
-                        updateLayout(supportsOptions, useSingleSpan);
-                    }
+                    updateLayout(widthDp < SMALL_WIDTH_DP);
                 });
     }
 
@@ -1157,7 +1162,7 @@
         return mSignInPromo;
     }
 
-    public void manualRefresh(Callback<Boolean> callback) {
+    void manualRefresh(Callback<Boolean> callback) {
         if (mCurrentStream != null) {
             mCurrentStream.triggerRefresh(callback);
         } else {
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_detached.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_detached.9.png
new file mode 100644
index 0000000..ca20a512
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_detached.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_folio.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_folio.9.png
new file mode 100644
index 0000000..f311341
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_tab_folio.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_detached.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_detached.9.png
new file mode 100644
index 0000000..6cf9b3a
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_detached.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_folio.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_folio.9.png
new file mode 100644
index 0000000..6c57c3e
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_tab_folio.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_detached.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_detached.9.png
new file mode 100644
index 0000000..3fba4fa
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_detached.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_folio.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_folio.9.png
new file mode 100644
index 0000000..520737b
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_tab_folio.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_detached.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_detached.9.png
new file mode 100644
index 0000000..06dc698
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_detached.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_folio.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_folio.9.png
new file mode 100644
index 0000000..799f3a5
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_tab_folio.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_detached.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_detached.9.png
new file mode 100644
index 0000000..ed4a742
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_detached.9.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_folio.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_folio.9.png
new file mode 100644
index 0000000..c82da99
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_tab_folio.9.png
Binary files differ
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/DexFixer.java b/chrome/android/java/src/org/chromium/chrome/browser/base/DexFixer.java
index 41181181..88989a0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/DexFixer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/DexFixer.java
@@ -19,7 +19,6 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.compat.ApiHelperForM;
-import org.chromium.base.compat.ApiHelperForO;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.build.BuildConfig;
@@ -152,7 +151,7 @@
             }
 
             // Check for corrupt dex.
-            String[] splitNames = ApiHelperForO.getSplitNames(appInfo);
+            String[] splitNames = appInfo.splitNames;
             if (splitNames != null) {
                 for (int i = 0; i < splitNames.length; i++) {
                     // Ignore config splits like "config.en".
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
index d4b0518..9150c76b5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
@@ -143,7 +143,6 @@
                 LocaleUtils.setDefaultLocalesFromConfiguration(config);
                 context = context.createConfigurationContext(config);
             }
-            performBrowserProcessPreloading(context);
         }
 
         super.attachBaseContext(context);
@@ -152,6 +151,10 @@
         maybeInitProcessType();
         BundleUtils.setIsBundle(ProductConfig.IS_BUNDLE);
 
+        if (isBrowserProcess) {
+            performBrowserProcessPreloading(context);
+        }
+
         // Write installed modules to crash keys. This needs to be done as early as possible so
         // that these values are set before any crashes are reported.
         ModuleUtil.updateCrashKeys();
@@ -294,7 +297,7 @@
 
     /** Creates a context which can be used to load code and resources in the chrome split. */
     public static Context createChromeContext(Context base) {
-        if (!BundleUtils.isIsolatedSplitInstalled(base, CHROME_SPLIT_NAME)) {
+        if (!BundleUtils.isIsolatedSplitInstalled(CHROME_SPLIT_NAME)) {
             return base;
         }
         return BundleUtils.createIsolatedSplitContext(base, CHROME_SPLIT_NAME);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatJobService.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatJobService.java
index 9aabaf3..ea058f9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatJobService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatJobService.java
@@ -31,7 +31,7 @@
     @Override
     protected void attachBaseContext(Context context) {
         // Make sure specified split is installed, otherwise fall back to chrome split.
-        if (mSplitName != null && BundleUtils.isIsolatedSplitInstalled(context, mSplitName)) {
+        if (mSplitName != null && BundleUtils.isIsolatedSplitInstalled(mSplitName)) {
             context = BundleUtils.createIsolatedSplitContext(context, mSplitName);
         } else {
             context = SplitCompatApplication.createChromeContext(context);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
index 9027c37..fa5a148 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
@@ -88,7 +88,7 @@
         }
 
         private Context createSplitContext() {
-            if (BundleUtils.isIsolatedSplitInstalled(mContext, mName)) {
+            if (BundleUtils.isIsolatedSplitInstalled(mName)) {
                 Context context = BundleUtils.createIsolatedSplitContext(mContext, mName);
                 if (GlobalAppLocaleController.getInstance().isOverridden()) {
                     Configuration config =
@@ -107,7 +107,7 @@
 
     /** Starts preloading a split context on a background thread. */
     public void preload(String name, OnComplete onComplete) {
-        if (!BundleUtils.isIsolatedSplitInstalled(mContext, name) && onComplete == null) {
+        if (!BundleUtils.isIsolatedSplitInstalled(name) && onComplete == null) {
             return;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index 1d3cc1d8..a27c047 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -1794,7 +1794,10 @@
             performHapticFeedback(tab);
         }
 
-        // 7. Request an update.
+        // 7. Lift the TSR folio container off the toolbar.
+        if (TabUiFeatureUtilities.isTabStripFolioEnabled()) mInteractingTab.setFolioAttached(false);
+
+        // 8. Request an update.
         mUpdateHost.requestUpdate();
     }
 
@@ -1819,7 +1822,10 @@
         // 4. Clear any tab group margins if they are enabled.
         if (TabUiFeatureUtilities.isTabletTabGroupsEnabled(mContext)) resetTabGroupMargins();
 
-        // 5. Request an update.
+        // 5. Reattach the TSR folio container to the toolbar.
+        if (TabUiFeatureUtilities.isTabStripFolioEnabled()) mInteractingTab.setFolioAttached(true);
+
+        // 6. Request an update.
         mUpdateHost.requestUpdate();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
index 21aa026..7b3c2f2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -31,6 +31,8 @@
 import org.chromium.chrome.browser.layouts.animation.CompositorAnimator;
 import org.chromium.chrome.browser.layouts.components.VirtualView;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
+import org.chromium.chrome.browser.tasks.tab_management.TabUiThemeProvider;
 import org.chromium.components.browser_ui.styles.ChromeColors;
 import org.chromium.components.browser_ui.styles.SemanticColorUtils;
 import org.chromium.ui.base.LocalizationUtils;
@@ -162,6 +164,10 @@
     // Animation/Timer Constants
     private static final int ANIM_TAB_CLOSE_BUTTON_FADE_MS = 150;
 
+    // Position Constants
+    private static final float DEFAULT_OFFSET_Y = 0.f;
+    private static final float FOLIO_DETACHED_OFFSET_Y = 4.f;
+
     // Close button width
     private static final int CLOSE_BUTTON_WIDTH_DP = 36;
     private static final int CLOSE_BUTTON_WIDTH_SCROLLING_STRIP_DP = 48;
@@ -182,6 +188,7 @@
     private boolean mVisible = true;
     private boolean mIsDying;
     private boolean mCanShowCloseButton = true;
+    private boolean mFolioAttached = true;
     private final boolean mIncognito;
     private float mContentOffsetX;
     private float mDividerOpacity;
@@ -309,6 +316,14 @@
     }
 
     /**
+     * Marks if tab container is attached to the toolbar for the Tab Strip Redesign folio treatment.
+     * @param folioAttached Whether the tab should be attached or not.
+     */
+    public void setFolioAttached(boolean folioAttached) {
+        mFolioAttached = folioAttached;
+    }
+
+    /**
      * @return The id of the {@link Tab} this {@link StripLayoutTab} represents.
      */
     public int getId() {
@@ -319,6 +334,12 @@
      * @return The Android resource that represents the tab background.
      */
     public int getResourceId() {
+        if (TabUiFeatureUtilities.isTabStripDetachedEnabled() || !mFolioAttached) {
+            return R.drawable.bg_tabstrip_tab_detached;
+        } else if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
+            return R.drawable.bg_tabstrip_tab_folio;
+        }
+
         return R.drawable.bg_tabstrip_tab;
     }
 
@@ -341,6 +362,17 @@
      * @return The tint color resource that represents the tab background.
      */
     public int getTint(boolean foreground) {
+        if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
+            // Inactive tabs have no container in TSR. Return arbitrary color to avoid calculation.
+            if (!foreground) return Color.TRANSPARENT;
+
+            if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
+                return ChromeColors.getDefaultThemeColor(mContext, mIncognito);
+            } else if (TabUiFeatureUtilities.isTabStripDetachedEnabled()) {
+                return TabUiThemeProvider.getTabStripDetachedTabColor(mContext, mIncognito);
+            }
+        }
+
         if (foreground) {
             return ChromeColors.getDefaultThemeColor(mContext, mIncognito);
         }
@@ -362,6 +394,11 @@
      * @return The tint color resource that represents the tab outline.
      */
     public int getOutlineTint(boolean foreground) {
+        if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
+            // Tabs have no outline in TSR. Return arbitrary color to avoid calculation.
+            return Color.TRANSPARENT;
+        }
+
         if (foreground) {
             return getTint(true);
         }
@@ -536,6 +573,17 @@
     }
 
     /**
+     * @return How far to offset the bottom of the tab container from the toolbar.
+     */
+    public float getBottomOffsetY() {
+        if (TabUiFeatureUtilities.isTabStripFolioEnabled() && !mFolioAttached) {
+            return FOLIO_DETACHED_OFFSET_Y;
+        }
+
+        return DEFAULT_OFFSET_Y;
+    }
+
+    /**
      * @param visiblePercentage How much of the tab is visible (not overlapped by other tabs).
      */
     public void setVisiblePercentage(float visiblePercentage) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
index 92f0c38..f6df795 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
@@ -17,6 +17,8 @@
     /** A list of resources to load synchronously once the compositor is initialized. */
     private static int[] sSynchronousResources = new int[] {
             R.drawable.bg_tabstrip_tab,
+            R.drawable.bg_tabstrip_tab_detached,
+            R.drawable.bg_tabstrip_tab_folio,
             R.drawable.btn_tab_close_normal,
             R.drawable.ic_new_tab_button,
             R.drawable.spinner,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
index 7dafa73..bb664cc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -193,10 +193,10 @@
                     isSelected, st.getClosePressed(), layoutHelper.getWidth() * mDpToPx,
                     st.getDrawX() * mDpToPx, st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx,
                     st.getHeight() * mDpToPx, st.getContentOffsetX() * mDpToPx,
-                    st.getDividerOffsetX() * mDpToPx, st.getCloseButton().getOpacity(),
-                    st.getDividerOpacity(), st.isLoading(), st.getLoadingSpinnerRotation(),
-                    st.getBrightness(), st.getOpacity(isSelected), layerTitleCache,
-                    resourceManager);
+                    st.getDividerOffsetX() * mDpToPx, st.getBottomOffsetY() * mDpToPx,
+                    st.getCloseButton().getOpacity(), st.getDividerOpacity(), st.isLoading(),
+                    st.getLoadingSpinnerRotation(), st.getBrightness(), st.getOpacity(isSelected),
+                    layerTitleCache, resourceManager);
         }
     }
 
@@ -235,9 +235,9 @@
                 int handleOutlineResourceId, int closeTint, int dividerTint, int handleTint,
                 int handleOutlineTint, boolean foreground, boolean closePressed, float toolbarWidth,
                 float x, float y, float width, float height, float contentOffsetX,
-                float dividerOffsetX, float closeButtonAlpha, float dividerAlpha, boolean isLoading,
-                float spinnerRotation, float brightness, float opacity,
-                LayerTitleCache layerTitleCache, ResourceManager resourceManager);
+                float dividerOffsetX, float bottomOffsetY, float closeButtonAlpha,
+                float dividerAlpha, boolean isLoading, float spinnerRotation, float brightness,
+                float opacity, LayerTitleCache layerTitleCache, ResourceManager resourceManager);
         void setContentTree(
                 long nativeTabStripSceneLayer, TabStripSceneLayer caller, SceneLayer contentTree);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java
index 1212592..0584622 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java
@@ -30,7 +30,8 @@
         }
 
         return new PartialCustomTabHeightStrategy(activity, initialHeight,
-                isPartialCustomTabFixedHeight, size -> connection.onResized(session, size),
+                isPartialCustomTabFixedHeight,
+                (height, width) -> connection.onResized(session, height, width),
                 lifecycleDispatcher, fullscreenManager, isTablet, interactWithBackground);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
index 02a5c30..b9a62482 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -233,6 +233,10 @@
 
     private volatile ChainedTasks mWarmupTasks;
 
+    // Caches the previous height reported via |onResized|. Used for extraCallback
+    // |ON_RESIZED_CALLLBACK| which cares about height only.
+    private int mPrevHeight;
+
     /**
      * <strong>DO NOT CALL</strong>
      * Public to be instanciable from {@link ChromeApplicationImpl}. This is however
@@ -1188,13 +1192,29 @@
     /**
      * Called when a resizable Custom Tab is resized.
      */
-    public void onResized(@Nullable CustomTabsSessionToken session, int size) {
+    public void onResized(@Nullable CustomTabsSessionToken session, int height, int width) {
         Bundle args = new Bundle();
-        args.putInt(ON_RESIZED_SIZE_EXTRA, size);
+        if (height != mPrevHeight) {
+            args.putInt(ON_RESIZED_SIZE_EXTRA, height);
 
-        if (safeExtraCallback(session, ON_RESIZED_CALLBACK, args) && mLogRequests) {
-            logCallback("extraCallback(" + ON_RESIZED_CALLBACK + ")", args);
+            // TODO(crbug.com/1366844): Deprecate the extra callback.
+            if (safeExtraCallback(session, ON_RESIZED_CALLBACK, args) && mLogRequests) {
+                logCallback("extraCallback(" + ON_RESIZED_CALLBACK + ")", args);
+            }
+            mPrevHeight = height;
         }
+
+        CustomTabsCallback callback = mClientManager.getCallbackForSession(session);
+        if (callback == null) return;
+        try {
+            callback.onActivityResized(height, width, args);
+        } catch (Exception e) {
+            // Catching all exceptions is really bad, but we need it here,
+            // because Android exposes us to client bugs by throwing a variety
+            // of exceptions. See crbug.com/517023.
+            return;
+        }
+        logCallback("onActivityResized()", "(" + height + "x" + width + ")");
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java
index f06dba0..10284dd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java
@@ -123,6 +123,7 @@
     private static boolean sHasLoggedImmersiveModeConfirmationSetting;
 
     private @Px int mDisplayHeight;
+    private @Px int mDisplayWidth;
     private @Px int mFullyExpandedAdjustmentHeight;
     private TabAnimator mTabAnimator;
     private int mShadowOffset;
@@ -185,11 +186,12 @@
     /** A callback to be called once the Custom Tab has been resized. */
     interface OnResizedCallback {
         /** The Custom Tab has been resized. */
-        void onResized(int size);
+        void onResized(int height, int width);
     }
 
-    // The current height used to trigger onResizedCallback when it is resized.
+    // The current height/width used to trigger onResizedCallback when it is resized.
     private int mHeight;
+    private int mWidth;
 
     // Class used to control show / hide nav bar.
     private NavBarTransitionController mNavbarTransitionController =
@@ -210,6 +212,7 @@
         mActivity = activity;
         mVersionCompat = PartialCustomTabVersionCompat.create(mActivity, this::updatePosition);
         mDisplayHeight = mVersionCompat.getDisplayHeight();
+        mDisplayWidth = mVersionCompat.getDisplayWidth();
         mUnclampedInitialHeight = initialHeight;
         mIsFixedHeight = isFixedHeight;
         mInteractWithBackground = interactWithBackground;
@@ -243,7 +246,8 @@
 
         fullscreenManager.addObserver(this);
         mIsTablet = isTablet;
-
+        mHeight = MATCH_PARENT;
+        mWidth = MATCH_PARENT;
         logImmersiveModeConfirmationSettingValue(ContextUtils.getApplicationContext());
     }
 
@@ -354,12 +358,14 @@
         boolean isInMultiWindow = MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity);
         int orientation = newConfig.orientation;
         int displayHeight = mVersionCompat.getDisplayHeight();
+        int displayWidth = mVersionCompat.getDisplayWidth();
 
         if (isInMultiWindow != mIsInMultiWindowMode || orientation != mOrientation
-                || displayHeight != mDisplayHeight) {
+                || displayHeight != mDisplayHeight || displayWidth != mDisplayWidth) {
             mIsInMultiWindowMode = isInMultiWindow;
             mOrientation = orientation;
             mDisplayHeight = displayHeight;
+            mDisplayWidth = displayWidth;
             if (isFullHeight()) {
                 // We should update CCT position before Window#FLAG_LAYOUT_NO_LIMITS is set,
                 // otherwise it is not possible to get the correct content height.
@@ -517,7 +523,6 @@
         // navigation area now just shows whatever is underneath: 1) loading view/web contents
         // while dragging 2) host app's navigation bar when at rest.
         positionAtHeight(height);
-        mHeight = attrs.height;
         if (!mInitFirstHeight) {
             setCoordinatorLayoutHeight(mDisplayHeight);
             mInitFirstHeight = true;
@@ -595,6 +600,12 @@
         return mIsFixedHeight;
     }
 
+    private boolean isFullscreen() {
+        WindowManager.LayoutParams attrs = mActivity.getWindow().getAttributes();
+        return attrs.x == 0 && attrs.y == 0 && attrs.width == MATCH_PARENT
+                && attrs.height == MATCH_PARENT;
+    }
+
     private boolean canInteractWithBackground() {
         return mInteractWithBackground;
     }
@@ -770,9 +781,16 @@
 
     private void maybeInvokeResizeCallback() {
         WindowManager.LayoutParams attrs = mActivity.getWindow().getAttributes();
-        if (mHeight != attrs.height && attrs.height > 0) {
-            mOnResizedCallback.onResized(attrs.height);
+        if (isFullHeight() || isFullscreen()) {
+            mOnResizedCallback.onResized(mDisplayHeight, mDisplayWidth);
+            mHeight = mDisplayHeight;
+            mWidth = mDisplayWidth;
+        } else {
+            if ((mHeight != attrs.height && mHeight > 0) || (mWidth != attrs.width && mWidth > 0)) {
+                mOnResizedCallback.onResized(attrs.height, attrs.width);
+            }
             mHeight = attrs.height;
+            mWidth = attrs.width;
         }
     }
 
@@ -902,6 +920,7 @@
 
     @Override
     public void onEnterFullscreen(Tab tab, FullscreenOptions options) {
+        if (isFullscreen()) return;
         WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
         attrs.copyFrom(mActivity.getWindow().getAttributes());
         attrs.x = 0;
@@ -910,12 +929,15 @@
         attrs.width = MATCH_PARENT;
         mActivity.getWindow().setAttributes(attrs);
         setTopMargins(0, 0);
+        maybeInvokeResizeCallback();
     }
 
     @Override
     public void onExitFullscreen(Tab tab) {
+        if (!isFullscreen()) return;
         setTopMargins(mShadowOffset, getHandleHeight() + mShadowOffset);
         initializeHeight();
+        maybeInvokeResizeCallback();
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabVersionCompat.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabVersionCompat.java
index bba8865..0dcf368e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabVersionCompat.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabVersionCompat.java
@@ -37,6 +37,9 @@
     /** Returns display height */
     abstract @Px int getDisplayHeight();
 
+    /** Returns display width */
+    abstract @Px int getDisplayWidth();
+
     /** Returns the status bar height */
     abstract @Px int getStatusbarHeight();
 
@@ -63,6 +66,12 @@
 
         @Override
         @Px
+        int getDisplayWidth() {
+            return mActivity.getWindowManager().getCurrentWindowMetrics().getBounds().width();
+        }
+
+        @Override
+        @Px
         int getStatusbarHeight() {
             return mActivity.getWindowManager()
                     .getCurrentWindowMetrics()
@@ -136,6 +145,18 @@
         }
 
         @Override
+        @Px
+        int getDisplayWidth() {
+            DisplayMetrics displayMetrics = new DisplayMetrics();
+            if (MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity)) {
+                mActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+            } else {
+                mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
+            }
+            return displayMetrics.widthPixels;
+        }
+
+        @Override
         @SuppressWarnings("DiscouragedApi")
         @Px
         int getStatusbarHeight() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index c64f668..5c8d7c2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -35,6 +35,7 @@
 import org.chromium.chrome.browser.signin.SigninFirstRunFragment;
 import org.chromium.chrome.browser.signin.services.FREMobileIdentityConsistencyFieldTrial;
 import org.chromium.components.browser_ui.modaldialog.AppModalPresenter;
+import org.chromium.components.metrics.LowEntropySource;
 import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType;
@@ -483,6 +484,9 @@
 
         FirstRunFlowSequencer.markFlowAsCompleted();
 
+        // LowEntropySource can't be used after the FRE has been completed.
+        LowEntropySource.markFirstRunComplete();
+
         if (sObserver != null) sObserver.onUpdateCachedEngineName(this);
 
         launchPendingIntentAndFinish();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index ac0c4cf..170e719 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -98,7 +98,7 @@
             SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(
                     Profile.getLastUsedRegularProfile());
             return FirstRunUtils.canAllowSync() && !signinManager.isSigninDisabledByPolicy()
-                    && signinManager.isSigninSupported(/*requireUpdatedPlayServices=*/false);
+                    && signinManager.isSigninSupported();
         }
 
         /** @return true if first use hints should be skipped. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
index 657e896..9dbcd24 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
@@ -11,6 +11,7 @@
 import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
 
 import android.app.Activity;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Message;
 import android.view.LayoutInflater;
@@ -18,6 +19,7 @@
 import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.Window;
 import android.view.WindowManager;
 
@@ -47,6 +49,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
 import org.chromium.chrome.browser.vr.VrModuleProvider;
+import org.chromium.components.browser_ui.util.DimensionCompat;
 import org.chromium.components.embedder_support.view.ContentView;
 import org.chromium.content_public.browser.GestureListenerManager;
 import org.chromium.content_public.browser.NavigationHandle;
@@ -142,6 +145,26 @@
     // in the current Tab.
     private ContentView mContentView;
 
+    private DimensionCompat mDimensionCompat;
+    private int mNavbarHeight;
+
+    // Monitors the window layout change while the fullscreen toast is on.
+    private OnGlobalLayoutListener mWindowLayoutListener = new OnGlobalLayoutListener() {
+        @Override
+        public void onGlobalLayout() {
+            if (mContentViewInFullscreen == null || mNotificationToast == null) return;
+            Rect bounds = new Rect();
+            mContentViewInFullscreen.getWindowVisibleDisplayFrame(bounds);
+            var lp = (ViewGroup.MarginLayoutParams) mNotificationToast.getLayoutParams();
+            int bottomMargin = mContentViewInFullscreen.getHeight() - bounds.bottom;
+            // If positioned at the bottom of the display, shift it up to avoid overlapping
+            // with the bottom nav bar when it appears by user gestures.
+            if (bottomMargin == 0) bottomMargin = mNavbarHeight;
+            lp.setMargins(0, 0, 0, bottomMargin);
+            mNotificationToast.requestLayout();
+        }
+    };
+
     // This static inner class holds a WeakReference to the outer object, to avoid triggering the
     // lint HandlerLeak warning.
     private static class FullscreenHandler extends Handler {
@@ -251,6 +274,7 @@
         mPersistentModeSupplier.set(false);
         mExitFullscreenOnStop = exitFullscreenOnStop;
         mFadeOutNotificationToastRunnable = this::fadeOutNotificationToast;
+        mDimensionCompat = DimensionCompat.create(mActivity, () -> {});
     }
 
     /**
@@ -528,7 +552,6 @@
             : "Cannot enter fullscreen with both status and navigation bars visible!";
 
         if (DEBUG_LOGS) Log.i(TAG, "enterFullscreen, options=" + options.toString());
-
         WebContents webContents = tab.getWebContents();
         if (webContents == null) return;
         mFullscreenOptions = options;
@@ -610,6 +633,12 @@
         mWebContentsInFullscreen = webContents;
         mContentViewInFullscreen = contentView;
         mTabInFullscreen = tab;
+
+        // Cache the navigation bar height before entering fullscreen mode in which the dimension
+        // is zero.
+        mNavbarHeight = mDimensionCompat.getNavbarHeight();
+        mActivity.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
+                mWindowLayoutListener);
     }
 
     /**
@@ -700,6 +729,10 @@
         assert mToastFadeAnimation != null;
         mToastFadeAnimation.cancel();
         mToastFadeAnimation = null;
+
+        mActivity.getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(
+                mWindowLayoutListener);
+
         // We can't actually remove it, so this will do.
         mNotificationToast.setVisibility(View.GONE);
         mNotificationToast = null;
@@ -904,11 +937,24 @@
         mTab = tab;
     }
 
+    ObserverList<FullscreenManager.Observer> getObserversForTesting() {
+        return mObservers;
+    }
+
     boolean isToastVisibleForTesting() {
         return mNotificationToast != null;
     }
 
-    ObserverList<FullscreenManager.Observer> getObserversForTesting() {
-        return mObservers;
+    int getToastBottomMarginForTesting() {
+        var lp = (ViewGroup.MarginLayoutParams) mNotificationToast.getLayoutParams();
+        return lp.bottomMargin;
+    }
+
+    void setVersionCompatForTesting(DimensionCompat compat) {
+        mDimensionCompat = compat;
+    }
+
+    void triggerWindowLayoutChangeForTesting() {
+        mWindowLayoutListener.onGlobalLayout();
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index 7af5f3b..a1f1cc2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -115,8 +115,7 @@
         final boolean isAccountsCachePopulated =
                 AccountManagerFacadeProvider.getInstance().getAccounts().isFulfilled();
         boolean canShowPersonalizedSigninPromo = mSigninManager.isSigninAllowed()
-                && mCanShowPersonalizedSuggestions && isAccountsCachePopulated
-                && mSigninManager.isSigninSupported(/*requireUpdatedPlayServices=*/true);
+                && mCanShowPersonalizedSuggestions && isAccountsCachePopulated;
         boolean canShowPersonalizedSyncPromo = mSigninManager.isSyncOptInAllowed()
                 && isUserSignedInButNotSyncing() && mCanShowPersonalizedSuggestions
                 && isAccountsCachePopulated;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
index e2027bb..c72bed9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -143,7 +143,7 @@
         super.onStart();
         SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(
                 Profile.getLastUsedRegularProfile());
-        if (signinManager.isSigninSupported(/*requireUpdatedPlayServices=*/false)) {
+        if (signinManager.isSigninSupported()) {
             signinManager.addSignInStateObserver(this);
         }
         SyncService syncService = SyncService.get();
@@ -157,7 +157,7 @@
         super.onStop();
         SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(
                 Profile.getLastUsedRegularProfile());
-        if (signinManager.isSigninSupported(/*requireUpdatedPlayServices=*/false)) {
+        if (signinManager.isSigninSupported()) {
             signinManager.removeSignInStateObserver(this);
         }
         SyncService syncService = SyncService.get();
@@ -246,7 +246,7 @@
     private void updatePreferences() {
         if (IdentityServicesProvider.get()
                         .getSigninManager(Profile.getLastUsedRegularProfile())
-                        .isSigninSupported(/*requireUpdatedPlayServices=*/false)) {
+                        .isSigninSupported()) {
             addPreferenceIfAbsent(PREF_SIGN_IN);
         } else {
             removePreferenceIfPresent(PREF_SIGN_IN);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
index 1836849..bd062822 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
@@ -168,7 +168,7 @@
     public boolean isSigninAllowed() {
         return mSignInState == null && mSigninAllowedByPolicy
                 && mIdentityManager.getPrimaryAccountInfo(ConsentLevel.SIGNIN) == null
-                && isSigninSupported(/*requireUpdatedPlayServices=*/false);
+                && isSigninSupported();
     }
 
     /**
@@ -178,7 +178,7 @@
     public boolean isSyncOptInAllowed() {
         return mSignInState == null && mSigninAllowedByPolicy
                 && mIdentityManager.getPrimaryAccountInfo(ConsentLevel.SYNC) == null
-                && isSigninSupported(/*requireUpdatedPlayServices=*/false);
+                && isSigninSupported();
     }
 
     /** Returns true if sign out can be started now. */
@@ -198,20 +198,12 @@
     }
 
     /**
-     * Returns whether the user can sign-in (maybe after an update to Google Play services).
-     * @param requireUpdatedPlayServices Indicates whether an updated version of play services is
-     *         required or not.
+     * @return Whether true if the current user is not demo user and the user has a reasonable
+     *         Google Play Services installed.
      */
     @Override
-    public boolean isSigninSupported(boolean requireUpdatedPlayServices) {
-        if (ApiCompatibilityUtils.isDemoUser()) {
-            return false;
-        }
-        if (requireUpdatedPlayServices) {
-            return ExternalAuthUtils.getInstance().canUseGooglePlayServices();
-        }
-        return !ExternalAuthUtils.getInstance().isGooglePlayServicesMissing(
-                ContextUtils.getApplicationContext());
+    public boolean isSigninSupported() {
+        return !ApiCompatibilityUtils.isDemoUser() && isGooglePlayServicesPresent();
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
index b30521f..f727570 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java
@@ -12,17 +12,12 @@
 
 import static org.hamcrest.core.AllOf.allOf;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import static org.chromium.components.browser_ui.widget.RecyclerViewTestUtils.activeInRecyclerView;
 
 import android.app.Activity;
-import android.content.Context;
 
 import androidx.test.filters.MediumTest;
 
@@ -34,6 +29,8 @@
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -79,11 +76,12 @@
     public final RuleChain chain =
             RuleChain.outerRule(mAccountManagerTestRule).around(mBookmarkTestRule);
 
-    private final SyncConsentActivityLauncher mMockSyncConsentActivityLauncher =
-            mock(SyncConsentActivityLauncher.class);
+    @Mock
+    private SyncConsentActivityLauncher mMockSyncConsentActivityLauncher;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         BookmarkPromoHeader.forcePromoStateForTests(SyncPromoState.PROMO_FOR_SIGNED_OUT_STATE);
         SyncConsentActivityLauncherImpl.setLauncherForTest(mMockSyncConsentActivityLauncher);
     }
@@ -103,9 +101,6 @@
                 mAccountManagerTestRule.addAccount(AccountManagerTestRule.TEST_ACCOUNT_EMAIL);
         HistogramDelta signinHistogram =
                 new HistogramDelta("Signin.SyncPromo.Continued.Count.Bookmarks", 1);
-        doNothing()
-                .when(SyncConsentActivityLauncherImpl.get())
-                .launchActivityForPromoDefaultFlow(any(Context.class), anyInt(), anyString());
         showBookmarkManagerAndCheckSigninPromoIsDisplayed();
 
         onView(allOf(withId(R.id.sync_promo_signin_button), activeInRecyclerView()))
@@ -122,9 +117,6 @@
     public void testSigninButtonNotDefaultAccount() {
         HistogramDelta signinHistogram =
                 new HistogramDelta("Signin.SyncPromo.Continued.Count.Bookmarks", 1);
-        doNothing()
-                .when(SyncConsentActivityLauncherImpl.get())
-                .launchActivityForPromoChooseAccountFlow(any(Context.class), anyInt(), anyString());
         CoreAccountInfo accountInfo =
                 mAccountManagerTestRule.addAccount(AccountManagerTestRule.TEST_ACCOUNT_EMAIL);
         showBookmarkManagerAndCheckSigninPromoIsDisplayed();
@@ -141,9 +133,6 @@
     public void testSigninButtonNewAccount() {
         HistogramDelta signinHistogram =
                 new HistogramDelta("Signin.SyncPromo.Continued.Count.Bookmarks", 1);
-        doNothing()
-                .when(SyncConsentActivityLauncherImpl.get())
-                .launchActivityForPromoAddAccountFlow(any(Context.class), anyInt());
         showBookmarkManagerAndCheckSigninPromoIsDisplayed();
         onView(allOf(withId(R.id.sync_promo_signin_button), activeInRecyclerView()))
                 .perform(click());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTabTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTabTest.java
new file mode 100644
index 0000000..2498c5a5
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTabTest.java
@@ -0,0 +1,221 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.compositor.overlays.strip;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.ContextThemeWrapper;
+
+import androidx.core.content.res.ResourcesCompat;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.google.android.material.color.MaterialColors;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.browser_ui.styles.ChromeColors;
+import org.chromium.ui.util.ColorUtils;
+
+/** Tests for {@link StripLayoutTab}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, qualifiers = "sw600dp")
+public class StripLayoutTabTest {
+    @Rule
+    public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
+
+    private static final String TAG = "StripLayoutTabTest";
+
+    private Context mContext;
+    private StripLayoutTab mNormalTab;
+    private StripLayoutTab mIncognitoTab;
+
+    @Before
+    public void setUp() {
+        mContext = new ContextThemeWrapper(
+                ApplicationProvider.getApplicationContext(), R.style.Theme_BrowserUI_DayNight);
+        mNormalTab = createStripLayoutTab(false);
+        mIncognitoTab = createStripLayoutTab(true);
+    }
+
+    @After
+    public void tearDown() {
+        TabUiFeatureUtilities.setTabStripRedesignEnableFolioForTesting(false);
+        TabUiFeatureUtilities.setTabStripRedesignEnableDetachedForTesting(false);
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    public void testGetTint() {
+        int expectedColor;
+
+        // Normal active tab color.
+        expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
+        assertEquals("Normal active tab should match the Surface-0 color.", expectedColor,
+                mNormalTab.getTint(true));
+
+        // Normal inactive tab color.
+        expectedColor =
+                ChromeColors.getSurfaceColor(mContext, R.dimen.compositor_background_tab_elevation);
+        assertEquals("Normal inactive tab should match the Surface-4 color.", expectedColor,
+                mNormalTab.getTint(false));
+
+        // Incognito active tab color.
+        expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
+        assertEquals("Incognito active tab should match the baseline color.", expectedColor,
+                mIncognitoTab.getTint(true));
+
+        // Incognito inactive tab color.
+        expectedColor = mContext.getResources().getColor(
+                R.color.baseline_neutral_900_with_neutral_1000_alpha_30);
+        assertEquals("Incognito inactive tab should match the baseline color.", expectedColor,
+                mIncognitoTab.getTint(false));
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    @Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
+    public void testGetTint_TabStripRedesignFolio() {
+        TabUiFeatureUtilities.setTabStripRedesignEnableFolioForTesting(true);
+        int expectedColor;
+
+        // Normal active tab color.
+        expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
+        assertEquals("Normal active folio should match the Surface-0 color.", expectedColor,
+                mNormalTab.getTint(true));
+
+        // Normal inactive tab color.
+        expectedColor = Color.TRANSPARENT;
+        assertEquals("Folio inactive tab containers should be transparent.", expectedColor,
+                mNormalTab.getTint(false));
+
+        // Incognito active tab color.
+        expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
+        assertEquals("Incognito active folio should match the baseline color.", expectedColor,
+                mIncognitoTab.getTint(true));
+
+        // Incognito inactive tab color.
+        expectedColor = Color.TRANSPARENT;
+        assertEquals("Folio inactive tab containers should be transparent.", expectedColor,
+                mIncognitoTab.getTint(false));
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    @Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
+    public void testGetTint_TabStripRedesignDetached() {
+        TabUiFeatureUtilities.setTabStripRedesignEnableDetachedForTesting(true);
+        int expectedColor;
+
+        // Normal active tab color.
+        expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
+        assertEquals("Detached normal active should match the Surface-5 color.", expectedColor,
+                mNormalTab.getTint(true));
+
+        // Normal inactive tab color.
+        expectedColor = Color.TRANSPARENT;
+        assertEquals("Detached inactive tab containers should be transparent.", expectedColor,
+                mNormalTab.getTint(false));
+
+        // Incognito active tab color.
+        expectedColor = Color.BLACK;
+        assertEquals("Detached incognito active should match the color black.", expectedColor,
+                mIncognitoTab.getTint(true));
+
+        // Incognito inactive tab color.
+        expectedColor = Color.TRANSPARENT;
+        assertEquals("Detached inactive tab containers should be transparent.", expectedColor,
+                mIncognitoTab.getTint(false));
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    public void testGetOutlineTint() {
+        int expectedColor;
+
+        // Normal active tab outline.
+        expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
+        assertEquals("Normal active tab outline should match the container color.", expectedColor,
+                mNormalTab.getOutlineTint(true));
+
+        // Normal inactive tab outline.
+        final int baseColor =
+                ChromeColors.getSurfaceColor(mContext, R.dimen.compositor_background_tab_elevation);
+        final int overlayColor = MaterialColors.getColor(mContext, R.attr.colorOutline, TAG);
+        final float overlayAlpha = ResourcesCompat.getFloat(
+                mContext.getResources(), R.dimen.compositor_background_tab_outline_alpha);
+        expectedColor = ColorUtils.getColorWithOverlay(baseColor, overlayColor, overlayAlpha);
+        assertEquals("Normal inactive tabs should have an overlain color.", expectedColor,
+                mNormalTab.getOutlineTint(false));
+
+        // Incognito active tab outline.
+        expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
+        assertEquals("Incognito active tab outline should match the container color.",
+                expectedColor, mIncognitoTab.getOutlineTint(true));
+
+        // Incognito inactive tab outline.
+        expectedColor = mContext.getResources().getColor(
+                R.color.baseline_neutral_900_with_neutral_1000_alpha_30_with_neutral_variant_400_alpha_15);
+        assertEquals("Inactive tab outline should match the baseline color.", expectedColor,
+                mIncognitoTab.getOutlineTint(false));
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    @Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
+    public void testGetOutlineTint_TabStripRedesignFolio() {
+        TabUiFeatureUtilities.setTabStripRedesignEnableFolioForTesting(true);
+        int expectedColor = Color.TRANSPARENT;
+
+        // Normal.
+        assertEquals("TSR Folio containers should not have an outline.", expectedColor,
+                mNormalTab.getOutlineTint(true));
+        assertEquals("TSR Folio containers should not have an outline.", expectedColor,
+                mNormalTab.getOutlineTint(false));
+
+        // Incognito.
+        assertEquals("TSR Folio containers should not have an outline.", expectedColor,
+                mIncognitoTab.getOutlineTint(true));
+        assertEquals("TSR Folio containers should not have an outline.", expectedColor,
+                mIncognitoTab.getOutlineTint(false));
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    @Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
+    public void testGetOutlineTint_TabStripRedesignDetached() {
+        TabUiFeatureUtilities.setTabStripRedesignEnableDetachedForTesting(true);
+        int expectedColor = Color.TRANSPARENT;
+
+        // Normal.
+        assertEquals("TSR Detached containers should not have an outline.", expectedColor,
+                mNormalTab.getOutlineTint(true));
+        assertEquals("TSR Detached containers should not have an outline.", expectedColor,
+                mNormalTab.getOutlineTint(false));
+
+        // Incognito.
+        assertEquals("TSR Detached containers should not have an outline.", expectedColor,
+                mIncognitoTab.getOutlineTint(true));
+        assertEquals("TSR Detached containers should not have an outline.", expectedColor,
+                mIncognitoTab.getOutlineTint(false));
+    }
+
+    private StripLayoutTab createStripLayoutTab(boolean incognito) {
+        return new StripLayoutTab(mContext, 0, null, null, null, null, incognito);
+    }
+}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java
index 91620519..57dfd2e 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java
@@ -105,7 +105,6 @@
     private static final int DEVICE_WIDTH = 1440;
 
     private static final int NAVBAR_HEIGHT = 160;
-    private static final int MAX_INIT_POS = DEVICE_HEIGHT / 2;
     private static final int INITIAL_HEIGHT = DEVICE_HEIGHT / 2 - NAVBAR_HEIGHT;
     private static final int FULL_HEIGHT = DEVICE_HEIGHT - NAVBAR_HEIGHT;
     private static final int MULTIWINDOW_HEIGHT = FULL_HEIGHT / 2;
@@ -217,6 +216,7 @@
         doAnswer(invocation -> {
             WindowManager.LayoutParams attributes = new WindowManager.LayoutParams();
             attributes.copyFrom((WindowManager.LayoutParams) invocation.getArgument(0));
+            mAttributes.copyFrom(attributes);
             mAttributeResults.add(attributes);
             return null;
         })
@@ -434,7 +434,7 @@
         mConfiguration.orientation = Configuration.ORIENTATION_PORTRAIT;
         mRealMetrics.widthPixels = DEVICE_WIDTH;
         mRealMetrics.heightPixels = DEVICE_HEIGHT;
-        when(mContentFrame.getHeight()).thenReturn(DEVICE_HEIGHT);
+        when(mContentFrame.getHeight()).thenReturn(DEVICE_HEIGHT - NAVBAR_HEIGHT);
         when(mDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
     }
 
@@ -773,6 +773,8 @@
         assertTabIsFullHeight(mAttributeResults.get(length - 1));
         assertEquals("ResizeType.AUTO_EXPANSION should be recorded once.", 1,
                 histogramExpansion.getDelta());
+        waitForAnimationToFinish();
+        verify(mOnResizedCallback).onResized(eq(FULL_HEIGHT), anyInt());
     }
 
     @Test
@@ -883,27 +885,41 @@
     }
 
     @Test
-    public void callbackWhenResized() {
+    public void callbackWhenHeightResized() {
         PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500);
         assertTabIsAtInitialPos(mAttributeResults.get(0));
         PartialCustomTabHandleStrategy handleStrategy = strategy.createHandleStrategyForTesting();
 
         // Slide back to the initial height -> no resize happens.
         assertTabIsAtInitialPos(dragTab(handleStrategy, 1500, 1450, 1400));
-        verify(mOnResizedCallback, never()).onResized(anyInt());
+        verify(mOnResizedCallback, never()).onResized(anyInt(), anyInt());
 
         // Drag to the top -> resized.
         assertTabIsFullHeight(dragTab(handleStrategy, 1500, 1000, 500));
-        verify(mOnResizedCallback).onResized(eq(FULL_HEIGHT));
+        verify(mOnResizedCallback).onResized(eq(FULL_HEIGHT), anyInt());
         clearInvocations(mOnResizedCallback);
 
         // Slide back to the top -> no resize happens.
         assertTabIsFullHeight(dragTab(handleStrategy, 50, 100, 150));
-        verify(mOnResizedCallback, never()).onResized(anyInt());
+        verify(mOnResizedCallback, never()).onResized(anyInt(), anyInt());
 
         // Drag to the initial height -> resized.
         assertTabIsAtInitialPos(dragTab(handleStrategy, 50, 650, 1300));
-        verify(mOnResizedCallback).onResized(eq(INITIAL_HEIGHT));
+        verify(mOnResizedCallback).onResized(eq(INITIAL_HEIGHT), anyInt());
+    }
+
+    @Test
+    public void callbackUponRotation() {
+        PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800);
+
+        configLandscapeMode();
+        strategy.onConfigurationChanged(mConfiguration);
+        verify(mOnResizedCallback).onResized(eq(DEVICE_WIDTH), eq(DEVICE_HEIGHT));
+        clearInvocations(mOnResizedCallback);
+
+        configPortraitMode();
+        strategy.onConfigurationChanged(mConfiguration);
+        verify(mOnResizedCallback).onResized(eq(INITIAL_HEIGHT), anyInt());
     }
 
     @Test
@@ -950,10 +966,13 @@
 
         strategy.onEnterFullscreen(null, null);
         assertTrue(isFullscreen());
+        verify(mOnResizedCallback).onResized(eq(DEVICE_HEIGHT), eq(DEVICE_WIDTH));
+        clearInvocations(mOnResizedCallback);
 
         strategy.onExitFullscreen(null);
         assertFalse(isFullscreen());
         assertEquals(height, getWindowAttributes().height);
+        verify(mOnResizedCallback).onResized(eq(height), anyInt());
     }
 
     @Test
@@ -1074,21 +1093,24 @@
         int expected = PartialCustomTabHeightStrategy.ResizeType.AUTO_EXPANSION;
         HistogramDelta histogramExpansion = new HistogramDelta("CustomTabs.ResizeType2", expected);
         strategy.onFindToolbarShown();
-        waitAnimationToFinish();
+        waitForAnimationToFinish();
 
         assertTabIsFullHeight(getWindowAttributes());
         assertEquals("ResizeType.AUTO_EXPANSION should be recorded once.", 1,
                 histogramExpansion.getDelta());
+        verify(mOnResizedCallback).onResized(eq(FULL_HEIGHT), anyInt());
+        clearInvocations(mOnResizedCallback);
 
         expected = PartialCustomTabHeightStrategy.ResizeType.AUTO_MINIMIZATION;
         HistogramDelta histogramMinimization =
                 new HistogramDelta("CustomTabs.ResizeType2", expected);
         strategy.onFindToolbarHidden();
-        waitAnimationToFinish();
+        waitForAnimationToFinish();
 
         assertTabIsAtInitialPos(getWindowAttributes());
         assertEquals("ResizeType.AUTO_MINIMIZATION should be recorded once.", 1,
                 histogramMinimization.getDelta());
+        verify(mOnResizedCallback).onResized(eq(INITIAL_HEIGHT), anyInt());
     }
 
     private boolean isFullscreen() {
@@ -1096,7 +1118,7 @@
         return attrs.isFullscreen();
     }
 
-    private static void waitAnimationToFinish() {
+    private static void waitForAnimationToFinish() {
         shadowOf(Looper.getMainLooper()).idle();
         ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
index 64e8b3a..e6e9d76 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
@@ -58,6 +58,7 @@
 import org.chromium.chrome.browser.xsurface.HybridListRenderer;
 import org.chromium.chrome.browser.xsurface.ListLayoutHelper;
 import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.components.feed.proto.wire.ReliabilityLoggingEnums.DiscoverLaunchResult;
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.search_engines.TemplateUrlService;
@@ -507,11 +508,16 @@
     @Config(qualifiers = "en-sw600dp")
     @Test
     public void testOnHeaderSelected_selectedWithLatestOptionsOnTablet() {
-        PropertyModel model = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
-        PropertyModel forYou = SectionHeaderProperties.createSectionHeader("For you");
-        OnSectionHeaderSelectedListener listener =
-                getOnSectionHeaderSelectedListener(model, forYou, true);
+        when(mFollowingStream.supportsOptions()).thenReturn(true);
         when(mOptionsCoordinator.getSelectedOptionId()).thenReturn(ContentOrder.REVERSE_CHRON);
+        when(mPrefService.getBoolean(Pref.ARTICLES_LIST_VISIBLE)).thenReturn(true);
+        when(mPrefService.getBoolean(Pref.ENABLE_SNIPPETS)).thenReturn(true);
+        PropertyModel sectionHeaderModel = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
+        mFeedSurfaceMediator =
+                createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, sectionHeaderModel);
+        mFeedSurfaceMediator.updateContent();
+        OnSectionHeaderSelectedListener listener =
+                mFeedSurfaceMediator.getOrCreateSectionHeaderListenerForTesting();
         listener.onSectionHeaderSelected(1);
 
         verify(mListLayoutHelper).setSpanCount(2);
@@ -520,11 +526,17 @@
     @Config(qualifiers = "en-sw600dp")
     @Test
     public void testOnHeaderSelected_selectedWithSortOptionsOnTablet() {
-        PropertyModel model = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
-        PropertyModel forYou = SectionHeaderProperties.createSectionHeader("For you");
-        OnSectionHeaderSelectedListener listener =
-                getOnSectionHeaderSelectedListener(model, forYou, true);
+        when(mFollowingStream.supportsOptions()).thenReturn(true);
         when(mOptionsCoordinator.getSelectedOptionId()).thenReturn(ContentOrder.GROUPED);
+        when(mPrefService.getBoolean(Pref.ARTICLES_LIST_VISIBLE)).thenReturn(true);
+        when(mPrefService.getBoolean(Pref.ENABLE_SNIPPETS)).thenReturn(true);
+        PropertyModel sectionHeaderModel = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
+        mFeedSurfaceMediator =
+                createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, sectionHeaderModel);
+        mFeedSurfaceMediator.updateContent();
+        OnSectionHeaderSelectedListener listener =
+                mFeedSurfaceMediator.getOrCreateSectionHeaderListenerForTesting();
+
         listener.onSectionHeaderSelected(1);
 
         verify(mListLayoutHelper).setSpanCount(1);
@@ -532,11 +544,36 @@
 
     @Config(qualifiers = "en-sw600dp")
     @Test
-    public void testOnOptionSelected() {
-        FeedSurfaceMediator mediator = createMediator();
+    public void testOnOptionSelectedOnTablet() {
+        when(mFollowingStream.supportsOptions()).thenReturn(true);
         when(mOptionsCoordinator.getSelectedOptionId()).thenReturn(ContentOrder.GROUPED);
+        when(mPrefService.getBoolean(Pref.ARTICLES_LIST_VISIBLE)).thenReturn(true);
+        when(mPrefService.getBoolean(Pref.ENABLE_SNIPPETS)).thenReturn(true);
+        PropertyModel sectionHeaderModel = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
+        mFeedSurfaceMediator =
+                createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, sectionHeaderModel);
+        mFeedSurfaceMediator.updateContent();
 
-        mediator.onOptionChanged();
+        mFeedSurfaceMediator.onOptionChanged();
+
+        verify(mListLayoutHelper).setSpanCount(1);
+    }
+
+    @Config(qualifiers = "en-sw600dp")
+    @DisableFeatures(ChromeFeatureList.WEB_FEED_SORT)
+    @Test
+    public void testOnHeaderSelected_withFollowingAndSortDisabledOnTablet() {
+        when(mPrefService.getBoolean(Pref.ARTICLES_LIST_VISIBLE)).thenReturn(true);
+        when(mPrefService.getBoolean(Pref.ENABLE_SNIPPETS)).thenReturn(true);
+        PropertyModel sectionHeaderModel = SectionHeaderListProperties.create(TOOLBAR_HEIGHT);
+        mFeedSurfaceMediator =
+                createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, sectionHeaderModel);
+        mFeedSurfaceMediator.updateContent();
+
+        OnSectionHeaderSelectedListener listener =
+                mFeedSurfaceMediator.getOrCreateSectionHeaderListenerForTesting();
+
+        listener.onSectionHeaderSelected(1);
 
         verify(mListLayoutHelper).setSpanCount(1);
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java
index 888d940..173b823 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java
@@ -4,12 +4,16 @@
 
 package org.chromium.chrome.browser.fullscreen;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
+import android.graphics.Rect;
 import android.view.View.OnLayoutChangeListener;
 
 import org.junit.Assert;
@@ -33,6 +37,7 @@
 import org.chromium.chrome.browser.tab.TabAttributes;
 import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper;
 import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.browser_ui.util.DimensionCompat;
 import org.chromium.components.embedder_support.view.ContentView;
 import org.chromium.content_public.browser.WebContents;
 
@@ -59,6 +64,8 @@
     private WebContents mWebContents;
     @Mock
     private ContentView mContentView;
+    @Mock
+    DimensionCompat mDimensionCompat;
 
     private FullscreenHtmlApiHandler mFullscreenHtmlApiHandler;
     private ObservableSupplierImpl<Boolean> mAreControlsHidden;
@@ -214,4 +221,47 @@
         assertTrue("Fullscreen toast should be visible in fullscreen",
                 mFullscreenHtmlApiHandler.isToastVisibleForTesting());
     }
+
+    @Test
+    public void testToastRepositionsUponWindowLayoutChange() {
+        doReturn(mWebContents).when(mTab).getWebContents();
+        doReturn(mContentView).when(mTab).getContentView();
+        doReturn(true).when(mTab).isUserInteractable();
+        doReturn(true).when(mTab).isHidden();
+        doReturn(true).when(mContentView).hasWindowFocus();
+        doReturn(SYSTEM_UI_HEIGHT).when(mDimensionCompat).getNavbarHeight();
+        final int contentHeight = DEVICE_HEIGHT - SYSTEM_UI_HEIGHT;
+        doReturn(contentHeight).when(mContentView).getHeight();
+        final Rect windowBounds = new Rect(0, 0, 800, contentHeight);
+        doAnswer(invocation -> {
+            Rect paramRect = invocation.getArgument(0);
+            paramRect.set(windowBounds);
+            return null;
+        })
+                .when(mContentView)
+                .getWindowVisibleDisplayFrame(any(Rect.class));
+        mAreControlsHidden.set(true);
+        mFullscreenHtmlApiHandler.setTabForTesting(mTab);
+        mFullscreenHtmlApiHandler.setVersionCompatForTesting(mDimensionCompat);
+
+        FullscreenOptions fullscreenOptions = new FullscreenOptions(false, false);
+        mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions);
+        var arg = ArgumentCaptor.forClass(OnLayoutChangeListener.class);
+        verify(mContentView).addOnLayoutChangeListener(arg.capture());
+        arg.getValue().onLayoutChange(mContentView, 0, 0, DEVICE_WIDTH, DEVICE_HEIGHT, 0, 0, 0, 0);
+        mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting();
+        assertEquals(SYSTEM_UI_HEIGHT, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting());
+
+        // Verify that the toast has a bigger margin that puts it up above the OSK.
+        final int oskHeight = 800;
+        final int windowHeightWithOsk = contentHeight - oskHeight;
+        windowBounds.bottom = windowHeightWithOsk;
+        mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting();
+        assertEquals(oskHeight, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting());
+
+        // Verify that the toast returns to the original position when the OSK is gone.
+        windowBounds.bottom = contentHeight;
+        mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting();
+        assertEquals(SYSTEM_UI_HEIGHT, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting());
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java
index f737637..4b565f10 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerImplTest.java
@@ -19,9 +19,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
-import android.os.UserManager;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -31,13 +28,11 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Answer;
 import org.robolectric.annotation.LooperMode;
-import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
@@ -132,7 +127,6 @@
         when(mNativeMock.isSigninAllowedByPolicy(NATIVE_SIGNIN_MANAGER)).thenReturn(true);
         // Pretend Google Play services are available as it is required for the sign-in
         when(mExternalAuthUtils.isGooglePlayServicesMissing(any())).thenReturn(false);
-        when(mExternalAuthUtils.canUseGooglePlayServices()).thenReturn(true);
         when(mProfile.isChild()).thenReturn(false);
         doAnswer(invocation -> {
             Runnable runnable = invocation.getArgument(0);
@@ -530,16 +524,4 @@
 
         assertFalse(mSigninManager.isSignOutAllowed());
     }
-
-    @Test
-    public void signInShouldBeSupportedForNonDemoUsers() {
-        // Make sure that the user is not a demo user.
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        UserManager userManager = Mockito.mock(UserManager.class);
-        Mockito.when(userManager.isDemoUser()).thenReturn(false);
-        shadowApplication.setSystemService(Context.USER_SERVICE, userManager);
-
-        assertTrue(mSigninManager.isSigninSupported(true));
-        assertTrue(mSigninManager.isSigninSupported(false));
-    }
 }
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 19921d07..72659899 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -303,10 +303,10 @@
       command_line->GetSwitchValueASCII(switches::kProcessType);
 
 #if !defined(COMPONENT_BUILD) && DCHECK_IS_ON()
-  // In non-component mode, chrome.exe contains a separate instance of
-  // base::FeatureList. Prevent accidental use of this here by forbidding use of
-  // the one that's linked with chrome.exe.
-  base::FeatureList::ForbidUseForCurrentModule();
+  // In non-component mode, chrome.exe contains its own base::FeatureList
+  // instance pointer, which remains nullptr. Attempts to access feature state
+  // from chrome.exe should fail, instead of silently returning a default state.
+  base::FeatureList::FailOnFeatureAccessWithoutFeatureList();
 
   // Patch the main EXE on non-component builds when DCHECKs are enabled.
   // This allows detection of third party code that might attempt to meddle with
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 68711c3..373bec8f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -8399,13 +8399,6 @@
      FEATURE_VALUE_TYPE(metrics::structured::kBluetoothSessionizedMetrics)},
 #endif
 
-    {"autofill-parse-merchant-promo-code-fields",
-     flag_descriptions::kAutofillParseMerchantPromoCodeFieldsName,
-     flag_descriptions::kAutofillParseMerchantPromoCodeFieldsDescription,
-     kOsAll,
-     FEATURE_VALUE_TYPE(
-         autofill::features::kAutofillParseMerchantPromoCodeFields)},
-
     {"autofill-highlight-only-changed-value-in-preview-mode",
      flag_descriptions::kAutofillHighlightOnlyChangedValuesInPreviewModeName,
      flag_descriptions::
@@ -8600,13 +8593,6 @@
      FEATURE_VALUE_TYPE(chromeos::wm::features::kPartialSplit)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    {"performant-split-view-resizing",
-     flag_descriptions::kPerformantSplitViewResizing,
-     flag_descriptions::kPerformantSplitViewResizingDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kPerformantSplitViewResizing)},
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
     {"privacy-guide-2", flag_descriptions::kPrivacyGuide2Name,
      flag_descriptions::kPrivacyGuide2Description, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kPrivacyGuide2)},
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
index 3808872..7dcd470f 100644
--- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
+++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -394,8 +394,19 @@
   auto* host = ash::GetWindowTreeHostForDisplay(
       display::Screen::GetScreen()->GetPrimaryDisplay().id());
   DCHECK(host);
-  // This skips rewriters.
-  host->DeliverEventToSink(synthetic_key_event.get());
+
+  bool dictation_enabled = AccessibilityManager::Get()->IsDictationEnabled();
+  bool from_accessibility_common =
+      extension_id() == extension_misc::kAccessibilityCommonExtensionId;
+  if (dictation_enabled && from_accessibility_common &&
+      params->use_rewriters.has_value() && params->use_rewriters.value()) {
+    // TODO(b/259397131): Remove the `useRewriters` property and remove this
+    // if statement.
+    host->SendEventToSink(synthetic_key_event.get());
+  } else {
+    host->DeliverEventToSink(synthetic_key_event.get());
+  }
+
   return RespondNow(WithArguments());
 }
 
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
index 97ccb98..da66404 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -40,6 +40,7 @@
     float height,
     float content_offset_x,
     float divider_offset_x,
+    float bottom_offset_y,
     float close_button_alpha,
     float divider_alpha,
     bool is_loading,
@@ -85,7 +86,7 @@
     y = y - (margin_height - height);
     height = margin_height;
   }
-  gfx::Size tab_bounds(width, height);
+  gfx::Size tab_bounds(width, height - bottom_offset_y);
 
   layer_->SetPosition(gfx::PointF(x, y));
   DecorationTitle* title_layer = nullptr;
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.h b/chrome/browser/android/compositor/layer/tab_handle_layer.h
index 7834223..bd6e9e8d 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.h
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.h
@@ -47,6 +47,7 @@
                      float height,
                      float content_offset_x,
                      float divider_offset_x,
+                     float bottom_offset_y,
                      float close_button_alpha,
                      float divider_alpha,
                      bool is_loading,
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
index a69628a..3581aa6 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -319,6 +319,7 @@
     jfloat height,
     jfloat content_offset_x,
     jfloat divider_offset_x,
+    jfloat bottom_offset_y,
     jfloat close_button_alpha,
     jfloat divider_alpha,
     jboolean is_loading,
@@ -343,11 +344,12 @@
                                                   close_tint);
   ui::Resource* divider_resource = resource_manager->GetStaticResourceWithTint(
       divider_resource_id, divider_tint);
-  layer->SetProperties(
-      id, close_button_resource, divider_resource, tab_handle_resource,
-      tab_handle_outline_resource, foreground, close_pressed, toolbar_width, x,
-      y, width, height, content_offset_x, divider_offset_x, close_button_alpha,
-      divider_alpha, is_loading, spinner_rotation, brightness, opacity);
+  layer->SetProperties(id, close_button_resource, divider_resource,
+                       tab_handle_resource, tab_handle_outline_resource,
+                       foreground, close_pressed, toolbar_width, x, y, width,
+                       height, content_offset_x, divider_offset_x,
+                       bottom_offset_y, close_button_alpha, divider_alpha,
+                       is_loading, spinner_rotation, brightness, opacity);
 }
 
 scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextLayer(
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
index 077e4b9d..ef96dce 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -129,6 +129,7 @@
       jfloat height,
       jfloat content_offset_x,
       jfloat divider_offset_x,
+      jfloat bottom_offset_y,
       jfloat close_button_alpha,
       jfloat divider_alpha,
       jboolean is_loading,
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
index 0be1e0d..5e58c0c1 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
+++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -154,6 +154,11 @@
         }
 
         @Override
+        public void onActivityResized(int height, int width, Bundle extras) {
+            Log.w(TAG, "onActivityResized: height = " + height + " width: " + width);
+        }
+
+        @Override
         public void extraCallback(@NonNull String callbackName, @Nullable Bundle args) {
             if (args == null) return;
 
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
index 6d96ec5..b431dbc3 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
@@ -9,6 +9,27 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
+#include "chrome/grit/component_extension_resources.h"
+
+namespace {
+
+int GetResourceIdForIcon(const std::string& app_id,
+                         int32_t size_in_dip,
+                         const apps::IconKey& icon_key) {
+  int resource_id = icon_key.resource_id;
+
+  if (app_id == arc::kPlayStoreAppId) {
+    int size_in_px = apps_util::ConvertDipToPx(
+        size_in_dip, /*quantize_to_supported_scale_factor=*/true);
+    resource_id = (size_in_px <= 32) ? IDR_ARC_SUPPORT_ICON_32_PNG
+                                     : IDR_ARC_SUPPORT_ICON_192_PNG;
+  }
+
+  return resource_id;
+}
+
+}  // namespace
 
 namespace apps {
 
@@ -18,9 +39,19 @@
 
 void AppIconReader::ReadIcons(const std::string& app_id,
                               int32_t size_in_dip,
-                              IconEffects icon_effects,
+                              const IconKey& icon_key,
                               IconType icon_type,
                               LoadIconCallback callback) {
+  IconEffects icon_effects = static_cast<IconEffects>(icon_key.icon_effects);
+  int resource_id = GetResourceIdForIcon(app_id, size_in_dip, icon_key);
+
+  if (icon_key.resource_id != IconKey::kInvalidResourceId) {
+    LoadIconFromResource(icon_type, size_in_dip, resource_id,
+                         /*is_placeholder_icon=*/false, icon_effects,
+                         std::move(callback));
+    return;
+  }
+
   const base::FilePath& base_path = profile_->GetPath();
 
   switch (icon_type) {
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
index 5642a652..70e7a742 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
@@ -34,7 +34,7 @@
   // `app_id`.
   void ReadIcons(const std::string& app_id,
                  int32_t size_in_dip,
-                 IconEffects icon_effects,
+                 const IconKey& icon_key,
                  IconType icon_type,
                  LoadIconCallback callback);
 
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.cc b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
index d4347d8..2a364aa 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
@@ -715,8 +715,7 @@
                                    IconType icon_type,
                                    LoadIconCallback callback) {
   icon_reader.ReadIcons(
-      app_id, size_hint_in_dip, static_cast<IconEffects>(icon_key.icon_effects),
-      icon_type,
+      app_id, size_hint_in_dip, icon_key, icon_type,
       base::BindOnce(&AppServiceProxyAsh::OnIconRead,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index 6fc2f07..801c5ecc 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -231,7 +231,8 @@
   }
 }
 
-void StandaloneBrowserApps::OnLoadComplete(bool success) {
+void StandaloneBrowserApps::OnLoadComplete(bool success,
+                                           const base::Version& version) {
   is_browser_load_success_ = success;
 
   apps::mojom::AppPtr mojom_app = apps::mojom::App::New();
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
index ae31fcb..ab0b473 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
@@ -91,7 +91,7 @@
   void StopApp(const std::string& app_id) override;
 
   // crosapi::BrowserManagerObserver
-  void OnLoadComplete(bool success) override;
+  void OnLoadComplete(bool success, const base::Version& version) override;
 
   mojo::RemoteSet<apps::mojom::Subscriber> subscribers_;
   Profile* const profile_;
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc
index b260998..7093f9b 100644
--- a/chrome/browser/ash/accessibility/dictation_browsertest.cc
+++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -1306,15 +1306,14 @@
 // and ensure that you can't run the Dictation
 // Commands under that feature flag.
 
-IN_PROC_BROWSER_TEST_P(DictationCommandsTest, DISABLED_NavStartTextSimple) {
+IN_PROC_BROWSER_TEST_P(DictationCommandsTest, NavStartTextSimple) {
   SendFinalResultAndWaitForEditableValue("Is good", "Is good");
   SendFinalResultAndWaitForCaretBoundsChanged("move to the start");
   SendFinalResultAndWaitForEditableValue("the weather outside",
                                          "the weather outside Is good");
 }
 
-IN_PROC_BROWSER_TEST_P(DictationCommandsTest,
-                       DISABLED_NavStartTextMultiLineString) {
+IN_PROC_BROWSER_TEST_P(DictationCommandsTest, NavStartTextMultiLineString) {
   if (!RunOnMultilineContent())
     return;
 
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
index 2828e93..0b4c203 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -261,6 +261,15 @@
     return nullptr;
   }
 
+  void ReadWindowTitle() {
+    extensions::browsertest_util::ExecuteScriptInBackgroundPageNoWait(
+        browser()->profile(), extension_misc::kChromeVoxExtensionId,
+        "import('/chromevox/background/"
+        "command_handler_interface.js').then(module => "
+        "module.CommandHandlerInterface.instance.onCommand('readCurrentTitle'))"
+        ";");
+  }
+
  private:
   const SpokenFeedbackAppListTestVariant variant_;
   std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
@@ -550,6 +559,9 @@
   sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_SPACE); });
   sm_.ExpectSpeechPattern("Search your *");
   sm_.ExpectSpeech("Edit text");
+  sm_.ExpectSpeech("Launcher, all apps");
+  sm_.Call([this]() { ReadWindowTitle(); });
+  sm_.ExpectSpeech("Launcher");
 
   sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_RIGHT); });
   sm_.ExpectSpeech("Button");
@@ -764,6 +776,8 @@
 
   sm_.ExpectSpeechPattern("Search your *");
   sm_.ExpectSpeech("Edit text");
+  sm_.Call([this]() { ReadWindowTitle(); });
+  sm_.ExpectSpeech("Launcher");
 
   sm_.Call([this]() {
     apps_provider_->set_best_match_count(2);
diff --git a/chrome/browser/ash/arc/policy/managed_configuration_variables.cc b/chrome/browser/ash/arc/policy/managed_configuration_variables.cc
index 576a996..539d5821 100644
--- a/chrome/browser/ash/arc/policy/managed_configuration_variables.cc
+++ b/chrome/browser/ash/arc/policy/managed_configuration_variables.cc
@@ -77,8 +77,9 @@
 }
 
 std::string DeviceSerialNumber() {
-  return chromeos::system::StatisticsProvider::GetInstance()
-      ->GetEnterpriseMachineID();
+  return std::string(chromeos::system::StatisticsProvider::GetInstance()
+                         ->GetMachineID()
+                         .value_or(""));
 }
 
 // Map associating known variables to functions that return the corresponding
diff --git a/chrome/browser/ash/crosapi/browser_loader.cc b/chrome/browser/ash/crosapi/browser_loader.cc
index e95e259..90a0b2c5 100644
--- a/chrome/browser/ash/crosapi/browser_loader.cc
+++ b/chrome/browser/ash/crosapi/browser_loader.cc
@@ -167,6 +167,28 @@
 
 BrowserLoader::~BrowserLoader() = default;
 
+// static.
+bool BrowserLoader::WillLoadStatefulComponentBuilds() {
+  // If the lacros chrome path is specified BrowserLoader will always attempt to
+  // load lacros from this path and component manager builds are ignored.
+  const base::FilePath lacros_chrome_path =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+          ash::switches::kLacrosChromePath);
+  if (!lacros_chrome_path.empty())
+    return false;
+
+  // If the user has set the lacros selection to rootfs this will always be
+  // loaded and component manager builds are ignored.
+  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
+  if (cmdline->HasSwitch(browser_util::kLacrosSelectionSwitch) &&
+      (cmdline->GetSwitchValueASCII(browser_util::kLacrosSelectionSwitch) ==
+       browser_util::kLacrosSelectionRootfs)) {
+    return false;
+  }
+
+  return true;
+}
+
 void BrowserLoader::Load(LoadCompletionCallback callback) {
   lacros_start_load_time_ = base::TimeTicks::Now();
   // TODO(crbug.com/1078607): Remove non-error logging from this class.
diff --git a/chrome/browser/ash/crosapi/browser_loader.h b/chrome/browser/ash/crosapi/browser_loader.h
index 0212e201..c117cc2 100644
--- a/chrome/browser/ash/crosapi/browser_loader.h
+++ b/chrome/browser/ash/crosapi/browser_loader.h
@@ -37,6 +37,14 @@
 
   virtual ~BrowserLoader();
 
+  // Returns true if the browser loader will try to load stateful lacros-chrome
+  // builds from the component manager. This may return false if the user
+  // specifies the lacros-chrome binary on the command line or the user has
+  // forced the lacros selection to rootfs.
+  // If this returns false subsequent loads of lacros-chrome will never load
+  // a newer lacros-chrome version and update checking can be skipped.
+  static bool WillLoadStatefulComponentBuilds();
+
   // Starts to load lacros-chrome binary or the rootfs lacros-chrome binary.
   // |callback| is called on completion with the path to the lacros-chrome on
   // success, or an empty filepath on failure, and the loaded lacros selection
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index e52cc30..54ba80ed 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -393,6 +393,75 @@
                                        version_info::GetVersion());
 }
 
+// The delegate keeps track of the most recent lacros-chrome binary version
+// loaded by the BrowserLoader.
+// It is the single source of truth for what is the most up-to-date launchable
+// version of lacros-chrome. It should be queried when determining if loading a
+// more recent lacros-chrome binary should be attempted.
+class BrowserVersionServiceDelegate : public BrowserVersionServiceAsh::Delegate,
+                                      public BrowserManagerObserver {
+ public:
+  BrowserVersionServiceDelegate(
+      const ComponentUpdateService* component_update_service,
+      BrowserManager* browser_manager)
+      : component_update_service_(component_update_service) {
+    observation_.Observe(browser_manager);
+  }
+  BrowserVersionServiceDelegate(const BrowserVersionServiceDelegate&) = delete;
+  BrowserVersionServiceDelegate& operator=(
+      const BrowserVersionServiceDelegate&) = delete;
+  ~BrowserVersionServiceDelegate() override = default;
+
+  // BrowserVersionServiceAsh::Delegate:
+  base::Version GetLatestLaunchableBrowserVersion() const override {
+    // If there is a newer browser available return the version of lacros-chrome
+    // maintained by the component manager. Otherwise return the current version
+    // loaded by the manager.
+    const auto component_version_number =
+        browser_util::GetInstalledLacrosComponentVersion(
+            component_update_service_);
+    return IsNewerBrowserAvailable() && component_version_number.IsValid()
+               ? component_version_number
+               : browser_version_loaded_;
+  }
+
+  bool IsNewerBrowserAvailable() const override {
+    // If the browser loader is not able to load newer stateful component builds
+    // signal there is no update available.
+    if (!BrowserLoader::WillLoadStatefulComponentBuilds())
+      return false;
+
+    const auto component_version_number =
+        browser_util::GetInstalledLacrosComponentVersion(
+            component_update_service_);
+    return (!browser_version_loaded_.IsValid() &&
+            component_version_number.IsValid()) ||
+           (browser_version_loaded_.IsValid() &&
+            component_version_number.IsValid() &&
+            browser_version_loaded_ < component_version_number);
+  }
+
+  // crosapi::BrowserManagerObserver:
+  void OnLoadComplete(bool success, const base::Version& version) override {
+    browser_version_loaded_ = version;
+  }
+
+ private:
+  // Version number of the most recently loaded lacros-chrome browser. This
+  // can be used for version checking and version comparisons. It is in the
+  // format of:
+  // <major_version>.<minor_version>.<build>.<patch>
+  // For example, "86.0.4240.38".
+  // Set immediately after lacros has loaded. May be invalid if BrowserLoader
+  // fails to successfully load a lacros binary.
+  base::Version browser_version_loaded_;
+
+  const raw_ptr<const ComponentUpdateService> component_update_service_;
+
+  base::ScopedObservation<BrowserManager, BrowserManagerObserver> observation_{
+      this};
+};
+
 }  // namespace
 
 // To be sure the lacros is running with neutral thread type.
@@ -431,6 +500,8 @@
       disabled_for_testing_(g_disabled_for_testing) {
   DCHECK(!g_instance);
   g_instance = this;
+  version_service_delegate_ =
+      std::make_unique<BrowserVersionServiceDelegate>(update_service, this);
 
   // Wait to query the flag until the user has entered the session. Enterprise
   // devices restart Chrome during login to apply flags. We don't want to run
@@ -599,7 +670,6 @@
            !IsLoginLacrosOpeningDisabledForTesting())) {
         pending_actions_.Push(BrowserAction::GetActionForSessionStart());
       }
-      component_update_observation_.Observe(component_update_service_);
       SetState(State::MOUNTING);
       browser_loader_->Load(base::BindOnce(
           &BrowserManager::OnLoadComplete, weak_factory_.GetWeakPtr(),
@@ -632,7 +702,6 @@
   DCHECK(!user_manager::UserManager::Get()->IsUserLoggedIn());
 
   // Load and start Lacros.
-  component_update_observation_.Observe(component_update_service_);
   SetState(State::MOUNTING);
   browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete,
                                        weak_factory_.GetWeakPtr(),
@@ -776,17 +845,19 @@
     DCHECK(browser_util::IsLacrosAllowedToLaunch());
   }
 
-  if (update_available_) {
-    update_available_ = false;
+  if (version_service_delegate_->IsNewerBrowserAvailable() &&
+      should_attempt_update_) {
     SetState(State::MOUNTING);
     lacros_path_ = base::FilePath();
     lacros_selection_ = absl::nullopt;
+    should_attempt_update_ = false;
     // OnLoadComplete will call Start again.
     browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete,
                                          weak_factory_.GetWeakPtr(),
                                          launching_at_login_screen));
     return;
   }
+  should_attempt_update_ = true;
 
   // Always reset the |relaunch_requested_| flag when launching Lacros.
   relaunch_requested_ = false;
@@ -1243,15 +1314,6 @@
   scheduler->RemoveObserver(this);
 }
 
-void BrowserManager::OnEvent(Events event, const std::string& id) {
-  // Track whether an update has been installed and should be loaded next time
-  // the browser is started.
-  if (event == Events::COMPONENT_UPDATED &&
-      id == browser_util::GetLacrosComponentInfo().crx_id) {
-    update_available_ = true;
-  }
-}
-
 void BrowserManager::OnLoadComplete(bool launching_at_login_screen,
                                     const base::FilePath& path,
                                     LacrosSelection selection,
@@ -1268,9 +1330,8 @@
   SetState(success ? State::STOPPED : State::UNAVAILABLE);
   // TODO(crbug.com/1266010): In the event the load operation failed, we should
   // launch the last successfully loaded image.
-  for (auto& observer : observers_) {
-    observer.OnLoadComplete(success);
-  }
+  for (auto& observer : observers_)
+    observer.OnLoadComplete(success, version);
 
   StartIfNeeded(launching_at_login_screen);
 }
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h
index 2a51f28..da013f885 100644
--- a/chrome/browser/ash/crosapi/browser_manager.h
+++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -23,6 +23,7 @@
 #include "chrome/browser/ash/crosapi/browser_manager_observer.h"
 #include "chrome/browser/ash/crosapi/browser_service_host_observer.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
+#include "chrome/browser/ash/crosapi/browser_version_service_ash.h"
 #include "chrome/browser/ash/crosapi/crosapi_id.h"
 #include "chrome/browser/ash/crosapi/crosapi_util.h"
 #include "chrome/browser/ash/crosapi/environment_provider.h"
@@ -30,7 +31,6 @@
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"
 #include "chromeos/crosapi/mojom/desk_template.mojom.h"
-#include "components/component_updater/component_updater_service.h"
 #include "components/policy/core/common/cloud/cloud_policy_core.h"
 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler_observer.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
@@ -90,8 +90,7 @@
                        public policy::CloudPolicyCore::Observer,
                        public policy::CloudPolicyStore::Observer,
                        public policy::ComponentCloudPolicyServiceObserver,
-                       public policy::CloudPolicyRefreshSchedulerObserver,
-                       public ComponentUpdateService::Observer {
+                       public policy::CloudPolicyRefreshSchedulerObserver {
  public:
   // Static getter of BrowserManager instance. In real use cases,
   // BrowserManager instance should be unique in the process.
@@ -285,6 +284,15 @@
   // for a graceful exit.
   void Shutdown();
 
+  const BrowserVersionServiceAsh::Delegate* version_service_delegate() const {
+    return version_service_delegate_.get();
+  }
+  void set_version_service_delegate_for_testing(
+      std::unique_ptr<BrowserVersionServiceAsh::Delegate>
+          version_service_delegate) {
+    version_service_delegate_ = std::move(version_service_delegate);
+  }
+
   void set_relaunch_requested_for_testing(bool relaunch_requested);
 
   // Parameters used to launch Lacros that are calculated on a background
@@ -586,9 +594,6 @@
   void OnRefreshSchedulerDestruction(
       policy::CloudPolicyRefreshScheduler* scheduler) override;
 
-  // component_updater::ComponentUpdateService::Observer:
-  void OnEvent(Events event, const std::string& id) override;
-
   // crosapi::BrowserManagerObserver:
   void OnLoadComplete(bool launching_at_login_screen,
                       const base::FilePath& path,
@@ -632,6 +637,9 @@
   // May be null in tests.
   ComponentUpdateService* const component_update_service_;
 
+  // Delegate handling various concerns regarding the version service.
+  std::unique_ptr<BrowserVersionServiceAsh::Delegate> version_service_delegate_;
+
   // Path to the lacros-chrome disk image directory.
   base::FilePath lacros_path_;
 
@@ -666,9 +674,11 @@
   // was unnecessary (e.g. because the user doesn't have Lacros enabled).
   bool unload_requested_ = false;
 
-  // Tracks whether an updated browser component is available. Used to determine
-  // if an update should be loaded prior to starting the browser.
-  bool update_available_ = false;
+  // Tracks whether BrowserManager should attempt to load a newer lacros-chrome
+  // browser version (if an update is possible and a new version is available).
+  // This helps to avoid re-trying an update multiple times should lacros-chrome
+  // fail to uprev on a reload.
+  bool should_attempt_update_ = true;
 
   // Tracks whether lacros-chrome is terminated.
   bool is_terminated_ = false;
@@ -683,10 +693,6 @@
   // '--lacros-mojo-socket-for-testing' is present in the command line.
   std::unique_ptr<TestMojoConnectionManager> test_mojo_connection_manager_;
 
-  base::ScopedObservation<ComponentUpdateService,
-                          ComponentUpdateService::Observer>
-      component_update_observation_{this};
-
   // Used to pass ash-chrome specific flags/configurations to lacros-chrome.
   std::unique_ptr<EnvironmentProvider> environment_provider_;
 
diff --git a/chrome/browser/ash/crosapi/browser_manager_observer.h b/chrome/browser/ash/crosapi/browser_manager_observer.h
index a067276e..569291c 100644
--- a/chrome/browser/ash/crosapi/browser_manager_observer.h
+++ b/chrome/browser/ash/crosapi/browser_manager_observer.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_ASH_CROSAPI_BROWSER_MANAGER_OBSERVER_H_
 
 #include "base/observer_list_types.h"
+#include "base/version.h"
 
 namespace crosapi {
 
@@ -16,7 +17,7 @@
   // Invoked when lacros-chrome state changes, without specifying the state.
   virtual void OnStateChanged() {}
   // Invoked when the browser loader has finished loading an image.
-  virtual void OnLoadComplete(bool success) {}
+  virtual void OnLoadComplete(bool success, const base::Version& version) {}
 };
 
 }  // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_manager_unittest.cc b/chrome/browser/ash/crosapi/browser_manager_unittest.cc
index 5aa0da2f..8a83fbe 100644
--- a/chrome/browser/ash/crosapi/browser_manager_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_manager_unittest.cc
@@ -99,6 +99,36 @@
   int start_count_ = 0;
 };
 
+class MockVersionServiceDelegate : public BrowserVersionServiceAsh::Delegate {
+ public:
+  MockVersionServiceDelegate() = default;
+  MockVersionServiceDelegate(const MockVersionServiceDelegate&) = delete;
+  MockVersionServiceDelegate& operator=(const MockVersionServiceDelegate&) =
+      delete;
+  ~MockVersionServiceDelegate() override = default;
+
+  // BrowserVersionServiceAsh::Delegate:
+  base::Version GetLatestLaunchableBrowserVersion() const override {
+    return latest_launchable_version_;
+  }
+
+  bool IsNewerBrowserAvailable() const override {
+    return is_newer_browser_available_;
+  }
+
+  void set_latest_lauchable_version(base::Version version) {
+    latest_launchable_version_ = std::move(version);
+  }
+
+  void set_is_newer_browser_available(bool is_newer_browser_available) {
+    is_newer_browser_available_ = is_newer_browser_available;
+  }
+
+ private:
+  base::Version latest_launchable_version_;
+  bool is_newer_browser_available_ = false;
+};
+
 }  // namespace
 
 class MockBrowserLoader : public BrowserLoader {
@@ -137,6 +167,11 @@
         std::make_unique<testing::NiceMock<MockComponentUpdateService>>();
     fake_browser_manager_ = std::make_unique<BrowserManagerFake>(
         std::move(browser_loader), component_update_service_.get());
+    auto version_service_delegate =
+        std::make_unique<MockVersionServiceDelegate>();
+    version_service_delegate_ = version_service_delegate.get();
+    fake_browser_manager_->set_version_service_delegate_for_testing(
+        std::move(version_service_delegate));
 
     shelf_model_ = std::make_unique<ash::ShelfModel>();
     shelf_controller_ = std::make_unique<ChromeShelfController>(
@@ -180,6 +215,7 @@
   MockBrowserLoader* browser_loader_ = nullptr;
   std::unique_ptr<MockComponentUpdateService> component_update_service_;
   std::unique_ptr<BrowserManagerFake> fake_browser_manager_;
+  raw_ptr<MockVersionServiceDelegate> version_service_delegate_;
   ScopedTestingLocalState local_state_;
   std::unique_ptr<ash::ShelfModel> shelf_model_;
   std::unique_ptr<ChromeShelfController> shelf_controller_;
@@ -263,13 +299,9 @@
   fake_browser_manager_->SetStatePublic(State::UNAVAILABLE);
   EXPECT_EQ(fake_browser_manager_->start_count(), 0);
 
-  // Simulate an update event by the component update service.
-  const std::string lacros_component_id =
-      browser_util::kLacrosDogfoodDevInfo.crx_id;
-  static_cast<component_updater::ComponentUpdateService::Observer*>(
-      fake_browser_manager_.get())
-      ->OnEvent(UpdateClient::Observer::Events::COMPONENT_UPDATED,
-                lacros_component_id);
+  version_service_delegate_->set_is_newer_browser_available(true);
+  version_service_delegate_->set_latest_lauchable_version(
+      base::Version("1.0.0"));
 
   std::unique_ptr<BrowserManager::ScopedKeepAlive> keep_alive =
       fake_browser_manager_->KeepAlive(BrowserManager::Feature::kTestOnly);
@@ -312,12 +344,9 @@
   using State = BrowserManagerFake::State;
   fake_browser_manager_->SetStatePublic(State::STOPPED);
 
-  const std::string lacros_component_id =
-      browser_util::kLacrosDogfoodDevInfo.crx_id;
-  static_cast<component_updater::ComponentUpdateService::Observer*>(
-      fake_browser_manager_.get())
-      ->OnEvent(UpdateClient::Observer::Events::COMPONENT_UPDATED,
-                lacros_component_id);
+  version_service_delegate_->set_is_newer_browser_available(true);
+  version_service_delegate_->set_latest_lauchable_version(
+      base::Version("1.0.0"));
 
   EXPECT_EQ(fake_browser_manager_->start_count(), 0);
   EXPECT_CALL(*browser_loader_, Load(_));
diff --git a/chrome/browser/ash/crosapi/browser_version_service_ash.cc b/chrome/browser/ash/crosapi/browser_version_service_ash.cc
index 1abecaf8..c74d241 100644
--- a/chrome/browser/ash/crosapi/browser_version_service_ash.cc
+++ b/chrome/browser/ash/crosapi/browser_version_service_ash.cc
@@ -4,24 +4,7 @@
 
 #include "chrome/browser/ash/crosapi/browser_version_service_ash.h"
 
-#include "base/ranges/algorithm.h"
-#include "chrome/browser/ash/crosapi/browser_util.h"
-
-namespace {
-
-absl::optional<component_updater::ComponentInfo> GetComponent(
-    const std::vector<component_updater::ComponentInfo>& components,
-    const std::string& id) {
-  auto it =
-      base::ranges::find(components, id, &component_updater::ComponentInfo::id);
-
-  if (it != components.end())
-    return *it;
-
-  return absl::nullopt;
-}
-
-}  // namespace
+#include "chrome/browser/ash/crosapi/browser_manager.h"
 
 namespace crosapi {
 
@@ -52,50 +35,38 @@
 
   // To avoid race conditions, trigger version notification on observer
   // registration.
-  absl::optional<base::Version> browser_version = GetBrowserVersion();
-  if (browser_version.has_value()) {
-    remote->OnBrowserVersionInstalled(browser_version.value().GetString());
-  }
+  remote->OnBrowserVersionInstalled(GetLatestLaunchableBrowserVersion());
 
   observers_.Add(std::move(remote));
 }
 
 void BrowserVersionServiceAsh::GetInstalledBrowserVersion(
     GetInstalledBrowserVersionCallback callback) {
-  std::string version_str;
+  std::move(callback).Run(GetLatestLaunchableBrowserVersion());
+}
 
-  auto browser_version = GetBrowserVersion();
-  if (browser_version.has_value())
-    version_str = browser_version.value().GetString();
-
-  std::move(callback).Run(version_str);
+const BrowserVersionServiceAsh::Delegate*
+BrowserVersionServiceAsh::GetDelegate() const {
+  return delegate_for_testing_
+             ? delegate_for_testing_.get()
+             : crosapi::BrowserManager::Get()->version_service_delegate();
 }
 
 void BrowserVersionServiceAsh::OnEvent(Events event, const std::string& id) {
-  absl::optional<component_updater::ComponentInfo> component_info =
-      GetComponent(component_update_service_->GetComponents(), id);
   // Check for notifications of the Lacros component being updated.
-  if (event == Events::COMPONENT_UPDATED &&
-      id == browser_util::GetLacrosComponentInfo().crx_id) {
-    absl::optional<base::Version> browser_version = GetBrowserVersion();
-    if (browser_version.has_value()) {
-      std::string version_str = browser_version.value().GetString();
-      for (auto& observer : observers_) {
-        observer->OnBrowserVersionInstalled(version_str);
-      }
-    }
+  if (event != Events::COMPONENT_UPDATED ||
+      id != browser_util::GetLacrosComponentInfo().crx_id ||
+      !GetDelegate()->IsNewerBrowserAvailable()) {
+    return;
   }
+
+  for (auto& observer : observers_)
+    observer->OnBrowserVersionInstalled(GetLatestLaunchableBrowserVersion());
 }
 
-absl::optional<base::Version> BrowserVersionServiceAsh::GetBrowserVersion() {
-  absl::optional<component_updater::ComponentInfo> component_info =
-      GetComponent(component_update_service_->GetComponents(),
-                   browser_util::GetLacrosComponentInfo().crx_id);
-  if (component_info.has_value()) {
-    return component_info.value().version;
-  }
-
-  return absl::nullopt;
+std::string BrowserVersionServiceAsh::GetLatestLaunchableBrowserVersion()
+    const {
+  return GetDelegate()->GetLatestLaunchableBrowserVersion().GetString();
 }
 
 }  // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_version_service_ash.h b/chrome/browser/ash/crosapi/browser_version_service_ash.h
index b39db2b..1499e07 100644
--- a/chrome/browser/ash/crosapi/browser_version_service_ash.h
+++ b/chrome/browser/ash/crosapi/browser_version_service_ash.h
@@ -17,6 +17,18 @@
     : public mojom::BrowserVersionService,
       public component_updater::ComponentUpdateService::Observer {
  public:
+  class Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Returns the latest available lacros-chrome version that can be launched.
+    virtual base::Version GetLatestLaunchableBrowserVersion() const = 0;
+
+    // Returns true if there is a more recent lacros-chrome binary available
+    // than what has currently been launched.
+    virtual bool IsNewerBrowserAvailable() const = 0;
+  };
+
   explicit BrowserVersionServiceAsh(
       component_updater::ComponentUpdateService* component_updater_service);
 
@@ -33,15 +45,25 @@
   void GetInstalledBrowserVersion(
       GetInstalledBrowserVersionCallback callback) override;
 
+  const Delegate* GetDelegate() const;
+
+  void set_delegate_for_testing(const Delegate* delegate) {
+    delegate_for_testing_ = delegate;
+  }
+
  private:
   // component_updater::ComponentUpdateService::Observer:
   void OnEvent(Events event, const std::string& id) override;
 
-  // Returns the browser version if there is one installed.
-  absl::optional<base::Version> GetBrowserVersion();
+  // Returns the stringified version of the latest available lacros-chrome that
+  // can be launched.
+  std::string GetLatestLaunchableBrowserVersion() const;
 
   component_updater::ComponentUpdateService* const component_update_service_;
 
+  // Optional delegate member for testing.
+  raw_ptr<const Delegate> delegate_for_testing_;
+
   // Support any number of connections.
   mojo::ReceiverSet<mojom::BrowserVersionService> receivers_;
 
diff --git a/chrome/browser/ash/crosapi/browser_version_service_ash_unittest.cc b/chrome/browser/ash/crosapi/browser_version_service_ash_unittest.cc
index f82a6c87..5b98314 100644
--- a/chrome/browser/ash/crosapi/browser_version_service_ash_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_version_service_ash_unittest.cc
@@ -37,6 +37,22 @@
   MOCK_METHOD1(OnBrowserVersionInstalled, void(const std::string& version));
 };
 
+class MockVersionServiceDelegate : public BrowserVersionServiceAsh::Delegate {
+ public:
+  MockVersionServiceDelegate() = default;
+  MockVersionServiceDelegate(const MockVersionServiceDelegate&) = delete;
+  MockVersionServiceDelegate& operator=(const MockVersionServiceDelegate&) =
+      delete;
+  ~MockVersionServiceDelegate() override = default;
+
+  // BrowserVersionServiceAsh::Delegate:
+  base::Version GetLatestLaunchableBrowserVersion() const override {
+    return base::Version("95.0.0.0");
+  }
+
+  bool IsNewerBrowserAvailable() const override { return true; }
+};
+
 class BrowserVersionServiceAshTest : public testing::Test {
  public:
   BrowserVersionServiceAshTest() = default;
@@ -70,8 +86,10 @@
       .Times(2);
 
   base::RunLoop run_loop;
+  MockVersionServiceDelegate delegate;
   BrowserVersionServiceAsh browser_version_service(
       &mock_component_update_service);
+  browser_version_service.set_delegate_for_testing(&delegate);
   browser_version_service.AddBrowserVersionObserver(
       browser_version_observer_.BindAndGetRemote());
 
@@ -96,8 +114,10 @@
   ON_CALL(mock_component_update_service, GetComponents())
       .WillByDefault(Return(sample_components));
 
+  MockVersionServiceDelegate delegate;
   BrowserVersionServiceAsh browser_version_service(
       &mock_component_update_service);
+  browser_version_service.set_delegate_for_testing(&delegate);
 
   base::MockCallback<
       mojom::BrowserVersionService::GetInstalledBrowserVersionCallback>
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index d7d3896a..4d4252e 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -176,6 +176,8 @@
           g_browser_process->component_updater())),
       cert_database_ash_(std::make_unique<CertDatabaseAsh>()),
       cert_provisioning_ash_(std::make_unique<CertProvisioningAsh>()),
+      chrome_app_kiosk_service_ash_(
+          std::make_unique<ChromeAppKioskServiceAsh>()),
       chrome_app_window_tracker_ash_(
           std::make_unique<ChromeAppWindowTrackerAsh>()),
       clipboard_ash_(std::make_unique<ClipboardAsh>()),
@@ -214,8 +216,6 @@
       in_session_auth_ash_(std::make_unique<InSessionAuthAsh>()),
       keystore_service_ash_(std::make_unique<KeystoreServiceAsh>()),
       kiosk_session_service_ash_(std::make_unique<KioskSessionServiceAsh>()),
-      chrome_app_kiosk_service_ash_(
-          std::make_unique<ChromeAppKioskServiceAsh>()),
       local_printer_ash_(std::make_unique<LocalPrinterAsh>()),
       login_ash_(std::make_unique<LoginAsh>()),
       login_screen_storage_ash_(std::make_unique<LoginScreenStorageAsh>()),
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h
index 481f8a7..4288d296 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.h
+++ b/chrome/browser/ash/crosapi/crosapi_ash.h
@@ -333,11 +333,21 @@
   void REMOVED_29(
       mojo::PendingReceiver<mojom::SystemDisplayDeprecated> receiver) override;
 
+  AutomationAsh* automation_ash() { return automation_ash_.get(); }
+
   BrowserServiceHostAsh* browser_service_host_ash() {
     return browser_service_host_ash_.get();
   }
 
-  AutomationAsh* automation_ash() { return automation_ash_.get(); }
+  CertDatabaseAsh* cert_database_ash() { return cert_database_ash_.get(); }
+
+  CertProvisioningAsh* cert_provisioning_ash() {
+    return cert_provisioning_ash_.get();
+  }
+
+  ChromeAppKioskServiceAsh* chrome_app_kiosk_service() {
+    return chrome_app_kiosk_service_ash_.get();
+  }
 
   DeskTemplateAsh* desk_template_ash() { return desk_template_ash_.get(); }
 
@@ -345,6 +355,11 @@
     return device_attributes_ash_.get();
   }
 
+  DeviceLocalAccountExtensionServiceAsh*
+  device_local_account_extension_service() {
+    return device_local_account_extension_service_ash_.get();
+  }
+
   DocumentScanAsh* document_scan_ash() { return document_scan_ash_.get(); }
 
   DownloadControllerAsh* download_controller_ash() {
@@ -352,12 +367,19 @@
   }
 
   EchoPrivateAsh* echo_private_ash() { return echo_private_ash_.get(); }
+
   EmojiPickerAsh* emoji_picker_ash() { return emoji_picker_ash_.get(); }
 
   ExtensionInfoPrivateAsh* extension_info_private_ash() {
     return extension_info_private_ash_.get();
   }
 
+  FileSystemProviderServiceAsh* file_system_provider_service_ash() {
+    return file_system_provider_service_ash_.get();
+  }
+
+  FileManagerAsh* file_manager_ash() { return file_manager_ash_.get(); }
+
   ForceInstalledTrackerAsh* force_installed_tracker_ash() {
     return force_installed_tracker_ash_.get();
   }
@@ -366,39 +388,26 @@
     return fullscreen_controller_ash_.get();
   }
 
+  ImageWriterAsh* image_writer_ash() { return image_writer_ash_.get(); }
+
+  KeystoreServiceAsh* keystore_service_ash() {
+    return keystore_service_ash_.get();
+  }
+
   KioskSessionServiceAsh* kiosk_session_service() {
     return kiosk_session_service_ash_.get();
   }
 
-  ChromeAppKioskServiceAsh* chrome_app_kiosk_service() {
-    return chrome_app_kiosk_service_ash_.get();
-  }
-
-  DeviceLocalAccountExtensionServiceAsh*
-  device_local_account_extension_service() {
-    return device_local_account_extension_service_ash_.get();
-  }
-
-  PrintingMetricsAsh* printing_metrics_ash() {
-    return printing_metrics_ash_.get();
-  }
-
-  SearchProviderAsh* search_provider_ash() {
-    return search_provider_ash_.get();
-  }
-
-  WallpaperAsh* wallpaper_ash() { return wallpaper_ash_.get(); }
-
-  WebAppServiceAsh* web_app_service_ash() { return web_app_service_ash_.get(); }
-
-  WebPageInfoFactoryAsh* web_page_info_factory_ash() {
-    return web_page_info_factory_ash_.get();
-  }
-
-  ImageWriterAsh* image_writer_ash() { return image_writer_ash_.get(); }
-
   LocalPrinterAsh* local_printer_ash() { return local_printer_ash_.get(); }
 
+  LoginAsh* login_ash() { return login_ash_.get(); }
+
+  LoginScreenStorageAsh* login_screen_storage_ash() {
+    return login_screen_storage_ash_.get();
+  }
+
+  LoginStateAsh* login_state_ash() { return login_state_ash_.get(); }
+
   NetworkChangeAsh* network_change_ash() { return network_change_ash_.get(); }
 
   NetworkingAttributesAsh* networking_attributes_ash() {
@@ -409,43 +418,35 @@
     return networking_private_ash_.get();
   }
 
-  TaskManagerAsh* task_manager_ash() { return task_manager_ash_.get(); }
-
-  TtsAsh* tts_ash() { return tts_ash_.get(); }
-
-  KeystoreServiceAsh* keystore_service_ash() {
-    return keystore_service_ash_.get();
-  }
-
-  CertDatabaseAsh* cert_database_ash() { return cert_database_ash_.get(); }
-
-  FileSystemProviderServiceAsh* file_system_provider_service_ash() {
-    return file_system_provider_service_ash_.get();
-  }
-
-  FileManagerAsh* file_manager_ash() { return file_manager_ash_.get(); }
-
-  CertProvisioningAsh* cert_provisioning_ash() {
-    return cert_provisioning_ash_.get();
-  }
-
-  LoginAsh* login_ash() { return login_ash_.get(); }
-
-  LoginScreenStorageAsh* login_screen_storage_ash() {
-    return login_screen_storage_ash_.get();
-  }
-
-  LoginStateAsh* login_state_ash() { return login_state_ash_.get(); }
-
   ParentAccessAsh* parent_access_ash() { return parent_access_ash_.get(); }
 
+  PrintingMetricsAsh* printing_metrics_ash() {
+    return printing_metrics_ash_.get();
+  }
+
+  ScreenManagerAsh* screen_manager_ash() { return screen_manager_ash_.get(); }
+
+  SearchProviderAsh* search_provider_ash() {
+    return search_provider_ash_.get();
+  }
+
   SharesheetAsh* sharesheet_ash() { return sharesheet_ash_.get(); }
 
   StructuredMetricsServiceAsh* structured_metrics_service_ash() {
     return structured_metrics_service_ash_.get();
   }
 
-  ScreenManagerAsh* screen_manager_ash() { return screen_manager_ash_.get(); }
+  TaskManagerAsh* task_manager_ash() { return task_manager_ash_.get(); }
+
+  TtsAsh* tts_ash() { return tts_ash_.get(); }
+
+  WallpaperAsh* wallpaper_ash() { return wallpaper_ash_.get(); }
+
+  WebAppServiceAsh* web_app_service_ash() { return web_app_service_ash_.get(); }
+
+  WebPageInfoFactoryAsh* web_page_info_factory_ash() {
+    return web_page_info_factory_ash_.get();
+  }
 
   VirtualKeyboardAsh* virtual_keyboard_ash() {
     return virtual_keyboard_ash_.get();
@@ -454,6 +455,7 @@
   VpnExtensionObserverAsh* vpn_extension_observer_ash() {
     return vpn_extension_observer_ash_.get();
   }
+
   VpnServiceAsh* vpn_service_ash() { return vpn_service_ash_.get(); }
 
   // Caller is responsible for ensuring that the pointer stays valid.
@@ -471,6 +473,7 @@
   std::unique_ptr<BrowserVersionServiceAsh> browser_version_service_ash_;
   std::unique_ptr<CertDatabaseAsh> cert_database_ash_;
   std::unique_ptr<CertProvisioningAsh> cert_provisioning_ash_;
+  std::unique_ptr<ChromeAppKioskServiceAsh> chrome_app_kiosk_service_ash_;
   std::unique_ptr<ChromeAppWindowTrackerAsh> chrome_app_window_tracker_ash_;
   std::unique_ptr<ClipboardAsh> clipboard_ash_;
   std::unique_ptr<ClipboardHistoryAsh> clipboard_history_ash_;
@@ -504,7 +507,6 @@
   std::unique_ptr<InSessionAuthAsh> in_session_auth_ash_;
   std::unique_ptr<KeystoreServiceAsh> keystore_service_ash_;
   std::unique_ptr<KioskSessionServiceAsh> kiosk_session_service_ash_;
-  std::unique_ptr<ChromeAppKioskServiceAsh> chrome_app_kiosk_service_ash_;
   std::unique_ptr<LocalPrinterAsh> local_printer_ash_;
   std::unique_ptr<LoginAsh> login_ash_;
   std::unique_ptr<LoginScreenStorageAsh> login_screen_storage_ash_;
diff --git a/chrome/browser/ash/customization/customization_document.cc b/chrome/browser/ash/customization/customization_document.cc
index eb6f786..9eb2fb81 100644
--- a/chrome/browser/ash/customization/customization_document.cc
+++ b/chrome/browser/ash/customization/customization_document.cc
@@ -356,9 +356,9 @@
     if (keyboard_layout_ptr)
       keyboard_layout_ = *keyboard_layout_ptr;
 
-    std::string hwid;
-    if (statistics_provider->GetMachineStatistic(
-            chromeos::system::kHardwareClassKey, &hwid)) {
+    if (const absl::optional<base::StringPiece> hwid =
+            statistics_provider->GetMachineStatistic(
+                chromeos::system::kHardwareClassKey)) {
       base::Value::List* hwid_list = root_->FindList(kHwidMapAttr);
       if (hwid_list) {
         for (const base::Value& hwid_value : *hwid_list) {
@@ -370,7 +370,7 @@
               hwid_dictionary ? hwid_dictionary->FindString(kHwidMaskAttr)
                               : nullptr;
           if (hwid_mask) {
-            if (base::MatchPattern(hwid, *hwid_mask)) {
+            if (base::MatchPattern(hwid.value(), *hwid_mask)) {
               // If HWID for this machine matches some mask, use HWID specific
               // settings.
               const std::string* initial_locale =
@@ -400,12 +400,21 @@
   }
 
   // If manifest doesn't exist still apply values from VPD.
-  statistics_provider->GetMachineStatistic(chromeos::system::kInitialLocaleKey,
-                                           &initial_locale_);
-  statistics_provider->GetMachineStatistic(
-      chromeos::system::kInitialTimezoneKey, &initial_timezone_);
-  statistics_provider->GetMachineStatistic(chromeos::system::kKeyboardLayoutKey,
-                                           &keyboard_layout_);
+  if (const absl::optional<base::StringPiece> locale_statistic =
+          statistics_provider->GetMachineStatistic(
+              chromeos::system::kInitialLocaleKey)) {
+    initial_locale_ = std::string(locale_statistic.value());
+  }
+  if (const absl::optional<base::StringPiece> timezone_statistic =
+          statistics_provider->GetMachineStatistic(
+              chromeos::system::kInitialTimezoneKey)) {
+    initial_timezone_ = std::string(timezone_statistic.value());
+  }
+  if (const absl::optional<base::StringPiece> keyboard_statistic =
+          statistics_provider->GetMachineStatistic(
+              chromeos::system::kKeyboardLayoutKey)) {
+    keyboard_layout_ = std::string(keyboard_statistic.value());
+  }
   configured_locales_ = base::SplitString(
       initial_locale_, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
 
@@ -580,14 +589,13 @@
     return;
 
   if (!url_.is_valid()) {
-    std::string customization_id;
     chromeos::system::StatisticsProvider* provider =
         chromeos::system::StatisticsProvider::GetInstance();
-    if (provider->GetMachineStatistic(chromeos::system::kCustomizationIdKey,
-                                      &customization_id) &&
-        !customization_id.empty()) {
+    const absl::optional<base::StringPiece> customization_id =
+        provider->GetMachineStatistic(chromeos::system::kCustomizationIdKey);
+    if (customization_id && !customization_id->empty()) {
       url_ = GURL(base::StringPrintf(
-          kManifestUrl, base::ToLowerASCII(customization_id).c_str()));
+          kManifestUrl, base::ToLowerASCII(customization_id.value()).c_str()));
     } else {
       // Remember that there is no customization ID in VPD.
       OnCustomizationNotFound();
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
index 314a4223..8ad1017 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -180,6 +180,7 @@
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "components/variations/pref_names.h"
+#include "components/viz/host/host_frame_sink_manager.h"
 #include "components/webapps/browser/banners/app_banner_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_controller.h"
@@ -200,6 +201,7 @@
 #include "extensions/common/permissions/permissions_data.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "net/base/filename_util.h"
+#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-shared.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/env.h"
@@ -1007,6 +1009,20 @@
   DCHECK(false);
 }
 
+std::string CompositorFrameSinkTypeToString(
+    viz::mojom::CompositorFrameSinkType type) {
+  switch (type) {
+    case viz::mojom::CompositorFrameSinkType::kUnspecified:
+      return "unspecified";
+    case viz::mojom::CompositorFrameSinkType::kVideo:
+      return "video";
+    case viz::mojom::CompositorFrameSinkType::kMediaStream:
+      return "media-stream";
+    case viz::mojom::CompositorFrameSinkType::kLayerTree:
+      return "layer-tree";
+  }
+}
+
 }  // namespace
 
 class WindowStateChangeObserver : public aura::WindowObserver {
@@ -6266,6 +6282,85 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// AutotestPrivateStartFrameCountingFunction
+//////////////////////////////////////////////////////////////////////////////
+
+AutotestPrivateStartFrameCountingFunction::
+    AutotestPrivateStartFrameCountingFunction() = default;
+
+AutotestPrivateStartFrameCountingFunction::
+    ~AutotestPrivateStartFrameCountingFunction() = default;
+
+ExtensionFunction::ResponseAction
+AutotestPrivateStartFrameCountingFunction::Run() {
+  std::unique_ptr<api::autotest_private::StartFrameCounting::Params> params(
+      api::autotest_private::StartFrameCounting::Params::Create(args()));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  if (params->bucket_size_in_seconds <= 0) {
+    return RespondNow(
+        Error("Param bucketSizeInSeconds must be greater than 0s"));
+  }
+
+  // "viz.mojom.FrameCountingPerSinkData" uses uint16 to store frame counts.
+  // Limit the max bucket size so that the max frame count does not go beyond
+  // uint16 max. 500s is safe even for a 120fps system.
+  constexpr int kMaxBucketSizeInSeconds = 500;
+  if (params->bucket_size_in_seconds > kMaxBucketSizeInSeconds) {
+    return RespondNow(
+        Error("Param bucketSizeInSeconds must be less than 500s"));
+  }
+
+  aura::Env::GetInstance()
+      ->context_factory()
+      ->GetHostFrameSinkManager()
+      ->StartFrameCountingForTest(  // IN-TEST
+          base::Seconds(params->bucket_size_in_seconds));
+  return RespondNow(NoArguments());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AutotestPrivateStopFrameCountingFunction
+//////////////////////////////////////////////////////////////////////////////
+
+AutotestPrivateStopFrameCountingFunction::
+    AutotestPrivateStopFrameCountingFunction() = default;
+
+AutotestPrivateStopFrameCountingFunction::
+    ~AutotestPrivateStopFrameCountingFunction() = default;
+
+ExtensionFunction::ResponseAction
+AutotestPrivateStopFrameCountingFunction::Run() {
+  auto callback = base::BindOnce(
+      &AutotestPrivateStopFrameCountingFunction::OnDataReceived, this);
+  aura::Env::GetInstance()
+      ->context_factory()
+      ->GetHostFrameSinkManager()
+      ->StopFrameCountingForTest(std::move(callback));  // IN-TEST
+  return RespondLater();
+}
+
+void AutotestPrivateStopFrameCountingFunction::OnDataReceived(
+    viz::mojom::FrameCountingDataPtr data_ptr) {
+  std::vector<api::autotest_private::FrameCountingPerSinkData> result;
+  for (const auto& per_sink_data : data_ptr->per_sink_data) {
+    api::autotest_private::FrameCountingPerSinkData result_per_sink_data;
+    result_per_sink_data.sink_type =
+        CompositorFrameSinkTypeToString(per_sink_data->type);
+    result_per_sink_data.is_root = per_sink_data->is_root;
+
+    std::copy(per_sink_data->presented_frames.begin(),
+              per_sink_data->presented_frames.end(),
+              std::back_inserter(result_per_sink_data.presented_frames));
+
+    result.emplace_back(std::move(result_per_sink_data));
+  }
+
+  Respond(ArgumentList(
+      api::autotest_private::StopFrameCounting::Results::Create(result)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // AutotestPrivateAPI
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
index 690db15..2ecf7e03 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
@@ -27,6 +27,7 @@
 #include "extensions/browser/extension_function.h"
 #include "extensions/browser/extension_function_histogram_value.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
 #include "ui/base/clipboard/clipboard_observer.h"
@@ -1730,6 +1731,30 @@
   ResponseAction Run() override;
 };
 
+class AutotestPrivateStartFrameCountingFunction : public ExtensionFunction {
+ public:
+  AutotestPrivateStartFrameCountingFunction();
+  DECLARE_EXTENSION_FUNCTION("autotestPrivate.startFrameCounting",
+                             AUTOTESTPRIVATE_STARTFRAMECOUNTING)
+
+ private:
+  ~AutotestPrivateStartFrameCountingFunction() override;
+  ResponseAction Run() override;
+};
+
+class AutotestPrivateStopFrameCountingFunction : public ExtensionFunction {
+ public:
+  AutotestPrivateStopFrameCountingFunction();
+  DECLARE_EXTENSION_FUNCTION("autotestPrivate.stopFrameCounting",
+                             AUTOTESTPRIVATE_STOPFRAMECOUNTING)
+
+ private:
+  ~AutotestPrivateStopFrameCountingFunction() override;
+  ResponseAction Run() override;
+
+  void OnDataReceived(viz::mojom::FrameCountingDataPtr data_ptr);
+};
+
 template <>
 KeyedService*
 BrowserContextKeyedAPIFactory<AutotestPrivateAPI>::BuildServiceInstanceFor(
diff --git a/chrome/browser/ash/extensions/default_app_order.cc b/chrome/browser/ash/extensions/default_app_order.cc
index 18c7b9dd..0d3930c 100644
--- a/chrome/browser/ash/extensions/default_app_order.cc
+++ b/chrome/browser/ash/extensions/default_app_order.cc
@@ -40,10 +40,9 @@
 const char kNameAttr[] = "name";
 const char kImportDefaultOrderAttr[] = "import_default_order";
 
-// Reads external ordinal json file and returned the parsed value. Returns NULL
-// if the file does not exist or could not be parsed properly. Caller takes
-// ownership of the returned value.
-std::unique_ptr<base::ListValue> ReadExternalOrdinalFile(
+// Reads external ordinal json file and returns the parsed value. Returns NULL
+// if the file does not exist or could not be parsed properly.
+std::unique_ptr<base::Value::List> ReadExternalOrdinalFile(
     const base::FilePath& path) {
   if (!base::PathExists(path))
     return nullptr;
@@ -58,12 +57,10 @@
     return nullptr;
   }
 
-  std::unique_ptr<base::ListValue> ordinal_list_value =
-      base::ListValue::From(std::move(value));
-  if (!ordinal_list_value)
+  if (!value->is_list())
     LOG(WARNING) << "Expect a JSON list in file " << path.value();
 
-  return ordinal_list_value;
+  return std::make_unique<base::Value::List>(std::move(*value).TakeList());
 }
 
 std::string GetLocaleSpecificStringImpl(const base::Value::Dict& root,
@@ -240,11 +237,11 @@
   base::FilePath ordinals_file;
   CHECK(base::PathService::Get(FILE_DEFAULT_APP_ORDER, &ordinals_file));
 
-  std::unique_ptr<base::ListValue> ordinals_value =
+  std::unique_ptr<base::Value::List> ordinals_value =
       ReadExternalOrdinalFile(ordinals_file);
   if (ordinals_value) {
     std::string locale = g_browser_process->GetApplicationLocale();
-    for (const base::Value& i : ordinals_value->GetList()) {
+    for (const base::Value& i : *ordinals_value) {
       if (i.is_string()) {
         std::string app_id = i.GetString();
         app_ids_.push_back(app_id);
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 83ce3028..f22ba51 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -343,6 +343,14 @@
               ::testing::Return(policy::DlpRulesManager::Level::kBlock));
       return true;
     }
+    if (name == "setBlockedComponents") {
+      policy::DlpRulesManager::AggregatedComponents components;
+      components[policy::DlpRulesManager::Level::kBlock].insert(
+          policy::DlpRulesManager::Component::kArc);
+      EXPECT_CALL(*mock_rules_manager_, GetAggregatedComponents)
+          .WillOnce(testing::Return(components));
+      return true;
+    }
     if (name == "setIsRestrictedByAnyRuleRestrictions") {
       EXPECT_CALL(*mock_rules_manager_, IsRestrictedByAnyRule)
           .WillOnce(::testing::Return(policy::DlpRulesManager::Level::kWarn))
@@ -1266,10 +1274,10 @@
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
     DLP, /* dlp.js */
     DlpFilesAppBrowserTest,
-    ::testing::Values(
-        TestCase("transferShowDlpToast").EnableDlp(),
-        TestCase("dlpShowManagedIcon").EnableDlp(),
-        TestCase("dlpContextMenuRestrictionDetails").EnableDlp()));
+    ::testing::Values(TestCase("transferShowDlpToast").EnableDlp(),
+                      TestCase("dlpShowManagedIcon").EnableDlp(),
+                      TestCase("dlpContextMenuRestrictionDetails").EnableDlp(),
+                      TestCase("saveAsDlpRestrictedDirectory").EnableDlp()));
 
 #define FILE_TRANSFER_TEST_CASE(name) \
   TestCase(name).EnableFileTransferConnector()
diff --git a/chrome/browser/ash/file_manager/trash_info_validator.cc b/chrome/browser/ash/file_manager/trash_info_validator.cc
index 06055b58..e9599252 100644
--- a/chrome/browser/ash/file_manager/trash_info_validator.cc
+++ b/chrome/browser/ash/file_manager/trash_info_validator.cc
@@ -66,7 +66,7 @@
       return base::File::FILE_ERROR_INVALID_OPERATION;
     default:
       NOTREACHED();
-      break;
+      return base::File::FILE_ERROR_FAILED;
   }
 }
 
diff --git a/chrome/browser/ash/ownership/owner_key_loader.cc b/chrome/browser/ash/ownership/owner_key_loader.cc
index 471b90d..4ac533f 100644
--- a/chrome/browser/ash/ownership/owner_key_loader.cc
+++ b/chrome/browser/ash/ownership/owner_key_loader.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/ownership/owner_key_util.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/cert/nss_cert_database.h"
@@ -65,7 +66,7 @@
   crypto::ScopedSECKEYPrivateKey sec_priv_key =
       owner_key_util->GenerateKeyPair(nss_db->GetPublicSlot().get());
   if (!sec_priv_key) {
-    LOG(ERROR) << "Failed to generete owner key";
+    LOG(ERROR) << "Failed to generate owner key";
     content::GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(std::move(ui_thread_callback), nullptr, nullptr));
@@ -146,10 +147,12 @@
     Profile* profile,
     DeviceSettingsService* device_settings_service,
     scoped_refptr<ownership::OwnerKeyUtil> owner_key_util,
+    bool is_enterprise_managed,
     KeypairCallback callback)
     : profile_(profile),
       device_settings_service_(device_settings_service),
       owner_key_util_(std::move(owner_key_util)),
+      is_enterprise_managed_(is_enterprise_managed),
       callback_(std::move(callback)) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(profile_);
@@ -167,24 +170,12 @@
 
   if (!device_settings_service_) {
     CHECK_IS_TEST();
-    std::move(callback_).Run(/*public_key=*/nullptr, /*private_key=*/nullptr);
+    return std::move(callback_).Run(/*public_key=*/nullptr,
+                                    /*private_key=*/nullptr);
     // `this` might be deleted here.
-    return;
   }
 
-  // device_settings_service_ indicates that the current user should become the
-  // owner, generate a new owner key pair for them.
-  if (device_settings_service_->GetWillEstablishConsumerOwnership()) {
-    LOG(WARNING) << "Establishing consumer ownership.";
-    GetCertDbAndPostOnWorkerThread(
-        profile_,
-        base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_,
-                       base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated,
-                                      weak_factory_.GetWeakPtr())));
-    return;
-  }
-
-  // Otherwise it might be the owner or not, start with loading the public key.
+  // Try loading the public key first. Most of the time it should already exist.
   base::ThreadPool::PostTask(
       FROM_HERE,
       {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
@@ -198,27 +189,28 @@
     scoped_refptr<ownership::PublicKey> public_key) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (!public_key || public_key->is_empty()) {
-    // This should not happen. For the very first user that doesn't have the
-    // public key yet, device_settings_service_ should indicate that. For other
-    // users, they should either have the public key or session_manager should
-    // recover it from the policies or session_manager should initiate powerwash
-    // if both policies and the public key were lost.
-    LOG(ERROR) << "Failed to load public key.";
-    std::move(callback_).Run(
-        /*public_key=*/nullptr, /*private_key=*/nullptr);
-    // `this` might be deleted here.
-    return;
-  }
-  public_key_ = public_key;
+  public_key_ = std::move(public_key);
 
-  // Now check whether the current user has access to the private key associated
-  // with the public key.
-  GetCertDbAndPostOnWorkerThread(
-      profile_, base::BindOnce(
-                    &LoadPrivateKeyOnWorkerThread, owner_key_util_, public_key_,
-                    base::BindOnce(&OwnerKeyLoader::OnPrivateKeyLoaded,
-                                   weak_factory_.GetWeakPtr())));
+  if (is_enterprise_managed_) {
+    // Managed devices don't have private owner keys.
+    return std::move(callback_).Run(std::move(public_key_), nullptr);
+    // `this` might be deleted here.
+  }
+
+  if (public_key_ && !public_key_->is_empty()) {
+    // Now check whether the current user has access to the private key
+    // associated with the public key.
+    return GetCertDbAndPostOnWorkerThread(
+        profile_,
+        base::BindOnce(&LoadPrivateKeyOnWorkerThread, owner_key_util_,
+                       public_key_,
+                       base::BindOnce(&OwnerKeyLoader::OnPrivateKeyLoaded,
+                                      weak_factory_.GetWeakPtr())));
+  }
+
+  // Public key was not found, if the current user is the owner, a new key
+  // should be generated.
+  MaybeGenerateNewKey();
 }
 
 void OwnerKeyLoader::OnPrivateKeyLoaded(
@@ -226,23 +218,65 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (private_key && private_key->key()) {
     // Success: both keys were loaded, the current user is the owner.
-    std::move(callback_).Run(public_key_, private_key);
+    return std::move(callback_).Run(std::move(public_key_),
+                                    std::move(private_key));
     // `this` might be deleted here.
-    return;
   }
 
-  // Private key failed to load. Maybe the current user is not the owner. Or
-  // the private key was lost. Check the policies to make the decision.
-  if (device_settings_service_->policy_data()) {
-    MaybeRegenerateLostKey(device_settings_service_->policy_data());
-    return;
+  // Private key failed to load. Maybe the current user is not the owner and
+  // doesn't have access to the key. Or the private key was lost. Make the
+  // decision and generate a new key if needed.
+  MaybeGenerateNewKey();
+}
+
+void OwnerKeyLoader::MaybeGenerateNewKey() {
+  // device_settings_service_ indicates that the current user should become the
+  // owner, generate a new owner key pair for them.
+  if (device_settings_service_->GetWillEstablishConsumerOwnership()) {
+    LOG(WARNING) << "Establishing consumer ownership.";
+    return GenerateNewKey();
   }
-  // If policy data is not available yet, try waiting for it. The assumption is
-  // that it can be loaded before this class finishes its work. The public key
-  // is usually required to load the policies, but device_settings_service_ also
-  // independently loads it for itself.
-  device_settings_service_->GetPolicyDataAsync(base::BindOnce(
-      &OwnerKeyLoader::OnPolicyDataReady, weak_factory_.GetWeakPtr()));
+
+  // Otherwise maybe it's not the first sign in. Check device policies.
+  // If the owner key was never generated before, the policies will be empty.
+  // Also, in theory ChromeOS is allowed to lose the policies and recover, so
+  // be prepared for them to still be empty.
+  const enterprise_management::PolicyData* policy_data =
+      device_settings_service_->policy_data();
+  if (policy_data && policy_data->has_username()) {
+    // If the policy says that the current user is the owner, generate a new key
+    // pair for them.
+    if (policy_data->username() == profile_->GetProfileUserName()) {
+      LOG(WARNING) << "The owner key was lost. Generating a new one.";
+      return GenerateNewKey();
+    } else {
+      // The current user is not the owner, just return the public key.
+      return std::move(callback_).Run(std::move(public_key_), nullptr);
+      // `this` might be deleted here.
+    }
+  }
+
+  // If the policies are empty, check the local state PrefService.
+  absl::optional<std::string> owner_email =
+      user_manager::UserManager::Get()->GetOwnerEmail();
+  if (owner_email.has_value() &&
+      owner_email.value() == profile_->GetProfileUserName()) {
+    LOG(WARNING) << "Generating new owner key based on local state data.";
+    return GenerateNewKey();
+  }
+
+  // The current user doesn't seem to be the owner, just return the public key
+  // (or nullptr, if it wasn't successfully loaded earlier).
+  return std::move(callback_).Run(std::move(public_key_), nullptr);
+  // `this` might be deleted here.
+}
+
+void OwnerKeyLoader::GenerateNewKey() {
+  GetCertDbAndPostOnWorkerThread(
+      profile_,
+      base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_,
+                     base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated,
+                                    weak_factory_.GetWeakPtr())));
 }
 
 void OwnerKeyLoader::OnNewKeyGenerated(
@@ -251,57 +285,22 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (private_key && private_key->key()) {
     LOG(WARNING) << "New owner key pair was generated.";
-    std::move(callback_).Run(public_key, private_key);
+    return std::move(callback_).Run(std::move(public_key),
+                                    std::move(private_key));
     // `this` might be deleted here.
-    return;
   }
 
   if (++generate_attempt_counter_ <= kMaxGenerateAttempts) {
     // Key generation is not expected to fail, but it is too important to simply
     // give up. Retry up to `kMaxGenerateAttempts` times if needed.
-    GetCertDbAndPostOnWorkerThread(
-        profile_,
-        base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_,
-                       base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated,
-                                      weak_factory_.GetWeakPtr())));
-    return;
+    return GenerateNewKey();
   }
 
   LOG(ERROR) << "Failed to generate new owner key.";
   // Return at least the public key, if it was loaded. If Chrome is taking
   // ownership for the first time, it should be null. If recovering from a lost
   // private key, it should be not null.
-  std::move(callback_).Run(public_key_, nullptr);
-  // `this` might be deleted here.
-}
-
-// This method is needed just to convert non-const pointer to a const one.
-// OnceCallback struggles to do it itself.
-void OwnerKeyLoader::OnPolicyDataReady(
-    enterprise_management::PolicyData* policy_data) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  MaybeRegenerateLostKey(policy_data);
-}
-
-void OwnerKeyLoader::MaybeRegenerateLostKey(
-    const enterprise_management::PolicyData* policy_data) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  // If the policy says that the current user is the owner, generate a new key
-  // pair for them. Also, in theory ChromeOS is allowed to lose the policies and
-  // recover, so be prepared for them to still be empty.
-  if (policy_data && policy_data->has_username() &&
-      (policy_data->username() == profile_->GetProfileUserName())) {
-    LOG(WARNING) << "The owner key was lost. Generating a new one.";
-    GetCertDbAndPostOnWorkerThread(
-        profile_,
-        base::BindOnce(&GenerateNewOwnerKeyOnWorkerThread, owner_key_util_,
-                       base::BindOnce(&OwnerKeyLoader::OnNewKeyGenerated,
-                                      weak_factory_.GetWeakPtr())));
-    return;
-  }
-
-  // The user doesn't seem to be the owner, return just the public key.
-  std::move(callback_).Run(public_key_, /*private_key=*/nullptr);
+  return std::move(callback_).Run(std::move(public_key_), nullptr);
   // `this` might be deleted here.
 }
 
diff --git a/chrome/browser/ash/ownership/owner_key_loader.h b/chrome/browser/ash/ownership/owner_key_loader.h
index 969ddab..1d9884cf 100644
--- a/chrome/browser/ash/ownership/owner_key_loader.h
+++ b/chrome/browser/ash/ownership/owner_key_loader.h
@@ -38,6 +38,7 @@
   OwnerKeyLoader(Profile* profile,
                  DeviceSettingsService* device_settings_service,
                  scoped_refptr<ownership::OwnerKeyUtil> owner_key_util,
+                 bool is_enterprise_managed,
                  KeypairCallback callback);
   OwnerKeyLoader(const OwnerKeyLoader&) = delete;
   auto operator=(const OwnerKeyLoader&) = delete;
@@ -50,15 +51,17 @@
  private:
   void OnPublicKeyLoaded(scoped_refptr<ownership::PublicKey> public_key);
   void OnPrivateKeyLoaded(scoped_refptr<ownership::PrivateKey> private_key);
+  void MaybeGenerateNewKey();
+  void GenerateNewKey();
   void OnNewKeyGenerated(scoped_refptr<ownership::PublicKey> public_key,
                          scoped_refptr<ownership::PrivateKey> private_key);
-  void OnPolicyDataReady(enterprise_management::PolicyData* policy_data);
   void MaybeRegenerateLostKey(
       const enterprise_management::PolicyData* policy_data);
 
   Profile* const profile_;
   DeviceSettingsService* const device_settings_service_;
   scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_;
+  const bool is_enterprise_managed_;
   scoped_refptr<ownership::PublicKey> public_key_;
   KeypairCallback callback_;
   int generate_attempt_counter_ = 0;
diff --git a/chrome/browser/ash/ownership/owner_key_loader_unittest.cc b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
index b1ca912..f5ad237 100644
--- a/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
+++ b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
@@ -11,12 +11,19 @@
 #include "chrome/browser/ash/policy/core/device_policy_builder.h"
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/net/fake_nss_service.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/ownership/mock_owner_key_util.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/user_manager/fake_user_manager.h"
+#include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "crypto/rsa_private_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using PublicKeyRefPtr = scoped_refptr<ownership::PublicKey>;
+using PrivateKeyRefPtr = scoped_refptr<ownership::PrivateKey>;
+
 namespace ash {
 
 std::vector<uint8_t> ExtractBytes(
@@ -30,6 +37,14 @@
  public:
   // testing::Test:
   void SetUp() override {
+    auto fake_user_manager = std::make_unique<user_manager::FakeUserManager>();
+    user_manager_ = fake_user_manager.get();
+    scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
+        std::move(fake_user_manager));
+
+    user_manager_->set_local_state(&local_state_);
+    user_manager_->RegisterPrefs(local_state_.registry());
+
     owner_key_util_ = base::MakeRefCounted<ownership::MockOwnerKeyUtil>();
 
     device_settings_service_.SetSessionManager(&session_manager_client_,
@@ -42,7 +57,7 @@
 
     key_loader_ = std::make_unique<OwnerKeyLoader>(
         profile_.get(), &device_settings_service_, owner_key_util_,
-        result_observer_.GetCallback());
+        /*is_enterprise_enrolled=*/false, result_observer_.GetCallback());
   }
 
  protected:
@@ -59,15 +74,17 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
+  TestingPrefServiceSimple local_state_;
+
+  std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
+  user_manager::FakeUserManager* user_manager_ = nullptr;
 
   scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
   FakeSessionManagerClient session_manager_client_;
   std::unique_ptr<TestingProfile> profile_;
   ash::DeviceSettingsService device_settings_service_;
   std::unique_ptr<OwnerKeyLoader> key_loader_;
-  base::test::TestFuture<scoped_refptr<ownership::PublicKey>,
-                         scoped_refptr<ownership::PrivateKey>>
-      result_observer_;
+  base::test::TestFuture<PublicKeyRefPtr, PrivateKeyRefPtr> result_observer_;
 };
 
 // Test that the first user generates a new owner key.
@@ -78,8 +95,28 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_TRUE(result_observer_.Get<1>()->key());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  EXPECT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
+}
+
+// Test that the first user generates owner key after a crash. If during the
+// first attempt Chrome crashes, on the next launch DeviceSettingsService won't
+// indicate again that the consumer owners needs to be established.
+// In such a case OwnerKeyLoader should read the identity of the owner from
+// local state.
+TEST_F(OwnerKeyLoaderTest, FirstUserGeneratesOwnerKeyAfterCrash) {
+  // Populate local state data that OwnerKeyLoader should read.
+  user_manager_->RecordOwner(
+      AccountId::FromUserEmail(profile_->GetProfileUserName()));
+
+  key_loader_->Run();
+
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  EXPECT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
 }
 
 // Test that the second user doesn't try to generate a new owner key.
@@ -92,9 +129,11 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key));
-  EXPECT_FALSE(result_observer_.Get<1>());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_EQ(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  EXPECT_FALSE(result_observer_.Get<PrivateKeyRefPtr>());
 }
 
 // Test that an owner user gets recognized as the owner when it's mentioned in
@@ -107,9 +146,12 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key));
-  EXPECT_TRUE(result_observer_.Get<1>()->key());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_EQ(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
 }
 
 // Test that even without existing device policies the owner key gets loaded
@@ -122,9 +164,12 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key));
-  EXPECT_TRUE(result_observer_.Get<1>()->key());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_EQ(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
 }
 
 // Test that the second user is not falsely recognized as the owner even if
@@ -137,15 +182,17 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_EQ(result_observer_.Get<0>()->data(), ExtractBytes(signing_key));
-  EXPECT_FALSE(result_observer_.Get<1>());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_EQ(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  EXPECT_FALSE(result_observer_.Get<PrivateKeyRefPtr>());
 }
 
 // Test that an owner user still gets recognized as the owner when it's
 // mentioned in the existing device policies, but the owner key was lost.
 // The key must be re-generated in such a case.
-TEST_F(OwnerKeyLoaderTest, OwnerUserRegeneratesMissingKey) {
+TEST_F(OwnerKeyLoaderTest, OwnerUserRegeneratesMissingKeyBasedOnPolicies) {
   auto signing_key = ConfigureExistingPolicies(profile_->GetProfileUserName());
   // Configure that the public key is on disk, but the private key doesn't
   // exist.
@@ -154,9 +201,35 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_NE(result_observer_.Get<0>()->data(), ExtractBytes(signing_key));
-  EXPECT_TRUE(result_observer_.Get<1>()->key());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_NE(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
+}
+
+// Test that an owner user still gets recognized as the owner when it's
+// mentioned in the local state, but the device policies and the owner key were
+// lost. The key must be re-generated in such a case.
+TEST_F(OwnerKeyLoaderTest, OwnerUserRegeneratesMissingKeyBasedOnLocalState) {
+  // Populate local state.
+  user_manager_->RecordOwner(
+      AccountId::FromUserEmail(profile_->GetProfileUserName()));
+
+  policy::DevicePolicyBuilder policy_builder;
+  auto signing_key = policy_builder.GetSigningKey();
+
+  owner_key_util_->SetPublicKeyFromPrivateKey(*signing_key);
+
+  key_loader_->Run();
+
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  EXPECT_NE(result_observer_.Get<PublicKeyRefPtr>()->data(),
+            ExtractBytes(signing_key));
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
 }
 
 // Test that OwnerKeyLoader makes several attempts to generate the owner key
@@ -168,8 +241,10 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>()->is_empty());
-  EXPECT_TRUE(result_observer_.Get<1>()->key());
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  ASSERT_TRUE(result_observer_.Get<PrivateKeyRefPtr>());
+  EXPECT_TRUE(result_observer_.Get<PrivateKeyRefPtr>()->key());
 }
 
 // Test that OwnerKeyLoader gives up to generate the owner key pair after a
@@ -181,8 +256,31 @@
 
   key_loader_->Run();
 
-  EXPECT_FALSE(result_observer_.Get<0>());
-  EXPECT_FALSE(result_observer_.Get<1>());
+  EXPECT_FALSE(result_observer_.Get<PublicKeyRefPtr>());
+  EXPECT_FALSE(result_observer_.Get<PrivateKeyRefPtr>());
+}
+
+// Test that enterprise devices don't attempt to load private key. The signing
+// key of the device policy is owned by the backend server in the
+// enterprise-enrolled case.
+TEST_F(OwnerKeyLoaderTest, EnterpriseDevicesDontNeedPrivateKey) {
+  // Create favorable conditions for the code to load private key. Claim in the
+  // device policies that the user is the owner (shouldn't happen on a real
+  // device) and prepare a private key in case OwnerKeyLoader tries to load it.
+  auto signing_key = ConfigureExistingPolicies(profile_->GetProfileUserName());
+  owner_key_util_->ImportPrivateKeyAndSetPublicKey(signing_key->Copy());
+
+  // Re-create the loader with is_enterprise_enrolled=true.
+  key_loader_ = std::make_unique<OwnerKeyLoader>(
+      profile_.get(), &device_settings_service_, owner_key_util_,
+      /*is_enterprise_enrolled=*/true, result_observer_.GetCallback());
+
+  key_loader_->Run();
+
+  ASSERT_TRUE(result_observer_.Get<PublicKeyRefPtr>());
+  ASSERT_TRUE(!result_observer_.Get<PublicKeyRefPtr>()->is_empty());
+  // Check that the private key wasn't loaded.
+  EXPECT_FALSE(result_observer_.Get<PrivateKeyRefPtr>());
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer.cc
index 93954587..4e886b6b 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <utility>
 
+#include "base/check.h"
 #include "base/containers/contains.h"
 #include "base/containers/queue.h"
 #include "base/logging.h"
@@ -85,15 +86,13 @@
 void NetworkEventsObserver::OnSignalStrengthChanged(
     const std::string& guid,
     chromeos::network_health::mojom::UInt32ValuePtr signal_strength) {
+  DCHECK(signal_strength) << "Signal strength should have a value.";
+
   const auto* network_state = ::ash::NetworkHandler::Get()
                                   ->network_state_handler()
                                   ->GetNetworkStateFromGuid(guid);
-  if (signal_strength.is_null()) {
-    NOTREACHED() << "Signal strength is null";
-    return;
-  }
   if (!network_state) {
-    NOTREACHED() << "Could not find network state with guid " << guid;
+    DVLOG(1) << "Could not find network state with guid " << guid;
     return;
   }
 
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_unittest.cc
index 1a63ad1..3d7f7f3 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_unittest.cc
@@ -241,6 +241,22 @@
   ASSERT_FALSE(event_reported);
 }
 
+TEST_F(NetworkEventsObserverTest, SignalStrengthInvalidGuid) {
+  NetworkEventsObserver network_events_observer;
+  bool event_reported = false;
+  auto cb =
+      base::BindLambdaForTesting([&](MetricData) { event_reported = true; });
+
+  network_events_observer.SetOnEventObservedCallback(std::move(cb));
+  network_events_observer.SetReportingEnabled(/*is_enabled=*/true);
+  network_events_observer.OnSignalStrengthChanged(
+      "invalid_guid",
+      ::chromeos::network_health::mojom::UInt32Value::New(kSignalStrength));
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_FALSE(event_reported);
+}
+
 TEST_P(NetworkEventsObserverTest, ConnectionState) {
   const NetworkConnectionStateTestCase& test_case = GetParam();
 
diff --git a/chrome/browser/ash/settings/device_settings_service.cc b/chrome/browser/ash/settings/device_settings_service.cc
index b4eae676..a1ebe35 100644
--- a/chrome/browser/ash/settings/device_settings_service.cc
+++ b/chrome/browser/ash/settings/device_settings_service.cc
@@ -133,17 +133,6 @@
   }
 }
 
-void DeviceSettingsService::GetPolicyDataAsync(PolicyDataCallback callback) {
-  if (policy_data_) {
-    std::move(callback).Run(policy_data_.get());
-    return;
-  }
-
-  pending_policy_data_callbacks_.push_back(std::move(callback));
-  if (pending_operations_.empty())
-    EnqueueLoad(false);
-}
-
 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() {
   return public_key_;
 }
@@ -384,10 +373,6 @@
   NotifyDeviceSettingsUpdated();
   RunPendingOwnershipStatusCallbacks();
 
-  if ((status == STORE_SUCCESS) || (status == STORE_NO_POLICY)) {
-    RunPendingPolicyDataCallbacks();
-  }
-
   // The completion callback happens after the notification so clients can
   // filter self-triggered updates.
   if (!callback.is_null())
@@ -412,14 +397,6 @@
   }
 }
 
-void DeviceSettingsService::RunPendingPolicyDataCallbacks() {
-  std::vector<PolicyDataCallback> callbacks;
-  callbacks.swap(pending_policy_data_callbacks_);
-  for (auto& callback : callbacks) {
-    std::move(callback).Run(policy_data_.get());
-  }
-}
-
 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() {
   DeviceSettingsService::Initialize();
 }
diff --git a/chrome/browser/ash/settings/device_settings_service.h b/chrome/browser/ash/settings/device_settings_service.h
index cf3a391e..314bb3f 100644
--- a/chrome/browser/ash/settings/device_settings_service.h
+++ b/chrome/browser/ash/settings/device_settings_service.h
@@ -129,13 +129,6 @@
     return policy_data_.get();
   }
 
-  // Asynchronously return policy data. If Chrome doesn't have any policy data
-  // yet, it will enqueue a new policy load. The callback will be called on
-  // success or if policy loaded successfully, but it it was empty (i.e.
-  // STORE_NO_POLICY). If failed to load, the callback is expected to be called
-  // some time later on the next successful load (requested by something else).
-  void GetPolicyDataAsync(PolicyDataCallback callback);
-
   const enterprise_management::PolicyFetchResponse* policy_fetch_response()
       const {
     return policy_fetch_response_.get();
@@ -281,16 +274,12 @@
   // Processes pending callbacks from GetOwnershipStatusAsync().
   void RunPendingOwnershipStatusCallbacks();
 
-  // Processes pending callbacks from GetPolicyDataAsync().
-  void RunPendingPolicyDataCallbacks();
-
   SessionManagerClient* session_manager_client_ = nullptr;
   scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_;
 
   Status store_status_ = STORE_SUCCESS;
 
   std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;
-  std::vector<PolicyDataCallback> pending_policy_data_callbacks_;
 
   std::string username_;
   scoped_refptr<ownership::PublicKey> public_key_;
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc
index 41843ad..8aa4d07 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc
@@ -573,7 +573,7 @@
 }
 
 void PersonalizationAppAmbientProviderImpl::StartScreenSaverPreview() {
-  Shell::Get()->ambient_controller()->ShowUi();
+  Shell::Get()->ambient_controller()->StartScreenSaverPreview();
 }
 
 }  // namespace ash::personalization_app
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index eb6bf46..3a39fd8 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -216,8 +216,6 @@
        features::kAutofillPageLanguageDetection,
        // TODO(crbug.com/1165780): Remove once shared labels are launched.
        features::kAutofillEnableSupportForParsingWithSharedLabels,
-       // TODO(crbug.com/1190334): Remove once launched.
-       features::kAutofillParseMerchantPromoCodeFields,
        // TODO(crbug.com/1335549): Remove once launched.
        features::kAutofillParseIBANFields,
        // TODO(crbug.com/1341387): Remove once launched.
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index 4a4754b..8a5bedf 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -35,8 +35,10 @@
 #include "components/webapps/browser/installable/installable_logging.h"
 #include "components/webapps/browser/installable/installable_manager.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
+#include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/common/content_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/fenced_frame_test_util.h"
@@ -732,8 +734,7 @@
 }
 
 class AppBannerManagerBrowserTestWithChromeBFCache
-    : public AppBannerManagerBrowserTest,
-      public testing::WithParamInterface<bool> {
+    : public AppBannerManagerBrowserTest {
  public:
   AppBannerManagerBrowserTestWithChromeBFCache() = default;
   ~AppBannerManagerBrowserTestWithChromeBFCache() override = default;
@@ -758,13 +759,6 @@
     // Allow BackForwardCache for all devices regardless of their memory.
     DisableFeature(::features::kBackForwardCacheMemoryControls);
 
-    if (GetParam()) {
-      EnableFeatureAndSetParams(blink::features::kBackForwardCacheAppBanner, "",
-                                "");
-    } else {
-      DisableFeature(blink::features::kBackForwardCacheAppBanner);
-    }
-
     SetupFeaturesAndParameters();
   }
 
@@ -801,15 +795,15 @@
     return embedded_test_server()->GetURL("/banners/nested_sw_test_page.html");
   }
 
-  bool IsBackForwardCacheAppBannerEnabled() {
-    return base::FeatureList::IsEnabled(
-        blink::features::kBackForwardCacheAppBanner);
+  bool IsRenderHostStoredInBackForwardCache(content::RenderFrameHost* rfh) {
+    return rfh->IsInLifecycleState(
+        content::RenderFrameHost::LifecycleState::kInBackForwardCache);
   }
 
-  bool IsRenderHostStoredInBackForwardCache(
-      content::RenderFrameHost::LifecycleState state) {
-    return state ==
-           content::RenderFrameHost::LifecycleState::kInBackForwardCache;
+  void AssertBackForwardCacheIsUsedAsExpected(
+      const content::RenderFrameHostWrapper& rfh) {
+    ASSERT_EQ(IsRenderHostStoredInBackForwardCache(rfh.get()),
+              content::BackForwardCache::IsBackForwardCacheFeatureEnabled());
   }
 
  private:
@@ -819,8 +813,8 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_P(AppBannerManagerBrowserTestWithChromeBFCache,
-                       VerifyBFCacheBehaviorWithFlag) {
+IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTestWithChromeBFCache,
+                       VerifyBFCacheBehavior) {
   ASSERT_TRUE(embedded_test_server()->Start());
   std::unique_ptr<AppBannerManagerTest> manager(
       CreateAppBannerManager(browser()));
@@ -831,7 +825,7 @@
                                   /*expected_will_show=*/false,
                                   State::PENDING_PROMPT_NOT_CANCELED);
   content::RenderFrameHostWrapper rfh_a(current_frame_host());
-  EXPECT_EQ(manager->state(),
+  ASSERT_EQ(manager->state(),
             AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED);
   histograms.ExpectTotalCount(kInstallableStatusCodeHistogram, 0);
 
@@ -840,39 +834,27 @@
   TriggerBannerFlowWithNavigation(browser(), manager.get(),
                                   Get2ndInstallableURL(),
                                   /*expected_will_show=*/false, absl::nullopt);
+  AssertBackForwardCacheIsUsedAsExpected(rfh_a);
+
   content::RenderFrameHostWrapper rfh_b(current_frame_host());
 
-  EXPECT_EQ(IsRenderHostStoredInBackForwardCache(rfh_a->GetLifecycleState()),
-            IsBackForwardCacheAppBannerEnabled());
-
-  // Navigate backward.
+  // Navigate backward to 1st installable URL.
   web_contents()->GetController().GoBack();
-  EXPECT_TRUE(content::WaitForLoadStop(web_contents()));
+  ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
   // Verify pipeline has been triggered for new page load.
   EXPECT_NE(manager->state(), AppBannerManager::State::INACTIVE);
 
-  // Depending on whether kBackForwardCacheAppBanner is enabled or disabled, the
-  // corresponding RenderFrameHost will also be either stored in the
-  // BackForwardCache or not.
-  EXPECT_EQ(IsRenderHostStoredInBackForwardCache(rfh_b->GetLifecycleState()),
-            IsBackForwardCacheAppBannerEnabled());
+  AssertBackForwardCacheIsUsedAsExpected(rfh_b);
 
-  // Navigate forward.
+  // Navigate forward to 2nd installable URL.
   web_contents()->GetController().GoForward();
-  EXPECT_TRUE(content::WaitForLoadStop(web_contents()));
+  ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
   // Verify pipeline has been triggered for new page load.
   EXPECT_NE(manager->state(), AppBannerManager::State::INACTIVE);
 
-  // Navigating back to B, A should either be stored in the BFCache or not
-  // depending on whether kBackForwardCacheAppBanner is enabled or disabled.
-  EXPECT_EQ(IsRenderHostStoredInBackForwardCache(rfh_a->GetLifecycleState()),
-            IsBackForwardCacheAppBannerEnabled());
+  AssertBackForwardCacheIsUsedAsExpected(rfh_a);
 }
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         AppBannerManagerBrowserTestWithChromeBFCache,
-                         ::testing::Bool());
-
 namespace {
 class FailingInstallableManager : public InstallableManager {
  public:
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index 0121568..0e52a00 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -146,6 +146,29 @@
 #endif
 );
 
+#if BUILDFLAG(IS_CHROMEOS)
+// If enabled, a blue border is drawn around shared tabs on ChromeOS.
+// If disabled, the blue border is not used on ChromeOS.
+//
+// Motivation:
+//  The blue border behavior used to cause problems on ChromeOS - see
+//  crbug.com/1320262 for Ash (fixed) and crbug.com/1030925 for Lacros
+//  (relatively old bug -- we would like to observe whether it's still
+//  there). This flag is introduced as means of disabling this feature in case
+//  of possible future regressions.
+//
+// TODO(crbug.com/1251999): Remove this flag once we confirm that blue border
+// works fine on ChromeOS.
+BASE_FEATURE(kTabCaptureBlueBorderCrOS,
+             "TabCaptureBlueBorderCrOS",
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+             base::FEATURE_ENABLED_BY_DEFAULT
+#else
+             base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+);
+#endif
+
 // Enables runtime detection of USB devices which provide a WebUSB landing page
 // descriptor.
 BASE_FEATURE(kWebUsbDeviceDetection,
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index aaa0292..7f030ca 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -55,6 +55,10 @@
 BASE_DECLARE_FEATURE(kSandboxExternalProtocolBlockedWarning);
 BASE_DECLARE_FEATURE(kTriggerNetworkDataMigration);
 
+#if BUILDFLAG(IS_CHROMEOS)
+BASE_DECLARE_FEATURE(kTabCaptureBlueBorderCrOS);
+#endif
+
 BASE_DECLARE_FEATURE(kWebUsbDeviceDetection);
 
 #if BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 8fc35f65..980b89ee 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1219,35 +1219,33 @@
     // that initialize a ScopedFeatureList in their constructors can do so
     // before the code below potentially kicks off tasks on other threads that
     // check if a feature is enabled, to avoid tsan data races.
-    TestingProfile::Builder profile_builder;
-    profile_builder.AddTestingFactory(
-        StatefulSSLHostStateDelegateFactory::GetInstance(),
-        StatefulSSLHostStateDelegateFactory::GetDefaultFactoryForTesting());
-    profile_builder.AddTestingFactory(
-        BookmarkModelFactory::GetInstance(),
-        BookmarkModelFactory::GetDefaultFactory());
-    profile_builder.AddTestingFactory(
-        HistoryServiceFactory::GetInstance(),
-        HistoryServiceFactory::GetDefaultFactory());
-    profile_builder.AddTestingFactory(
-        FaviconServiceFactory::GetInstance(),
-        FaviconServiceFactory::GetDefaultFactory());
-    profile_builder.AddTestingFactory(
-        SpellcheckServiceFactory::GetInstance(),
-        base::BindRepeating([](content::BrowserContext* profile)
-                                -> std::unique_ptr<KeyedService> {
-          return std::make_unique<SpellcheckService>(
-              static_cast<Profile*>(profile));
-        }));
-    profile_builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
-                                      SyncServiceFactory::GetDefaultFactory());
-    profile_builder.AddTestingFactory(
-        ChromeSigninClientFactory::GetInstance(),
-        base::BindRepeating(&signin::BuildTestSigninClient));
-    profile_builder.AddTestingFactory(
-        WebDataServiceFactory::GetInstance(),
-        WebDataServiceFactory::GetDefaultFactory());
-    profile_ = profile_builder.Build();
+    profile_ =
+        TestingProfile::Builder()
+            .AddTestingFactory(
+                StatefulSSLHostStateDelegateFactory::GetInstance(),
+                StatefulSSLHostStateDelegateFactory::
+                    GetDefaultFactoryForTesting())
+            .AddTestingFactory(BookmarkModelFactory::GetInstance(),
+                               BookmarkModelFactory::GetDefaultFactory())
+            .AddTestingFactory(HistoryServiceFactory::GetInstance(),
+                               HistoryServiceFactory::GetDefaultFactory())
+            .AddTestingFactory(FaviconServiceFactory::GetInstance(),
+                               FaviconServiceFactory::GetDefaultFactory())
+            .AddTestingFactory(
+                SpellcheckServiceFactory::GetInstance(),
+                base::BindRepeating([](content::BrowserContext* profile)
+                                        -> std::unique_ptr<KeyedService> {
+                  return std::make_unique<SpellcheckService>(
+                      static_cast<Profile*>(profile));
+                }))
+            .AddTestingFactory(SyncServiceFactory::GetInstance(),
+                               SyncServiceFactory::GetDefaultFactory())
+            .AddTestingFactory(
+                ChromeSigninClientFactory::GetInstance(),
+                base::BindRepeating(&signin::BuildTestSigninClient))
+            .AddTestingFactory(WebDataServiceFactory::GetInstance(),
+                               WebDataServiceFactory::GetDefaultFactory())
+            .Build();
 
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_LACROS)
     web_app_provider_ = web_app::FakeWebAppProvider::Get(profile_.get());
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index a85624b9..5119a034 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2410,14 +2410,6 @@
 #endif
 }
 
-bool ChromeContentBrowserClient::IsIsolatedWebAppsDeveloperModeAllowed(
-    content::BrowserContext* context) {
-  Profile* profile = Profile::FromBrowserContext(context);
-  return profile &&
-         profile->GetPrefs()->GetBoolean(
-             policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed);
-}
-
 bool ChromeContentBrowserClient::IsGetDisplayMediaSetSelectAllScreensAllowed(
     content::BrowserContext* context,
     const url::Origin& origin) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 6e2f9c3..861ee43 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -240,8 +240,6 @@
       bool origin_matches_flag) override;
   bool IsIsolatedContextAllowedForUrl(content::BrowserContext* browser_context,
                                       const GURL& lock_url) override;
-  bool IsIsolatedWebAppsDeveloperModeAllowed(
-      content::BrowserContext* context) override;
   bool IsGetDisplayMediaSetSelectAllScreensAllowed(
       content::BrowserContext* context,
       const url::Origin& origin) override;
diff --git a/chrome/browser/dips/dips_database.cc b/chrome/browser/dips/dips_database.cc
index 6436f7a..8adc5a0 100644
--- a/chrome/browser/dips/dips_database.cc
+++ b/chrome/browser/dips/dips_database.cc
@@ -38,6 +38,11 @@
 
 }  // namespace
 
+// See comments at declaration of these variables in dips_database.h
+// for details.
+
+const base::TimeDelta DIPSDatabase::kMaxAge = base::Days(180);
+
 DIPSDatabase::DIPSDatabase(const absl::optional<base::FilePath>& db_path)
     : db_path_(db_path.value_or(base::FilePath())),
       db_(std::make_unique<sql::Database>(
@@ -224,6 +229,22 @@
                                    ToOptionalTime(statement.ColumnTime(8))}};
 }
 
+std::vector<std::string> DIPSDatabase::GetAllSitesForTesting() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  static constexpr char kReadSql[] =  // clang-format off
+      "SELECT site FROM bounces ORDER BY site";
+  // clang-format on
+
+  DCHECK(db_->IsSQLValid(kReadSql));
+  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kReadSql));
+
+  std::vector<std::string> sites;
+  while (statement.Step()) {
+    sites.push_back(statement.ColumnString(0));
+  }
+  return sites;
+}
+
 std::vector<std::string> DIPSDatabase::GetSitesThatBounced(
     base::Time range_start,
     base::Time last_interaction) const {
@@ -324,9 +345,12 @@
   DCHECK(db_->is_open());
 
   sql::Transaction transaction(db_.get());
+  if (!transaction.Begin())
+    return false;
 
-  if (!transaction.Begin() ||
-      !ClearTimestamps(delete_begin, delete_end, type) ||
+  GarbageCollect();
+
+  if (!ClearTimestamps(delete_begin, delete_end, type) ||
       !AdjustFirstTimestamps(delete_begin, delete_end, type) ||
       !AdjustLastTimestamps(delete_begin, delete_end, type))
     return false;
@@ -637,3 +661,77 @@
 
   return true;
 }
+
+size_t DIPSDatabase::GetEntryCount() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  sql::Statement s_entry_count(
+      db_->GetCachedStatement(SQL_FROM_HERE, "SELECT COUNT(*) FROM bounces"));
+  return (s_entry_count.Step() ? s_entry_count.ColumnInt(0) : 0);
+}
+
+size_t DIPSDatabase::GarbageCollect() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  size_t num_entries = GetEntryCount();
+  size_t num_deleted = 0;
+  int purge_goal = num_entries - (max_entries_ - purge_entries_);
+
+  if (num_entries <= max_entries_)
+    return 0;
+
+  DCHECK_GT(purge_goal, 0);
+  num_deleted += GarbageCollectExpired();
+
+  // If expiration did not purge enough entries, remove entries with the oldest
+  // |last_user_interaction_time| until the |purge_goal| is satisfied.
+  if (num_deleted < static_cast<size_t>(purge_goal)) {
+    num_deleted += GarbageCollectOldest(purge_goal - num_deleted);
+  }
+
+  return num_deleted;
+}
+
+size_t DIPSDatabase::GarbageCollectExpired() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  base::Time safe_date(base::Time::Now() - kMaxAge);
+
+  static constexpr char kExpireByInteractionSql[] =  // clang-format off
+        "DELETE FROM bounces WHERE last_user_interaction_time<? AND "
+                                  "last_user_interaction_time>0";
+  // clang-format on
+  DCHECK(db_->IsSQLValid(kExpireByInteractionSql));
+
+  sql::Statement s_expire_by_interaction(
+      db_->GetCachedStatement(SQL_FROM_HERE, kExpireByInteractionSql));
+  s_expire_by_interaction.BindTime(0, safe_date);
+
+  if (!s_expire_by_interaction.Run())
+    return 0;
+
+  return db_->GetLastChangeCount();
+}
+
+size_t DIPSDatabase::GarbageCollectOldest(int purge_goal) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  static constexpr char kGarbageCollectOldestSql[] =  // clang-format off
+      "DELETE FROM bounces WHERE site "
+          "IN(SELECT site FROM bounces "
+              "ORDER BY "
+                  "MAX(last_user_interaction_time,last_site_storage_time) ASC,"
+                      "last_site_storage_time ASC "
+              "LIMIT ?)";
+  // clang-format on
+  DCHECK(db_->IsSQLValid(kGarbageCollectOldestSql));
+
+  sql::Statement s_garbage_collect_oldest(
+      db_->GetCachedStatement(SQL_FROM_HERE, kGarbageCollectOldestSql));
+  s_garbage_collect_oldest.BindInt(0, purge_goal);
+
+  if (!s_garbage_collect_oldest.Run())
+    return 0;
+
+  return db_->GetLastChangeCount();
+}
diff --git a/chrome/browser/dips/dips_database.h b/chrome/browser/dips/dips_database.h
index 63e6c66..517eafd48 100644
--- a/chrome/browser/dips/dips_database.h
+++ b/chrome/browser/dips/dips_database.h
@@ -21,6 +21,13 @@
 // Encapsulates an SQL database that holds DIPS info.
 class DIPSDatabase {
  public:
+  // The length of time since last user interaction or site storage that a
+  // site's entry will not be subject to garbage collection due to expiration.
+  // However, even with interaction or storage within this period, if there are
+  // more than |max_entries_| entries, an entry can still be deleted by
+  // |GarbageCollectOldest()|.
+  static const base::TimeDelta kMaxAge;
+
   // Passing in an absl::nullopt `db_path` causes the db to be created in
   // memory. Init() must be called before using the DIPSDatabase to make sure it
   // is initialized.
@@ -46,6 +53,8 @@
 
   absl::optional<StateValue> Read(const std::string& site);
 
+  std::vector<std::string> GetAllSitesForTesting() const;
+
   // Returns all sites that did a bounce after |range_start| with their last
   // interaction happening before |last_interaction|.
   //
@@ -78,8 +87,31 @@
                           const base::Time& delete_end,
                           const DIPSEventRemovalType type);
 
+  // Returns the number of entries present in the database.
+  size_t GetEntryCount() const;
+
+  // If the number of entries in the database is greater than
+  // |GetMaxEntries()|, garbage collect. Returns the number of entries deleted
+  // (useful for debugging).
+  size_t GarbageCollect();
+
+  // Removes entries for sites without user interaction or site storage within
+  // |kMaxAge|. Returns the number of entries deleted.
+  size_t GarbageCollectExpired();
+
+  // Removes the |purge_goal| entries with the oldest
+  // |MAX(last_user_interaction_time,last_site_storage_time)| value. Returns the
+  // number of entries deleted.
+  size_t GarbageCollectOldest(int purge_goal);
+
   bool in_memory() const { return db_path_.empty(); }
 
+  size_t GetMaxEntries() const { return max_entries_; }
+  size_t GetPurgeEntries() const { return purge_entries_; }
+
+  void SetMaxEntriesForTesting(size_t entries) { max_entries_ = entries; }
+  void SetPurgeEntriesForTesting(size_t entries) { purge_entries_ = entries; }
+
  protected:
   // Initialization functions --------------------------------------------------
   sql::InitStatus OpenDatabase();
@@ -101,6 +133,10 @@
   // Callback for database errors.
   void DatabaseErrorCallback(int extended_error, sql::Statement* stmt);
 
+  // When the number of entries in the database exceeds |max_entries_|, purge
+  // down to |max_entries_| - |purge_entries_|.
+  size_t max_entries_ = 3500;
+  size_t purge_entries_ = 300;
   const base::FilePath db_path_;
   std::unique_ptr<sql::Database> db_ GUARDED_BY_CONTEXT(sequence_checker_);
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/browser/dips/dips_database_unittest.cc b/chrome/browser/dips/dips_database_unittest.cc
index e47839e..ea8965b 100644
--- a/chrome/browser/dips/dips_database_unittest.cc
+++ b/chrome/browser/dips/dips_database_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/strings/strcat.h"
 #include "base/test/gtest_util.h"
 #include "chrome/browser/dips/dips_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -382,3 +383,145 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(All, DIPSDatabaseQueryTest, ::testing::Bool());
+
+// A test class that verifies DIPSDatabase garbage collection behavior.
+class DIPSDatabaseGarbageCollectionTest
+    : public DIPSDatabaseTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  DIPSDatabaseGarbageCollectionTest() : DIPSDatabaseTest(true) {}
+
+  void SetUp() override {
+    DIPSDatabaseTest::SetUp();
+
+    DCHECK(db_);
+
+    db_->SetMaxEntriesForTesting(200);
+    db_->SetPurgeEntriesForTesting(20);
+
+    recent_interaction = Time::Now();
+    old_interaction = Time::Now() - DIPSDatabase::kMaxAge - base::Days(1);
+
+    recent_interaction_times = {recent_interaction, recent_interaction};
+    old_interaction_times = {old_interaction, old_interaction};
+  }
+
+  void BloatBouncesForGC(int num_recent_entries, int num_old_entries) {
+    DCHECK(db_);
+
+    for (int i = 0; i < num_recent_entries; i++) {
+      db_->Write(base::StrCat({"https://recent_interaction.test",
+                               base::NumberToString(i)}),
+                 storage_times, recent_interaction_times, stateful_bounce_times,
+                 stateless_bounce_times);
+    }
+
+    for (int i = 0; i < num_old_entries; i++) {
+      db_->Write(base::StrCat(
+                     {"https://old_interaction.test", base::NumberToString(i)}),
+                 storage_times, old_interaction_times, stateful_bounce_times,
+                 stateless_bounce_times);
+    }
+  }
+
+  base::Time recent_interaction;
+  base::Time old_interaction;
+  base::Time storage = Time::FromDoubleT(2);
+  base::Time stateful_bounce = Time::FromDoubleT(3);
+  base::Time stateless_bounce = Time::FromDoubleT(4);
+
+  TimestampRange recent_interaction_times;
+  TimestampRange old_interaction_times;
+  TimestampRange storage_times = {storage, storage};
+  TimestampRange stateful_bounce_times = {stateful_bounce, stateful_bounce};
+  TimestampRange stateless_bounce_times = {stateless_bounce, stateless_bounce};
+};
+
+// More than |max_entries_| entries with recent user interaction; garbage
+// collection should purge down to |max_entries_| - |purge_entries_| entries.
+TEST_P(DIPSDatabaseGarbageCollectionTest, RemovesRecentOverMax) {
+  BloatBouncesForGC(/*num_recent_entries=*/db_->GetMaxEntries() * 2,
+                    /*num_old_entries=*/0);
+
+  EXPECT_EQ(db_->GarbageCollect(),
+            db_->GetMaxEntries() + db_->GetPurgeEntries());
+
+  EXPECT_EQ(db_->GetEntryCount(),
+            db_->GetMaxEntries() - db_->GetPurgeEntries());
+}
+
+// Less than |max_entries_| entries, some with expired user interaction and some
+// with recent; no entries should be garbage collected.
+TEST_P(DIPSDatabaseGarbageCollectionTest, PreservesUnderMax) {
+  BloatBouncesForGC(
+      /*num_recent_entries=*/(db_->GetMaxEntries() - db_->GetPurgeEntries()) /
+          4,
+      /*num_old_entries=*/(db_->GetMaxEntries() - db_->GetPurgeEntries()) / 4);
+
+  EXPECT_EQ(db_->GarbageCollect(), static_cast<size_t>(0));
+
+  EXPECT_EQ(db_->GetEntryCount(),
+            (db_->GetMaxEntries() - db_->GetPurgeEntries()) / 2);
+}
+
+// Exactly |max_entries_| entries, some with expired user interaction and some
+// with recent; no entries should be garbage collected.
+TEST_P(DIPSDatabaseGarbageCollectionTest, PreservesMax) {
+  BloatBouncesForGC(/*num_recent_entries=*/db_->GetMaxEntries() / 2,
+                    /*num_old_entries=*/db_->GetMaxEntries() / 2);
+
+  EXPECT_EQ(db_->GarbageCollect(), static_cast<size_t>(0));
+
+  EXPECT_EQ(db_->GetEntryCount(), db_->GetMaxEntries());
+}
+
+// More than |max_entries_| entries with recent user interaction and a few with
+// expired user interaction; only entries with expired user interaction should
+// be garbage collected by pure expiration.
+TEST_P(DIPSDatabaseGarbageCollectionTest, ExpirationPreservesRecent) {
+  BloatBouncesForGC(/*num_recent_entries=*/db_->GetMaxEntries() * 2,
+                    /*num_old_entries=*/db_->GetMaxEntries() / 2);
+
+  EXPECT_EQ(db_->GarbageCollectExpired(), db_->GetMaxEntries() / 2);
+
+  EXPECT_EQ(db_->GetEntryCount(), db_->GetMaxEntries() * 2);
+}
+
+// The entries with the oldest interaction and storage times should be deleted
+// first.
+TEST_P(DIPSDatabaseGarbageCollectionTest, OldestEntriesRemoved) {
+  db_->Write("https://old_interaction.test", {},
+             /*interaction_times=*/{Time::FromDoubleT(1), Time::FromDoubleT(1)},
+             {}, {});
+  db_->Write("https://old_storage_old_interaction.test",
+             /*storage_times=*/{Time::FromDoubleT(1), Time::FromDoubleT(1)},
+             /*interaction_times=*/{Time::FromDoubleT(2), Time::FromDoubleT(2)},
+             {}, {});
+  db_->Write("https://old_storage.test",
+             /*storage_times=*/{Time::FromDoubleT(3), Time::FromDoubleT(3)}, {},
+             {}, {});
+  db_->Write("https://old_storage_new_interaction.test",
+             /*storage_times=*/{Time::FromDoubleT(1), Time::FromDoubleT(1)},
+             /*interaction_times=*/{Time::FromDoubleT(4), Time::FromDoubleT(4)},
+             {}, {});
+  db_->Write("https://new_storage_old_interaction.test",
+             /*storage_times=*/{Time::FromDoubleT(5), Time::FromDoubleT(5)},
+             /*interaction_times=*/{Time::FromDoubleT(2), Time::FromDoubleT(2)},
+             {}, {});
+  db_->Write("https://new_storage_new_interaction.test",
+             /*storage_times=*/{Time::FromDoubleT(6), Time::FromDoubleT(6)},
+             /*interaction_times=*/{Time::FromDoubleT(7), Time::FromDoubleT(7)},
+             {}, {});
+
+  EXPECT_EQ(db_->GarbageCollectOldest(3), static_cast<size_t>(3));
+  EXPECT_EQ(db_->GetEntryCount(), static_cast<size_t>(3));
+
+  EXPECT_THAT(db_->GetAllSitesForTesting(),
+              testing::ElementsAre("https://new_storage_new_interaction.test",
+                                   "https://new_storage_old_interaction.test",
+                                   "https://old_storage_new_interaction.test"));
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         DIPSDatabaseGarbageCollectionTest,
+                         ::testing::Bool());
diff --git a/chrome/browser/dips/dips_helper_browsertest.cc b/chrome/browser/dips/dips_helper_browsertest.cc
index 46696e1..4f5b457 100644
--- a/chrome/browser/dips/dips_helper_browsertest.cc
+++ b/chrome/browser/dips/dips_helper_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/browsing_data/browsing_data_important_sites_util.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
+#include "chrome/browser/dips/dips_features.h"
 #include "chrome/browser/dips/dips_service.h"
 #include "chrome/browser/dips/dips_service_factory.h"
 #include "chrome/browser/dips/dips_storage.h"
@@ -85,8 +86,17 @@
 
 }  // namespace
 
-class DIPSTabHelperBrowserTest : public InProcessBrowserTest {
+class DIPSTabHelperBrowserTest : public InProcessBrowserTest,
+                                 public testing::WithParamInterface<bool> {
  protected:
+  void SetUp() override {
+    if (IsPersistentStorageEnabled()) {
+      scoped_feature_list_.InitAndEnableFeatureWithParameters(
+          dips::kFeature, {{"persist_database", "true"}});
+    }
+    InProcessBrowserTest::SetUp();
+  }
+
   void SetUpCommandLine(base::CommandLine* command_line) override {
     // Prevents flakiness by handling clicks even before content is drawn.
     command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
@@ -142,11 +152,16 @@
     return state;
   }
 
+  bool IsPersistentStorageEnabled() { return GetParam(); }
+
  private:
   base::SimpleTestClock test_clock_;
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+INSTANTIATE_TEST_SUITE_P(All, DIPSTabHelperBrowserTest, ::testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        InteractionsRecordedInAncestorFrames) {
   GURL url_a = embedded_test_server()->GetURL("a.test", "/iframe_blank.html");
   GURL url_b = embedded_test_server()->GetURL("b.test", "/title1.html");
@@ -201,7 +216,7 @@
   EXPECT_FALSE(GetDIPSState(url_b).has_value());
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        MultipleUserInteractionsRecorded) {
   GURL url = embedded_test_server()->GetURL("a.test", "/title1.html");
   base::Time time = base::Time::FromDoubleT(1);
@@ -245,7 +260,7 @@
             state_2->user_interaction_times.last);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, StorageRecordedInSingleFrame) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, StorageRecordedInSingleFrame) {
   // We host the iframe content on an HTTPS server, because for it to write a
   // cookie, the cookie needs to be SameSite=None and Secure.
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
@@ -288,7 +303,7 @@
   EXPECT_FALSE(state_b.has_value());
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, MultipleSiteStoragesRecorded) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, MultipleSiteStoragesRecorded) {
   GURL url = embedded_test_server()->GetURL("a.test", "/set-cookie?foo=bar");
   base::Time time = base::Time::FromDoubleT(1);
 
@@ -320,7 +335,7 @@
             state_2->site_storage_times.last);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, Histograms_StorageThenClick) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, Histograms_StorageThenClick) {
   base::HistogramTester histograms;
   GURL url = embedded_test_server()->GetURL("a.test", "/set-cookie?foo=bar");
   base::Time time = base::Time::FromDoubleT(1);
@@ -348,7 +363,7 @@
   histograms.ExpectUniqueTimeSample(kTimeToInteraction, base::Seconds(10), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        Histograms_StorageThenClick_Incognito) {
   base::HistogramTester histograms;
   GURL url = embedded_test_server()->GetURL("a.test", "/set-cookie?foo=bar");
@@ -383,7 +398,7 @@
                                     base::Seconds(10), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, Histograms_ClickThenStorage) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, Histograms_ClickThenStorage) {
   base::HistogramTester histograms;
   base::Time time = base::Time::FromDoubleT(1);
   content::WebContents* web_contents = GetActiveWebContents();
@@ -414,7 +429,7 @@
   histograms.ExpectUniqueTimeSample(kTimeToStorage, base::Seconds(10), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        Histograms_MultipleStoragesThenClick) {
   base::HistogramTester histograms;
   GURL url = embedded_test_server()->GetURL("a.test", "/set-cookie?foo=bar");
@@ -460,7 +475,7 @@
   histograms.ExpectUniqueTimeSample(kTimeToInteraction, base::Seconds(10), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        Histograms_MultipleClicksThenStorage) {
   base::HistogramTester histograms;
   GURL url = embedded_test_server()->GetURL("a.test", "/title1.html");
@@ -514,14 +529,14 @@
   histograms.ExpectUniqueTimeSample(kTimeToStorage, base::Seconds(7), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, PRE_PrepopulateTest) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, PRE_PrepopulateTest) {
   // Simulate the user typing the URL to visit the page, which will record site
   // engagement.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("a.test", "/title1.html")));
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest, PrepopulateTest) {
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest, PrepopulateTest) {
   // Since there was previous site engagement, the DIPS DB should be
   // prepopulated with a user interaction timestamp.
   auto state = GetDIPSState(GURL("http://a.test"));
@@ -529,7 +544,7 @@
   EXPECT_TRUE(state->user_interaction_times.first.has_value());
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        PRE_ChromeBrowsingDataRemover_Basic) {
   // Simulate the user typing the URL to visit the page, which will record site
   // engagement.
@@ -537,7 +552,7 @@
       browser(), embedded_test_server()->GetURL("a.test", "/title1.html")));
 }
 
-IN_PROC_BROWSER_TEST_F(DIPSTabHelperBrowserTest,
+IN_PROC_BROWSER_TEST_P(DIPSTabHelperBrowserTest,
                        ChromeBrowsingDataRemover_Basic) {
   base::Time time = base::Time::Now();
   uint64_t remove_mask = chrome_browsing_data_remover::DATA_TYPE_HISTORY |
diff --git a/chrome/browser/dips/dips_service.cc b/chrome/browser/dips/dips_service.cc
index 265fbbdf..5e4a814b 100644
--- a/chrome/browser/dips/dips_service.cc
+++ b/chrome/browser/dips/dips_service.cc
@@ -6,6 +6,7 @@
 
 #include <set>
 
+#include "base/files/file_path.h"
 #include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/thread_pool.h"
@@ -54,9 +55,16 @@
           Profile::FromBrowserContext(context))),
       repeating_timer_(CreateTimer(Profile::FromBrowserContext(context))),
       storage_(base::SequenceBound<DIPSStorage>(CreateTaskRunner())) {
-  // TODO(crbug.com/1342228): Persist DB to disk for non-OTR profiles.
-  storage_.AsyncCall(&DIPSStorage::Init).WithArgs(absl::nullopt);
-  // TODO(rtarpine): Prevent use of the DB until prepopulation starts.
+  absl::optional<base::FilePath> path;
+
+  if (base::FeatureList::IsEnabled(dips::kFeature) &&
+      dips::kPersistedDatabaseEnabled.Get() &&
+      !browser_context_->IsOffTheRecord()) {
+    path = browser_context_->GetPath().Append(kDIPSFilename);
+  }
+
+  storage_.AsyncCall(&DIPSStorage::Init).WithArgs(path);
+  // TODO: Prevent use of the DB until prepopulation starts.
   InitializeStorageWithEngagedSites();
   if (repeating_timer_)
     repeating_timer_->Start();
diff --git a/chrome/browser/dips/dips_utils.h b/chrome/browser/dips/dips_utils.h
index faaa340..7de35e0 100644
--- a/chrome/browser/dips/dips_utils.h
+++ b/chrome/browser/dips/dips_utils.h
@@ -7,6 +7,7 @@
 
 #include <ostream>
 
+#include "base/files/file_path.h"
 #include "base/strings/string_piece_forward.h"
 #include "base/time/time.h"
 #include "services/network/public/mojom/cookie_access_observer.mojom.h"
@@ -22,6 +23,11 @@
 // read+write.
 using CookieOperation = network::mojom::CookieAccessDetails::Type;
 
+// Constants:
+// The filename for the DIPS database.
+const base::FilePath::CharType kDIPSFilename[] = FILE_PATH_LITERAL("DIPS");
+
+// CookieAccessType:
 // NOTE: We use this type as a bitfield, and will soon be logging it. Don't
 // change the values or add additional members.
 enum class CookieAccessType {
diff --git a/chrome/browser/enterprise/connectors/enterprise_connectors_policy_handler_unittest.cc b/chrome/browser/enterprise/connectors/enterprise_connectors_policy_handler_unittest.cc
index 03e4ce9..82729cf 100644
--- a/chrome/browser/enterprise/connectors/enterprise_connectors_policy_handler_unittest.cc
+++ b/chrome/browser/enterprise/connectors/enterprise_connectors_policy_handler_unittest.cc
@@ -259,8 +259,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
                                      kOnFileTransferPref,
 #endif
-                                     kOnSecurityEventPref,
-                                     kSendDownloadToCloudPref),
+                                     kOnSecurityEventPref),
                      testing::Bool()));
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc
index 589c74b..f174c08 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -595,15 +595,13 @@
 ExtensionFunction::ResponseAction CookiesGetAllCookieStoresFunction::Run() {
   Profile* original_profile = Profile::FromBrowserContext(browser_context());
   DCHECK(original_profile);
-  std::unique_ptr<base::ListValue> original_tab_ids(new base::ListValue());
+  base::Value::List original_tab_ids;
   Profile* incognito_profile = nullptr;
-  std::unique_ptr<base::ListValue> incognito_tab_ids;
+  base::Value::List incognito_tab_ids;
   if (include_incognito_information() &&
       original_profile->HasPrimaryOTRProfile()) {
     incognito_profile =
         original_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
-    if (incognito_profile)
-      incognito_tab_ids = std::make_unique<base::ListValue>();
   }
   DCHECK(original_profile != incognito_profile);
 
@@ -612,20 +610,18 @@
   // whether the browser is regular or incognito.
   for (auto* browser : *BrowserList::GetInstance()) {
     if (browser->profile() == original_profile) {
-      cookies_helpers::AppendToTabIdList(browser, original_tab_ids.get());
-    } else if (incognito_tab_ids.get() &&
-               browser->profile() == incognito_profile) {
-      cookies_helpers::AppendToTabIdList(browser, incognito_tab_ids.get());
+      cookies_helpers::AppendToTabIdList(browser, original_tab_ids);
+    } else if (browser->profile() == incognito_profile) {
+      cookies_helpers::AppendToTabIdList(browser, incognito_tab_ids);
     }
   }
   // Return a list of all cookie stores with at least one open tab.
   std::vector<api::cookies::CookieStore> cookie_stores;
-  if (original_tab_ids->GetList().size() > 0) {
+  if (!original_tab_ids.empty()) {
     cookie_stores.push_back(cookies_helpers::CreateCookieStore(
         original_profile, std::move(original_tab_ids)));
   }
-  if (incognito_tab_ids.get() && incognito_tab_ids->GetList().size() > 0 &&
-      incognito_profile) {
+  if (incognito_profile && !incognito_tab_ids.empty()) {
     cookie_stores.push_back(cookies_helpers::CreateCookieStore(
         incognito_profile, std::move(incognito_tab_ids)));
   }
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
index e10fb62..f6944113 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
@@ -132,18 +132,14 @@
   return cookie;
 }
 
-CookieStore CreateCookieStore(Profile* profile,
-                              std::unique_ptr<base::ListValue> tab_ids) {
+CookieStore CreateCookieStore(Profile* profile, base::Value::List tab_ids) {
   DCHECK(profile);
-  DCHECK(tab_ids);
-  base::DictionaryValue dict;
-  dict.SetStringKey(cookies_api_constants::kIdKey,
-                    GetStoreIdFromProfile(profile));
-  dict.SetKey(cookies_api_constants::kTabIdsKey,
-              base::Value::FromUniquePtrValue(std::move(tab_ids)));
+  base::Value::Dict dict;
+  dict.Set(cookies_api_constants::kIdKey, GetStoreIdFromProfile(profile));
+  dict.Set(cookies_api_constants::kTabIdsKey, std::move(tab_ids));
 
   CookieStore cookie_store;
-  bool rv = CookieStore::Populate(dict, &cookie_store);
+  bool rv = CookieStore::Populate(base::Value(std::move(dict)), &cookie_store);
   CHECK(rv);
   return cookie_store;
 }
@@ -198,12 +194,11 @@
   }
 }
 
-void AppendToTabIdList(Browser* browser, base::ListValue* tab_ids) {
+void AppendToTabIdList(Browser* browser, base::Value::List& tab_ids) {
   DCHECK(browser);
-  DCHECK(tab_ids);
   TabStripModel* tab_strip = browser->tab_strip_model();
   for (int i = 0; i < tab_strip->count(); ++i) {
-    tab_ids->Append(ExtensionTabUtil::GetTabId(tab_strip->GetWebContentsAt(i)));
+    tab_ids.Append(ExtensionTabUtil::GetTabId(tab_strip->GetWebContentsAt(i)));
   }
 }
 
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.h b/chrome/browser/extensions/api/cookies/cookies_helpers.h
index 93aaf1b..5eb22d3c 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.h
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
+#include "base/values.h"
 #include "chrome/common/extensions/api/cookies.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_monster.h"
@@ -24,10 +25,6 @@
 class Browser;
 class Profile;
 
-namespace base {
-class ListValue;
-}
-
 namespace net {
 class CanonicalCookie;
 }
@@ -54,9 +51,8 @@
                                   const std::string& store_id);
 
 // Constructs a new CookieStore object as defined by the cookies API.
-api::cookies::CookieStore CreateCookieStore(
-    Profile* profile,
-    std::unique_ptr<base::ListValue> tab_ids);
+api::cookies::CookieStore CreateCookieStore(Profile* profile,
+                                            base::Value::List tab_ids);
 
 // Dispatch a request to the CookieManager for cookies associated with
 // |url|.
@@ -96,7 +92,7 @@
 
 // Appends the IDs of all tabs belonging to the given browser to the
 // given list.
-void AppendToTabIdList(Browser* browser, base::ListValue* tab_ids);
+void AppendToTabIdList(Browser* browser, base::Value::List& tab_ids);
 
 // A class representing the cookie filter parameters passed into
 // cookies.getAll().
diff --git a/chrome/browser/extensions/api/cookies/cookies_unittest.cc b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
index 7a9ef61..b3727bd 100644
--- a/chrome/browser/extensions/api/cookies/cookies_unittest.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
@@ -126,7 +126,7 @@
   EXPECT_EQ(10000, *cookie2.expiration_date);
 
   TestingProfile profile;
-  auto tab_ids_list = std::make_unique<base::ListValue>();
+  base::Value::List tab_ids_list;
   std::vector<int> tab_ids;
   CookieStore cookie_store =
       cookies_helpers::CreateCookieStore(&profile, std::move(tab_ids_list));
@@ -157,9 +157,10 @@
 }
 
 TEST_F(ExtensionCookiesTest, EmptyDictionary) {
-  base::DictionaryValue dict;
+  base::Value::Dict dict;
   GetAll::Params::Details details;
-  bool rv = GetAll::Params::Details::Populate(dict, &details);
+  bool rv =
+      GetAll::Params::Details::Populate(base::Value(std::move(dict)), &details);
   ASSERT_TRUE(rv);
   cookies_helpers::MatchFilter filter(&details);
   net::CanonicalCookie cookie;
@@ -167,7 +168,7 @@
 }
 
 TEST_F(ExtensionCookiesTest, DomainMatching) {
-  const DomainMatchCase tests[] = {
+  static constexpr DomainMatchCase tests[] = {
       {"bar.com", "bar.com", true},       {".bar.com", "bar.com", true},
       {"bar.com", "food.bar.com", true},  {"bar.com", "bar.foo.com", false},
       {".bar.com", ".foo.bar.com", true}, {".bar.com", "baz.foo.bar.com", true},
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index 3665015..7c273a59 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -19,6 +19,7 @@
 #include "base/json/json_reader.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
 #include "base/strings/stringprintf.h"
@@ -613,11 +614,12 @@
         GetCurrentManager(), download_count);
   }
 
-  bool RunFunction(ExtensionFunction* function, const std::string& args) {
+  bool RunFunction(scoped_refptr<ExtensionFunction> function,
+                   const std::string& args) {
     return RunFunctionInternal(extension_, function, args);
   }
 
-  bool RunFunctionInSecondExtension(ExtensionFunction* function,
+  bool RunFunctionInSecondExtension(scoped_refptr<ExtensionFunction> function,
                                     const std::string& args) {
     return RunFunctionInternal(second_extension_, function, args);
   }
@@ -684,7 +686,7 @@
 
  private:
   void SetUpExtensionFunction(const raw_ptr<const Extension>& extension,
-                              ExtensionFunction* function) {
+                              scoped_refptr<ExtensionFunction> function) {
     if (extension) {
       const GURL url = current_browser_ == incognito_browser_ &&
                                !IncognitoInfo::IsSplitMode(extension)
@@ -706,12 +708,12 @@
   }
 
   bool RunFunctionInternal(const raw_ptr<const Extension>& extension,
-                           ExtensionFunction* function,
+                           scoped_refptr<ExtensionFunction> function,
                            const std::string& args) {
     scoped_refptr<ExtensionFunction> delete_function(function);
     SetUpExtensionFunction(extension, function);
     bool result = extension_function_test_utils::RunFunction(
-        function, args, current_browser(), GetFlags());
+        function.get(), args, current_browser(), GetFlags());
     if (!result) {
       LOG(ERROR) << function->GetError();
     }
@@ -967,7 +969,8 @@
   platform_util::internal::DisableShellOperationsForTesting();
 
   LoadExtension("downloads_split");
-  DownloadsOpenFunction* open_function = new DownloadsOpenFunction();
+  scoped_refptr<DownloadsOpenFunction> open_function =
+      base::MakeRefCounted<DownloadsOpenFunction>();
   open_function->set_user_gesture(true);
   EXPECT_STREQ(errors::kInvalidId,
                RunFunctionAndReturnError(
@@ -986,7 +989,7 @@
                           "  \"paused\": false,"
                           "  \"url\": \"%s\"}]",
                           download_item->GetURL().spec().c_str())));
-  open_function = new DownloadsOpenFunction();
+  open_function = base::MakeRefCounted<DownloadsOpenFunction>();
   open_function->set_user_gesture(true);
   EXPECT_STREQ(errors::kNotComplete,
                RunFunctionAndReturnError(
@@ -996,7 +999,7 @@
   FinishFirstSlowDownloads();
   EXPECT_FALSE(download_item->GetOpened());
 
-  open_function = new DownloadsOpenFunction();
+  open_function = base::MakeRefCounted<DownloadsOpenFunction>();
   EXPECT_STREQ(errors::kUserGesture,
                RunFunctionAndReturnError(
                   open_function,
@@ -1004,20 +1007,20 @@
   current_browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_FALSE(download_item->GetOpened());
 
-  scoped_refptr<DownloadsOpenFunction> scoped_open(new DownloadsOpenFunction());
-  scoped_open->set_user_gesture(true);
+  open_function = base::MakeRefCounted<DownloadsOpenFunction>();
+  open_function->set_user_gesture(true);
   base::Value args_list(base::Value::Type::LIST);
   args_list.Append(static_cast<int>(download_item->GetId()));
-  scoped_open->SetArgs(std::move(args_list));
-  scoped_open->set_extension(extension());
+  open_function->SetArgs(std::move(args_list));
+  open_function->set_extension(extension());
   DownloadsOpenFunction::OnPromptCreatedCallback callback =
       base::BindOnce(&OnOpenPromptCreated, base::Unretained(download_item));
   DownloadsOpenFunction::set_on_prompt_created_cb_for_testing(&callback);
-  api_test_utils::SendResponseHelper response_helper(scoped_open.get());
+  api_test_utils::SendResponseHelper response_helper(open_function.get());
   std::unique_ptr<ExtensionFunctionDispatcher> dispatcher(
       new ExtensionFunctionDispatcher(current_browser()->profile()));
-  scoped_open->SetDispatcher(dispatcher->AsWeakPtr());
-  scoped_open->RunWithValidation()->Execute();
+  open_function->SetDispatcher(dispatcher->AsWeakPtr());
+  open_function->RunWithValidation()->Execute();
   response_helper.WaitForResponse();
   EXPECT_TRUE(response_helper.has_response());
   EXPECT_TRUE(response_helper.GetResponse());
@@ -1034,74 +1037,78 @@
 
   // Call pause().  It should succeed and the download should be paused on
   // return.
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_TRUE(download_item->IsPaused());
 
   // Calling removeFile on a non-active download yields kNotComplete
   // and should not crash. http://crbug.com/319984
-  error = RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
-                                    DownloadItemIdAsArgList(download_item));
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsRemoveFileFunction>(),
+      DownloadItemIdAsArgList(download_item));
   EXPECT_STREQ(errors::kNotComplete, error.c_str());
 
   // Calling pause() twice shouldn't be an error.
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_TRUE(download_item->IsPaused());
 
   // Now try resuming this download.  It should succeed.
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_FALSE(download_item->IsPaused());
 
   // Resume again.  Resuming a download that wasn't paused is not an error.
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_FALSE(download_item->IsPaused());
 
   // Pause again.
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_TRUE(download_item->IsPaused());
 
   // And now cancel.
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
 
   // Cancel again.  Shouldn't have any effect.
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
                           DownloadItemIdAsArgList(download_item)));
   EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
 
   // Calling paused on a non-active download yields kNotInProgress.
-  error = RunFunctionAndReturnError(
-      new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
+  error =
+      RunFunctionAndReturnError(base::MakeRefCounted<DownloadsPauseFunction>(),
+                                DownloadItemIdAsArgList(download_item));
   EXPECT_STREQ(errors::kNotInProgress, error.c_str());
 
   // Calling resume on a non-active download yields kNotResumable
-  error = RunFunctionAndReturnError(
-      new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
+  error =
+      RunFunctionAndReturnError(base::MakeRefCounted<DownloadsResumeFunction>(),
+                                DownloadItemIdAsArgList(download_item));
   EXPECT_STREQ(errors::kNotResumable, error.c_str());
 
   // Calling pause on a non-existent download yields kInvalidId.
   error = RunFunctionAndReturnError(
-      new DownloadsPauseFunction(), "[-42]");
+      base::MakeRefCounted<DownloadsPauseFunction>(), "[-42]");
   EXPECT_STREQ(errors::kInvalidId, error.c_str());
 
   // Calling resume on a non-existent download yields kInvalidId
   error = RunFunctionAndReturnError(
-      new DownloadsResumeFunction(), "[-42]");
+      base::MakeRefCounted<DownloadsResumeFunction>(), "[-42]");
   EXPECT_STREQ(errors::kInvalidId, error.c_str());
 
   // Calling removeFile on a non-existent download yields kInvalidId.
   error = RunFunctionAndReturnError(
-      new DownloadsRemoveFileFunction(), "[-42]");
+      base::MakeRefCounted<DownloadsRemoveFileFunction>(), "[-42]");
   EXPECT_STREQ(errors::kInvalidId, error.c_str());
 
   int id = download_item->GetId();
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsEraseFunction(), base::StringPrintf("[{\"id\": %d}]", id)));
+  std::unique_ptr<base::Value> result(
+      RunFunctionAndReturnResult(base::MakeRefCounted<DownloadsEraseFunction>(),
+                                 base::StringPrintf("[{\"id\": %d}]", id)));
   DownloadManager::DownloadVector items;
   GetCurrentManager()->GetAllDownloads(&items);
   EXPECT_EQ(0UL, items.size());
@@ -1119,7 +1126,7 @@
     IconLoader::IconSize icon_size,
     const std::string& response) {
   scoped_refptr<DownloadsGetFileIconFunction> function(
-      new DownloadsGetFileIconFunction());
+      base::MakeRefCounted<DownloadsGetFileIconFunction>());
   function->SetIconExtractorForTesting(new MockIconExtractorImpl(
       expected_path, icon_size, response));
   return function;
@@ -1199,7 +1206,8 @@
   download_item->Remove();
   download_item = nullptr;
   EXPECT_EQ(nullptr, GetCurrentManager()->GetDownload(id));
-  error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsGetFileIconFunction>(), args32);
   EXPECT_STREQ(errors::kInvalidId,
                error.c_str());
 }
@@ -1248,8 +1256,8 @@
   ScopedCancellingItem item(CreateFirstSlowTestDownload());
   ASSERT_TRUE(item.get());
 
-  std::unique_ptr<base::Value> result(
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(), "[{}]"));
+  std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1267,8 +1275,8 @@
   base::DeleteFile(download_item->GetTargetFilePath());
 
   ASSERT_FALSE(download_item->GetFileExternallyRemoved());
-  std::unique_ptr<base::Value> result(
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(), "[{}]"));
+  std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1287,7 +1295,8 @@
   ScopedCancellingItem item(CreateFirstSlowTestDownload());
   ASSERT_TRUE(item.get());
 
-  RunFunction(new DownloadsShowFunction(), DownloadItemIdAsArgList(item.get()));
+  RunFunction(base::MakeRefCounted<DownloadsShowFunction>(),
+              DownloadItemIdAsArgList(item.get()));
 }
 
 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
@@ -1296,7 +1305,7 @@
   ScopedCancellingItem item(CreateFirstSlowTestDownload());
   ASSERT_TRUE(item.get());
 
-  RunFunction(new DownloadsShowDefaultFolderFunction(),
+  RunFunction(base::MakeRefCounted<DownloadsShowDefaultFolderFunction>(),
               DownloadItemIdAsArgList(item.get()));
 }
 #endif
@@ -1315,7 +1324,8 @@
                                      &all_downloads));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{\"filenameRegex\": \"foobar\"}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1334,7 +1344,7 @@
   ScopedItemVectorCanceller delete_items(&items);
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(),
+      base::MakeRefCounted<DownloadsSearchFunction>(),
       base::StringPrintf("[{\"id\": %u}]", items[0]->GetId())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
@@ -1354,9 +1364,9 @@
   CreateTwoDownloads(&items);
   ScopedItemVectorCanceller delete_items(&items);
 
-  std::unique_ptr<base::Value> result(
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(),
-                                 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
+  std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{\"id\": 0, \"filename\": \"foobar\"}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(0UL, result->GetList().size());
@@ -1375,7 +1385,8 @@
       CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{\"orderBy\": [\"filename\"]}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(2UL, result->GetList().size());
@@ -1405,7 +1416,7 @@
       CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{\"orderBy\": []}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(2UL, result->GetList().size());
@@ -1439,7 +1450,8 @@
       CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{\"danger\": \"content\"}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1455,7 +1467,8 @@
   items[0]->Cancel(true);
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{\"state\": \"in_progress\"}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1469,7 +1482,7 @@
   ScopedItemVectorCanceller delete_items(&items);
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{\"limit\": 1}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1478,16 +1491,18 @@
 // Test invalid search parameters.
 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
     DownloadExtensionTest_SearchInvalid) {
-  std::string error = RunFunctionAndReturnError(
-      new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
+  std::string error =
+      RunFunctionAndReturnError(base::MakeRefCounted<DownloadsSearchFunction>(),
+                                "[{\"filenameRegex\": \"(\"}]");
   EXPECT_STREQ(errors::kInvalidFilter,
       error.c_str());
-  error = RunFunctionAndReturnError(
-      new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
+  error =
+      RunFunctionAndReturnError(base::MakeRefCounted<DownloadsSearchFunction>(),
+                                "[{\"orderBy\": [\"goat\"]}]");
   EXPECT_STREQ(errors::kInvalidOrderBy,
       error.c_str());
   error = RunFunctionAndReturnError(
-      new DownloadsSearchFunction(), "[{\"limit\": -1}]");
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{\"limit\": -1}]");
   EXPECT_STREQ(errors::kInvalidQueryLimit,
       error.c_str());
 }
@@ -1507,13 +1522,13 @@
   ASSERT_TRUE(
       CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
-  std::unique_ptr<base::Value> result(
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(),
-                                 "[{"
-                                 "\"state\": \"complete\", "
-                                 "\"danger\": \"content\", "
-                                 "\"orderBy\": [\"filename\"], "
-                                 "\"limit\": 1}]"));
+  std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(),
+      "[{"
+      "\"state\": \"complete\", "
+      "\"danger\": \"content\", "
+      "\"orderBy\": [\"filename\"], "
+      "\"limit\": 1}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_list());
   ASSERT_EQ(1UL, result->GetList().size());
@@ -1553,8 +1568,8 @@
   // Extensions running in the incognito window should have access to both
   // items because the Test extension is in spanning mode.
   GoOffTheRecord();
-  result_value =
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(), "[{}]");
+  result_value = RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{}]");
   ASSERT_TRUE(result_value.get());
   ASSERT_TRUE(result_value->is_list());
   ASSERT_EQ(2UL, result_value->GetList().size());
@@ -1584,8 +1599,8 @@
   // Extensions running in the on-record window should have access only to the
   // on-record item.
   GoOnTheRecord();
-  result_value =
-      RunFunctionAndReturnResult(new DownloadsSearchFunction(), "[{}]");
+  result_value = RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsSearchFunction>(), "[{}]");
   ASSERT_TRUE(result_value.get());
   ASSERT_TRUE(result_value->is_list());
   ASSERT_EQ(1UL, result_value->GetList().size());
@@ -1603,15 +1618,16 @@
 
   // Pausing/Resuming the off-record item while on the record should return an
   // error. Cancelling "non-existent" downloads is not an error.
-  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
-  EXPECT_STREQ(errors::kInvalidId,
-               error.c_str());
-  error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
-                                    off_item_arg);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsPauseFunction>(), off_item_arg);
   EXPECT_STREQ(errors::kInvalidId,
                error.c_str());
   error = RunFunctionAndReturnError(
-      new DownloadsGetFileIconFunction(),
+      base::MakeRefCounted<DownloadsResumeFunction>(), off_item_arg);
+  EXPECT_STREQ(errors::kInvalidId,
+               error.c_str());
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsGetFileIconFunction>(),
       base::StringPrintf("[%d, {}]", off_item->GetId()));
   EXPECT_STREQ(errors::kInvalidId,
                error.c_str());
@@ -1630,42 +1646,59 @@
 
   // Do the pause/resume/cancel test for both the on- and off-items while off
   // the record.
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
+  EXPECT_TRUE(
+      RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(), on_item_arg));
   EXPECT_TRUE(on_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
+  EXPECT_TRUE(
+      RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(), on_item_arg));
   EXPECT_TRUE(on_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
+                          on_item_arg));
   EXPECT_FALSE(on_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
+                          on_item_arg));
   EXPECT_FALSE(on_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
+  EXPECT_TRUE(
+      RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(), on_item_arg));
   EXPECT_TRUE(on_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
+                          on_item_arg));
   EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
+                          on_item_arg));
   EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
-  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsPauseFunction>(), on_item_arg);
   EXPECT_STREQ(errors::kNotInProgress, error.c_str());
-  error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsResumeFunction>(), on_item_arg);
   EXPECT_STREQ(errors::kNotResumable, error.c_str());
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
+                          off_item_arg));
   EXPECT_TRUE(off_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
+                          off_item_arg));
   EXPECT_TRUE(off_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
+                          off_item_arg));
   EXPECT_FALSE(off_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
+                          off_item_arg));
   EXPECT_FALSE(off_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsPauseFunction>(),
+                          off_item_arg));
   EXPECT_TRUE(off_item->IsPaused());
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
+                          off_item_arg));
   EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
-  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsCancelFunction>(),
+                          off_item_arg));
   EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
-  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsPauseFunction>(), off_item_arg);
   EXPECT_STREQ(errors::kNotInProgress, error.c_str());
-  error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
-                                    off_item_arg);
+  error = RunFunctionAndReturnError(
+      base::MakeRefCounted<DownloadsResumeFunction>(), off_item_arg);
   EXPECT_STREQ(errors::kNotResumable, error.c_str());
 }
 
@@ -1688,7 +1721,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -1750,7 +1783,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.spec().c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -1809,7 +1842,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -1855,7 +1888,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\", \"filename\": \"foo%%bar\"}]",
                          download_url.c_str())));
   ASSERT_TRUE(result.get());
@@ -1943,7 +1976,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.spec().c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -1969,7 +2002,7 @@
                                          "    \"previous\": \"in_progress\"}}]",
                                          result_id)));
 
-  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsResumeFunction>(),
                           DownloadItemIdAsArgList(item)));
   ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
                       base::StringPrintf("[{\"id\":%d,"
@@ -2023,17 +2056,18 @@
 
   for (size_t index = 0; index < std::size(kUnsafeHeaders); ++index) {
     std::string download_url = embedded_test_server()->GetURL("/slow?0").spec();
-    EXPECT_STREQ(errors::kInvalidHeaderUnsafe,
-                  RunFunctionAndReturnError(new DownloadsDownloadFunction(),
-                                            base::StringPrintf(
-        "[{\"url\": \"%s\","
-        "  \"filename\": \"unsafe-header-%d.txt\","
-        "  \"headers\": [{"
-        "    \"name\": \"%s\","
-        "    \"value\": \"unsafe\"}]}]",
-        download_url.c_str(),
-        static_cast<int>(index),
-        kUnsafeHeaders[index])).c_str());
+    EXPECT_STREQ(
+        errors::kInvalidHeaderUnsafe,
+        RunFunctionAndReturnError(
+            base::MakeRefCounted<DownloadsDownloadFunction>(),
+            base::StringPrintf("[{\"url\": \"%s\","
+                               "  \"filename\": \"unsafe-header-%d.txt\","
+                               "  \"headers\": [{"
+                               "    \"name\": \"%s\","
+                               "    \"value\": \"unsafe\"}]}]",
+                               download_url.c_str(), static_cast<int>(index),
+                               kUnsafeHeaders[index]))
+            .c_str());
   }
 }
 
@@ -2044,25 +2078,30 @@
   ASSERT_TRUE(StartEmbeddedTestServer());
   GoOnTheRecord();
   std::string download_url = embedded_test_server()->GetURL("/slow?0").spec();
-  EXPECT_STREQ(errors::kInvalidHeaderName,
-               RunFunctionAndReturnError(new DownloadsDownloadFunction(),
-                                         base::StringPrintf(
-      "[{\"url\": \"%s\","
-      "  \"filename\": \"unsafe-header-crlf.txt\","
-      "  \"headers\": [{"
-      "    \"name\": \"Header\\r\\nSec-Spoof: Hey\\r\\nX-Split:X\","
-      "    \"value\": \"unsafe\"}]}]",
-      download_url.c_str())).c_str());
+  EXPECT_STREQ(
+      errors::kInvalidHeaderName,
+      RunFunctionAndReturnError(
+          base::MakeRefCounted<DownloadsDownloadFunction>(),
+          base::StringPrintf(
+              "[{\"url\": \"%s\","
+              "  \"filename\": \"unsafe-header-crlf.txt\","
+              "  \"headers\": [{"
+              "    \"name\": \"Header\\r\\nSec-Spoof: Hey\\r\\nX-Split:X\","
+              "    \"value\": \"unsafe\"}]}]",
+              download_url.c_str()))
+          .c_str());
 
-  EXPECT_STREQ(errors::kInvalidHeaderValue,
-               RunFunctionAndReturnError(new DownloadsDownloadFunction(),
-                                         base::StringPrintf(
-      "[{\"url\": \"%s\","
-      "  \"filename\": \"unsafe-header-crlf.txt\","
-      "  \"headers\": [{"
-      "    \"name\": \"Invalid-value\","
-      "    \"value\": \"hey\\r\\nSec-Spoof: Hey\"}]}]",
-      download_url.c_str())).c_str());
+  EXPECT_STREQ(
+      errors::kInvalidHeaderValue,
+      RunFunctionAndReturnError(
+          base::MakeRefCounted<DownloadsDownloadFunction>(),
+          base::StringPrintf("[{\"url\": \"%s\","
+                             "  \"filename\": \"unsafe-header-crlf.txt\","
+                             "  \"headers\": [{"
+                             "    \"name\": \"Invalid-value\","
+                             "    \"value\": \"hey\\r\\nSec-Spoof: Hey\"}]}]",
+                             download_url.c_str()))
+          .c_str());
 }
 
 // This test is very flaky on Win. http://crbug.com/248438
@@ -2081,7 +2120,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"sub/dir/ect/ory.txt\"}]",
                          download_url.c_str())));
@@ -2126,12 +2165,14 @@
   std::string download_url = embedded_test_server()->GetURL("/slow?0").spec();
   GoOnTheRecord();
 
-  EXPECT_STREQ(errors::kInvalidFilename,
-                RunFunctionAndReturnError(new DownloadsDownloadFunction(),
-                                          base::StringPrintf(
-      "[{\"url\": \"%s\","
-      "  \"filename\": \"../../../../../etc/passwd\"}]",
-      download_url.c_str())).c_str());
+  EXPECT_STREQ(
+      errors::kInvalidFilename,
+      RunFunctionAndReturnError(
+          base::MakeRefCounted<DownloadsDownloadFunction>(),
+          base::StringPrintf("[{\"url\": \"%s\","
+                             "  \"filename\": \"../../../../../etc/passwd\"}]",
+                             download_url.c_str()))
+          .c_str());
 }
 
 // Test that downloading invalid URLs immediately returns kInvalidURLError.
@@ -2145,7 +2186,7 @@
   for (const char* url : kInvalidURLs) {
     EXPECT_STREQ(errors::kInvalidURL,
                  RunFunctionAndReturnError(
-                     new DownloadsDownloadFunction(),
+                     base::MakeRefCounted<DownloadsDownloadFunction>(),
                      base::StringPrintf("[{\"url\": \"%s\"}]", url))
                      .c_str())
         << url;
@@ -2160,7 +2201,7 @@
 
   int result_id = -1;
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]"));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2172,9 +2213,9 @@
       "[{\"state\": \"in_progress\","
       "  \"url\": \"javascript:document.write(\\\"hello\\\");\"}]"));
 
-  result =
-      RunFunctionAndReturnResult(new DownloadsDownloadFunction(),
-                                 "[{\"url\": \"javascript:return false;\"}]");
+  result = RunFunctionAndReturnResult(
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
+      "[{\"url\": \"javascript:return false;\"}]");
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
   result_id = result->GetInt();
@@ -2204,7 +2245,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2256,7 +2297,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2291,7 +2332,7 @@
                           result_id)));
 
   result = RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf(
           "[{\"url\": \"%s\",  \"conflictAction\": \"overwrite\"}]",
           download_url.c_str()));
@@ -2344,7 +2385,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"data.txt\"}]",
                          download_url.c_str())));
@@ -2400,7 +2441,7 @@
 #endif
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"file.txt\"}]",
                          download_url.c_str())));
@@ -2450,7 +2491,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"auth-basic-fail.txt\"}]",
                          download_url.c_str())));
@@ -2493,7 +2534,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"headers-succeed.txt\","
                          "  \"headers\": ["
@@ -2558,7 +2599,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"headers-fail.txt\"}]",
                          download_url.c_str())));
@@ -2595,7 +2636,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"auth-basic-succeed.txt\","
                          "  \"headers\": [{"
@@ -2650,7 +2691,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"filename\": \"post-succeed.txt\","
                          "  \"method\": \"POST\","
@@ -2714,7 +2755,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"body\": \"BODY\","
                          "  \"filename\": \"post-get.txt\"}]",
@@ -2763,7 +2804,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\","
                          "  \"method\": \"POST\","
                          "  \"filename\": \"post-nobody.txt\"}]",
@@ -2802,7 +2843,7 @@
   GoOnTheRecord();
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2865,7 +2906,7 @@
 
   // Now download it.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2924,7 +2965,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -2992,7 +3033,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3057,7 +3098,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3128,7 +3169,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf(R"([{"url": "%s"}])", download_url.c_str())));
   ASSERT_TRUE(result.get());
   int result_id = result->GetInt();
@@ -3156,7 +3197,7 @@
   ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
 
   std::unique_ptr<base::Value> determine_result(RunFunctionAndReturnResult(
-      new DownloadsInternalDetermineFilenameFunction(),
+      base::MakeRefCounted<DownloadsInternalDetermineFilenameFunction>(),
       base::StringPrintf(R"([%d, "", "uniquify"])", result_id)));
   EXPECT_FALSE(determine_result.get());  // No return value.
 }
@@ -3182,7 +3223,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3243,7 +3284,7 @@
   std::string download_url = "data:application/x-shockwave-flash,";
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3324,7 +3365,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3394,7 +3435,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3464,7 +3505,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3533,7 +3574,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3603,7 +3644,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3673,7 +3714,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3743,7 +3784,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3807,7 +3848,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3879,7 +3920,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -3930,7 +3971,7 @@
 
   // Start downloading a file.
   result = RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str()));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4003,7 +4044,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4054,7 +4095,7 @@
 
   // Start downloading a file.
   result = RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str()));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4131,7 +4172,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4198,7 +4239,7 @@
   // Start an on-record download.
   GoOnTheRecord();
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4261,7 +4302,7 @@
   // Start an incognito download for comparison.
   GoOffTheRecord();
   result = RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str()));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4347,7 +4388,7 @@
   // Start an on-record download.
   GoOnTheRecord();
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4410,7 +4451,7 @@
   // Start an incognito download for comparison.
   GoOffTheRecord();
   result = RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str()));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4613,11 +4654,13 @@
 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                        DownloadExtensionTest_SetShelfEnabled) {
   LoadExtension("downloads_split");
-  EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
+  EXPECT_TRUE(RunFunction(
+      base::MakeRefCounted<DownloadsSetShelfEnabledFunction>(), "[false]"));
   EXPECT_FALSE(DownloadCoreServiceFactory::GetForBrowserContext(
                    current_browser()->profile())
                    ->IsDownloadUiEnabled());
-  EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
+  EXPECT_TRUE(RunFunction(
+      base::MakeRefCounted<DownloadsSetShelfEnabledFunction>(), "[true]"));
   EXPECT_TRUE(DownloadCoreServiceFactory::GetForBrowserContext(
                   current_browser()->profile())
                   ->IsDownloadUiEnabled());
@@ -4634,12 +4677,12 @@
 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                        DownloadExtensionTest_SetUiOptions) {
   LoadExtension("downloads_split");
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": false}])"));
   EXPECT_FALSE(DownloadCoreServiceFactory::GetForBrowserContext(
                    current_browser()->profile())
                    ->IsDownloadUiEnabled());
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": true}])"));
   EXPECT_TRUE(DownloadCoreServiceFactory::GetForBrowserContext(
                   current_browser()->profile())
@@ -4670,7 +4713,7 @@
   // button; wait until the download completes.
   LoadExtension("downloads_split");
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       "[{\"url\": \"data:application/x-shockwave-flash,\", \"filename\": "
       "\"dangerous.swf\"}]"));
   ASSERT_TRUE(result.get());
@@ -4718,7 +4761,7 @@
 
   // Start downloading a file.
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsDownloadFunction(),
+      base::MakeRefCounted<DownloadsDownloadFunction>(),
       base::StringPrintf("[{\"url\": \"%s\"}]", download_url.c_str())));
   ASSERT_TRUE(result.get());
   ASSERT_TRUE(result->is_int());
@@ -4781,11 +4824,11 @@
   ScopedItemVectorCanceller delete_items(&items);
   LoadExtension("downloads_split");
 
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": true}])"));
   EXPECT_TRUE(GetDownloadToolbarButton()->IsShowing());
 
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": false}])"));
   EXPECT_FALSE(GetDownloadToolbarButton()->IsShowing());
 
@@ -4798,7 +4841,7 @@
     DownloadExtensionBubbleEnabledTest,
     DownloadExtensionBubbleEnabledTest_SetUiOptionsBeforeDownloadStart) {
   LoadExtension("downloads_split");
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": false}])"));
   DownloadManager::DownloadVector items;
   CreateTwoDownloads(&items);
@@ -4833,7 +4876,7 @@
     DownloadExtensionBubbleEnabledTest,
     DownloadExtensionBubbleEnabledTest_SetUiOptionsOffTheRecord) {
   LoadExtension("downloads_split");
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": false}])"));
   DownloadManager::DownloadVector items;
   CreateTwoDownloads(&items);
@@ -4843,7 +4886,7 @@
   GoOffTheRecord();
   EXPECT_FALSE(GetDownloadToolbarButton()->IsShowing());
 
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": true}])"));
   items[0]->Cancel(true);
   EXPECT_TRUE(GetDownloadToolbarButton()->IsShowing());
@@ -4856,7 +4899,7 @@
     DownloadExtensionBubbleEnabledTest,
     DownloadExtensionBubbleEnabledTest_SetUiOptionsMultipleExtensions) {
   LoadExtension("downloads_split");
-  EXPECT_TRUE(RunFunction(new DownloadsSetUiOptionsFunction(),
+  EXPECT_TRUE(RunFunction(base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
                           R"([{"enabled": false}])"));
   DownloadManager::DownloadVector items;
   CreateTwoDownloads(&items);
@@ -4865,14 +4908,16 @@
 
   LoadSecondExtension("downloads_spanning");
   // Returns error because the first extension has disabled the UI.
-  EXPECT_STREQ(errors::kUiDisabled, RunFunctionAndReturnErrorInSecondExtension(
-                                        new DownloadsSetUiOptionsFunction(),
-                                        R"([{"enabled": true}])")
-                                        .c_str());
+  EXPECT_STREQ(errors::kUiDisabled,
+               RunFunctionAndReturnErrorInSecondExtension(
+                   base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
+                   R"([{"enabled": true}])")
+                   .c_str());
   // Two extensions can set the UI to disabled at the same time. No error should
   // be returned.
-  EXPECT_TRUE(RunFunctionInSecondExtension(new DownloadsSetUiOptionsFunction(),
-                                           R"([{"enabled": false}])"));
+  EXPECT_TRUE(RunFunctionInSecondExtension(
+      base::MakeRefCounted<DownloadsSetUiOptionsFunction>(),
+      R"([{"enabled": false}])"));
 
   DisableExtension(GetExtensionId());
   items[0]->Pause();
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
index 9f335d8..b5f5fdd 100644
--- a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
+++ b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
@@ -727,6 +727,8 @@
   // TODO(crbug.com/1115237): Now that this is an interactive test, is this
   // ifdef still necessary?
 #if !BUILDFLAG(IS_MAC)
+  ui_test_utils::BrowserActivationWaiter waiter(popup_browser);
+  waiter.WaitForActivation();
   EXPECT_TRUE(popup_browser->window()->IsActive());
 #endif
   EXPECT_FALSE(browser()->window()->IsActive());
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
index 17d3f58..be6d53e 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -159,7 +159,7 @@
     return;
   }
   std::string font_name = pref->GetValue()->GetString();
-  base::ListValue args;
+  base::Value::List args;
   base::Value::Dict dict;
   dict.Set(kFontIdKey, font_name);
   dict.Set(kGenericFamilyKey, generic_family);
@@ -168,7 +168,7 @@
 
   extensions::preference_helpers::DispatchEventToExtensions(
       profile_, events::FONT_SETTINGS_ON_FONT_CHANGED,
-      fonts::OnFontChanged::kEventName, &args,
+      fonts::OnFontChanged::kEventName, std::move(args),
       extensions::mojom::APIPermissionID::kFontSettings, false, pref_name);
 }
 
@@ -181,13 +181,13 @@
       pref_name);
   CHECK(pref);
 
-  base::ListValue args;
+  base::Value::List args;
   base::Value::Dict dict;
   dict.Set(key, pref->GetValue()->Clone());
   args.Append(std::move(dict));
 
   extensions::preference_helpers::DispatchEventToExtensions(
-      profile_, histogram_value, event_name, &args,
+      profile_, histogram_value, event_name, std::move(args),
       extensions::mojom::APIPermissionID::kFontSettings, false, pref_name);
 }
 
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_handler.cc b/chrome/browser/extensions/api/notifications/extension_notification_handler.cc
index 61bf0d2..738514f 100644
--- a/chrome/browser/extensions/api/notifications/extension_notification_handler.cc
+++ b/chrome/browser/extensions/api/notifications/extension_notification_handler.cc
@@ -28,7 +28,7 @@
 
 namespace {
 
-std::unique_ptr<base::ListValue> CreateBaseEventArgs(
+base::Value::List CreateBaseEventArgs(
     const std::string& extension_id,
     const std::string& scoped_notification_id) {
   // Unscope the notification id before returning it.
@@ -37,8 +37,8 @@
   std::string unscoped_notification_id =
       scoped_notification_id.substr(index_of_separator);
 
-  std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Append(unscoped_notification_id);
+  base::Value::List args;
+  args.Append(unscoped_notification_id);
   return args;
 }
 
@@ -67,9 +67,8 @@
   std::string extension_id(GetExtensionId(GURL(origin)));
   DCHECK(!extension_id.empty());
 
-  std::unique_ptr<base::ListValue> args(
-      CreateBaseEventArgs(extension_id, notification_id));
-  args->Append(by_user);
+  base::Value::List args = CreateBaseEventArgs(extension_id, notification_id);
+  args.Append(by_user);
   SendEvent(profile, extension_id, events::NOTIFICATIONS_ON_CLOSED,
             api::notifications::OnClosed::kEventName, gesture, std::move(args));
 
@@ -91,10 +90,9 @@
   DCHECK(!reply.has_value());
 
   std::string extension_id(GetExtensionId(GURL(origin)));
-  std::unique_ptr<base::ListValue> args(
-      CreateBaseEventArgs(extension_id, notification_id));
+  base::Value::List args = CreateBaseEventArgs(extension_id, notification_id);
   if (action_index.has_value())
-    args->Append(action_index.value());
+    args.Append(action_index.value());
   events::HistogramValue histogram_value =
       action_index.has_value() ? events::NOTIFICATIONS_ON_BUTTON_CLICKED
                                : events::NOTIFICATIONS_ON_CLICKED;
@@ -122,7 +120,7 @@
     events::HistogramValue histogram_value,
     const std::string& event_name,
     EventRouter::UserGestureState user_gesture,
-    std::unique_ptr<base::ListValue> args) {
+    base::Value::List args) {
   if (extension_id.empty())
     return;
 
@@ -130,8 +128,8 @@
   if (!event_router)
     return;
 
-  auto event = std::make_unique<Event>(histogram_value, event_name,
-                                       std::move(*args).TakeList());
+  auto event =
+      std::make_unique<Event>(histogram_value, event_name, std::move(args));
   event->user_gesture = user_gesture;
   event_router->DispatchEventToExtension(extension_id, std::move(event));
 }
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_handler.h b/chrome/browser/extensions/api/notifications/extension_notification_handler.h
index 9929c68..a4ce114 100644
--- a/chrome/browser/extensions/api/notifications/extension_notification_handler.h
+++ b/chrome/browser/extensions/api/notifications/extension_notification_handler.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_NOTIFICATIONS_EXTENSION_NOTIFICATION_HANDLER_H_
 #define CHROME_BROWSER_EXTENSIONS_API_NOTIFICATIONS_EXTENSION_NOTIFICATION_HANDLER_H_
 
+#include "base/values.h"
 #include "chrome/browser/notifications/notification_handler.h"
 #include "extensions/browser/event_router.h"
 
@@ -49,7 +50,7 @@
                          events::HistogramValue histogram_value,
                          const std::string& name,
                          EventRouter::UserGestureState user_gesture,
-                         std::unique_ptr<base::ListValue> args);
+                         base::Value::List args);
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_handler_unittest.cc b/chrome/browser/extensions/api/notifications/extension_notification_handler_unittest.cc
index 5aa89af..9481dac 100644
--- a/chrome/browser/extensions/api/notifications/extension_notification_handler_unittest.cc
+++ b/chrome/browser/extensions/api/notifications/extension_notification_handler_unittest.cc
@@ -41,10 +41,10 @@
                  events::HistogramValue histogram_value,
                  const std::string& event_name,
                  EventRouter::UserGestureState user_gesture,
-                 std::unique_ptr<base::ListValue> args) final {
+                 base::Value::List args) final {
     EXPECT_EQ(event_name_, event_name);
     EXPECT_EQ(extension_id_, extension_id);
-    EXPECT_EQ(param_count_, args->GetList().size());
+    EXPECT_EQ(param_count_, args.size());
   }
 
  private:
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc
index f052144..86ea5c1 100644
--- a/chrome/browser/extensions/api/preference/preference_api.cc
+++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -302,7 +302,7 @@
       browser_pref, &event_name, &permission);
   DCHECK(found_event);
 
-  base::ListValue args;
+  base::Value::List args;
   PrefTransformerInterface* transformer =
       PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref);
 
@@ -321,8 +321,8 @@
   events::HistogramValue histogram_value =
       events::TYPES_CHROME_SETTING_ON_CHANGE;
   extensions::preference_helpers::DispatchEventToExtensionsWithAshControlState(
-      profile_, histogram_value, event_name, &args, permission, incognito,
-      browser_pref, control_state);
+      profile_, histogram_value, event_name, std::move(args), permission,
+      incognito, browser_pref, control_state);
 }
 #endif
 
@@ -336,7 +336,7 @@
       browser_pref, &event_name, &permission);
   DCHECK(rv);
 
-  base::ListValue args;
+  base::Value::List args;
   const PrefService::Preference* pref =
       pref_service->FindPreference(browser_pref);
   CHECK(pref);
@@ -370,8 +370,8 @@
   events::HistogramValue histogram_value =
       events::TYPES_CHROME_SETTING_ON_CHANGE;
   extensions::preference_helpers::DispatchEventToExtensions(
-      profile_, histogram_value, event_name, &args, permission, incognito,
-      browser_pref);
+      profile_, histogram_value, event_name, std::move(args), permission,
+      incognito, browser_pref);
 }
 
 void PreferenceEventRouter::OnOffTheRecordProfileCreated(
diff --git a/chrome/browser/extensions/api/preference/preference_helpers.cc b/chrome/browser/extensions/api/preference/preference_helpers.cc
index 0cabd14..306ae55 100644
--- a/chrome/browser/extensions/api/preference/preference_helpers.cc
+++ b/chrome/browser/extensions/api/preference/preference_helpers.cc
@@ -82,7 +82,7 @@
 void DispatchEventToExtensionsImpl(Profile* profile,
                                    events::HistogramValue histogram_value,
                                    const std::string& event_name,
-                                   base::ListValue* args,
+                                   base::Value::List args,
                                    mojom::APIPermissionID permission,
                                    bool incognito,
                                    const std::string& browser_pref,
@@ -98,14 +98,13 @@
         extension->permissions_data()->HasAPIPermission(permission) &&
         (!incognito || util::IsIncognitoEnabled(extension->id(), profile))) {
       // Inject level of control key-value.
-      base::Value::List& args_list = args->GetList();
-      DCHECK(!args_list.empty());
-      DCHECK(args_list[0].is_dict());
+      DCHECK(!args.empty());
+      DCHECK(args[0].is_dict());
 
       std::string level_of_control =
           level_getter.Run(profile, extension->id(), browser_pref, incognito);
 
-      args_list[0].SetStringKey(kLevelOfControlKey, level_of_control);
+      args[0].SetStringKey(kLevelOfControlKey, level_of_control);
 
       // If the extension is in incognito split mode,
       // a) incognito pref changes are visible only to the incognito tabs
@@ -135,7 +134,7 @@
         }
       }
 
-      base::Value::List args_copy = args->GetList().Clone();
+      base::Value::List args_copy = args.Clone();
       auto event =
           std::make_unique<Event>(histogram_value, event_name,
                                   std::move(args_copy), restrict_to_profile);
@@ -149,14 +148,14 @@
     Profile* profile,
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    base::ListValue* args,
+    base::Value::List args,
     mojom::APIPermissionID permission,
     bool incognito,
     const std::string& browser_pref,
     crosapi::mojom::PrefControlState control_state) {
   DispatchEventToExtensionsImpl(
-      profile, histogram_value, event_name, args, permission, incognito,
-      browser_pref,
+      profile, histogram_value, event_name, std::move(args), permission,
+      incognito, browser_pref,
       base::BindRepeating(&GetLevelOfControlWithAshControlState,
                           control_state));
 }
@@ -184,13 +183,13 @@
 void DispatchEventToExtensions(Profile* profile,
                                events::HistogramValue histogram_value,
                                const std::string& event_name,
-                               base::ListValue* args,
+                               base::Value::List args,
                                mojom::APIPermissionID permission,
                                bool incognito,
                                const std::string& browser_pref) {
-  DispatchEventToExtensionsImpl(profile, histogram_value, event_name, args,
-                                permission, incognito, browser_pref,
-                                base::BindRepeating(GetLevelOfControl));
+  DispatchEventToExtensionsImpl(
+      profile, histogram_value, event_name, std::move(args), permission,
+      incognito, browser_pref, base::BindRepeating(GetLevelOfControl));
 }
 }  // namespace preference_helpers
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/preference/preference_helpers.h b/chrome/browser/extensions/api/preference/preference_helpers.h
index 5977c08f..2ab0bcf 100644
--- a/chrome/browser/extensions/api/preference/preference_helpers.h
+++ b/chrome/browser/extensions/api/preference/preference_helpers.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "extensions/browser/extension_event_histogram_value.h"
 #include "extensions/browser/extension_prefs_scope.h"
@@ -21,10 +22,6 @@
 class PrefService;
 class Profile;
 
-namespace base {
-class ListValue;
-}
-
 namespace extensions {
 namespace preference_helpers {
 
@@ -53,7 +50,7 @@
     Profile* profile,
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    base::ListValue* args,
+    base::Value::List args,
     mojom::APIPermissionID permission,
     bool incognito,
     const std::string& browser_pref,
@@ -64,11 +61,11 @@
 // |permission|. |args| is passed as arguments to the event listener.  A
 // key-value for the level of control the extension has over |browser_pref| is
 // injected into the first item of |args|, which must be of type
-// DictionaryValue.
+// dictionary.
 void DispatchEventToExtensions(Profile* profile,
                                events::HistogramValue histogram_value,
                                const std::string& event_name,
-                               base::ListValue* args,
+                               base::Value::List args,
                                mojom::APIPermissionID permission,
                                bool incognito,
                                const std::string& browser_pref);
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index b4ab3086c..65d0b208 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1623,18 +1623,6 @@
       web_contents_, extension(), source_context_type(), nullptr, -1)));
 }
 
-void TabsUpdateFunction::OnExecuteCodeFinished(
-    const std::string& error,
-    const GURL& url,
-    const base::ListValue& script_result) {
-  if (!error.empty()) {
-    Respond(Error(error));
-    return;
-  }
-
-  return Respond(GetResult());
-}
-
 ExtensionFunction::ResponseAction TabsMoveFunction::Run() {
   std::unique_ptr<tabs::Move::Params> params(
       tabs::Move::Params::Create(args()));
@@ -1642,7 +1630,7 @@
 
   int new_index = params->move_properties.index;
   const auto& window_id = params->move_properties.window_id;
-  base::ListValue tab_values;
+  base::Value::List tab_values;
 
   size_t num_tabs = 0;
   std::string error;
@@ -1650,14 +1638,14 @@
     std::vector<int>& tab_ids = *params->tab_ids.as_integers;
     num_tabs = tab_ids.size();
     for (int tab_id : tab_ids) {
-      if (!MoveTab(tab_id, &new_index, &tab_values, window_id, &error))
+      if (!MoveTab(tab_id, &new_index, tab_values, window_id, &error))
         return RespondNow(Error(std::move(error)));
     }
   } else {
     EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
     num_tabs = 1;
-    if (!MoveTab(*params->tab_ids.as_integer, &new_index, &tab_values,
-                 window_id, &error)) {
+    if (!MoveTab(*params->tab_ids.as_integer, &new_index, tab_values, window_id,
+                 &error)) {
       return RespondNow(Error(std::move(error)));
     }
   }
@@ -1670,9 +1658,8 @@
   if (num_tabs == 0)
     return RespondNow(Error("No tabs given."));
   if (num_tabs == 1) {
-    CHECK_EQ(1u, tab_values.GetList().size());
-    base::Value::List tabs = std::move(tab_values).TakeList();
-    return RespondNow(WithArguments(std::move(tabs[0])));
+    CHECK_EQ(1u, tab_values.size());
+    return RespondNow(WithArguments(std::move(tab_values[0])));
   }
 
   // Return the results as an array if there are multiple tabs.
@@ -1681,7 +1668,7 @@
 
 bool TabsMoveFunction::MoveTab(int tab_id,
                                int* new_index,
-                               base::ListValue* tab_values,
+                               base::Value::List& tab_values,
                                const absl::optional<int>& window_id,
                                std::string* error) {
   Browser* source_browser = nullptr;
@@ -1724,10 +1711,10 @@
       content::WebContents* web_contents =
           tab_strip_model->GetWebContentsAt(inserted_index);
 
-      tab_values->Append(CreateTabObjectHelper(web_contents, extension(),
-                                               source_context_type(),
-                                               tab_strip_model, inserted_index)
-                             .ToValue());
+      tab_values.Append(CreateTabObjectHelper(web_contents, extension(),
+                                              source_context_type(),
+                                              tab_strip_model, inserted_index)
+                            .ToValue());
     }
 
     // Insert the tabs one after another.
@@ -1748,10 +1735,10 @@
         source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false);
 
   if (has_callback()) {
-    tab_values->Append(CreateTabObjectHelper(contents, extension(),
-                                             source_context_type(),
-                                             source_tab_strip, *new_index)
-                           .ToValue());
+    tab_values.Append(CreateTabObjectHelper(contents, extension(),
+                                            source_context_type(),
+                                            source_tab_strip, *new_index)
+                          .ToValue());
   }
 
   // Insert the tabs one after another.
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h
index 86092644..05e976fd 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.h
+++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/values.h"
 #include "chrome/browser/extensions/chrome_extension_function_details.h"
 #include "chrome/common/extensions/api/tabs.h"
 #include "components/translate/core/browser/translate_driver.h"
@@ -146,9 +147,6 @@
 
  private:
   ResponseAction Run() override;
-  void OnExecuteCodeFinished(const std::string& error,
-                             const GURL& on_url,
-                             const base::ListValue& script_result);
 
   DECLARE_EXTENSION_FUNCTION("tabs.update", TABS_UPDATE)
 };
@@ -157,7 +155,7 @@
   ResponseAction Run() override;
   bool MoveTab(int tab_id,
                int* new_index,
-               base::ListValue* tab_values,
+               base::Value::List& tab_values,
                const absl::optional<int>& window_id,
                std::string* error);
   DECLARE_EXTENSION_FUNCTION("tabs.move", TABS_MOVE)
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
index 9eab4cf..65cf0018 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -48,16 +48,15 @@
 
 namespace {
 
-std::unique_ptr<base::ListValue> RunTabsQueryFunction(
-    Browser* browser,
-    const Extension* extension,
-    const std::string& query_info) {
+base::Value::List RunTabsQueryFunction(Browser* browser,
+                                       const Extension* extension,
+                                       const std::string& query_info) {
   scoped_refptr<TabsQueryFunction> function(new TabsQueryFunction());
   function->set_extension(extension);
   std::unique_ptr<base::Value> value(
       extension_function_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), query_info, browser, api_test_utils::NONE));
-  return base::ListValue::From(std::move(value));
+  return std::move(*value).TakeList();
 }
 
 // Creates an extension with "tabs" permission.
@@ -296,10 +295,9 @@
 
   // An extension without "tabs" permission will see none of the 3 tabs.
   scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build();
-  std::unique_ptr<base::ListValue> tabs_list_without_permission(
-      RunTabsQueryFunction(browser(), extension.get(), kTitleAndURLQueryInfo));
-  ASSERT_TRUE(tabs_list_without_permission);
-  EXPECT_EQ(0u, tabs_list_without_permission->GetList().size());
+  base::Value::List tabs_list_without_permission =
+      RunTabsQueryFunction(browser(), extension.get(), kTitleAndURLQueryInfo);
+  EXPECT_EQ(0u, tabs_list_without_permission.size());
 
   // An extension with "tabs" permission however will see the third tab.
   scoped_refptr<const Extension> extension_with_permission =
@@ -312,13 +310,11 @@
                   .Set("permissions", ListBuilder().Append("tabs").Build())
                   .Build())
           .Build();
-  std::unique_ptr<base::ListValue> tabs_list_with_permission(
-      RunTabsQueryFunction(browser(), extension_with_permission.get(),
-                           kTitleAndURLQueryInfo));
-  ASSERT_TRUE(tabs_list_with_permission);
-  ASSERT_EQ(1u, tabs_list_with_permission->GetList().size());
+  base::Value::List tabs_list_with_permission = RunTabsQueryFunction(
+      browser(), extension_with_permission.get(), kTitleAndURLQueryInfo);
+  ASSERT_EQ(1u, tabs_list_with_permission.size());
 
-  const base::Value& third_tab_info = tabs_list_with_permission->GetList()[0];
+  const base::Value& third_tab_info = tabs_list_with_permission[0];
   ASSERT_TRUE(third_tab_info.is_dict());
   absl::optional<int> third_tab_id = third_tab_info.FindIntKey("id");
   EXPECT_EQ(ExtensionTabUtil::GetTabId(web_contentses[2]), third_tab_id);
@@ -368,13 +364,11 @@
           .Build();
 
   {
-    std::unique_ptr<base::ListValue> tabs_list_with_permission(
-        RunTabsQueryFunction(browser(), extension_with_permission.get(),
-                             kTitleAndURLQueryInfo));
-    ASSERT_TRUE(tabs_list_with_permission);
-    ASSERT_EQ(1u, tabs_list_with_permission->GetList().size());
+    base::Value::List tabs_list_with_permission = RunTabsQueryFunction(
+        browser(), extension_with_permission.get(), kTitleAndURLQueryInfo);
+    ASSERT_EQ(1u, tabs_list_with_permission.size());
 
-    const base::Value& third_tab_info = tabs_list_with_permission->GetList()[0];
+    const base::Value& third_tab_info = tabs_list_with_permission[0];
     ASSERT_TRUE(third_tab_info.is_dict());
     absl::optional<int> third_tab_id = third_tab_info.FindIntKey("id");
     EXPECT_EQ(ExtensionTabUtil::GetTabId(web_contentses[2]), third_tab_id);
@@ -383,15 +377,13 @@
   // Try the same without title, first and third tabs will match.
   const char* kURLQueryInfo = "[{\"url\": \"*://www.google.com/*\"}]";
   {
-    std::unique_ptr<base::ListValue> tabs_list_with_permission(
-        RunTabsQueryFunction(browser(), extension_with_permission.get(),
-                             kURLQueryInfo));
-    ASSERT_TRUE(tabs_list_with_permission);
-    ASSERT_EQ(2u, tabs_list_with_permission->GetList().size());
+    base::Value::List tabs_list_with_permission = RunTabsQueryFunction(
+        browser(), extension_with_permission.get(), kURLQueryInfo);
+    ASSERT_EQ(2u, tabs_list_with_permission.size());
 
-    const base::Value& first_tab_info = tabs_list_with_permission->GetList()[0];
+    const base::Value& first_tab_info = tabs_list_with_permission[0];
     ASSERT_TRUE(first_tab_info.is_dict());
-    const base::Value& third_tab_info = tabs_list_with_permission->GetList()[1];
+    const base::Value& third_tab_info = tabs_list_with_permission[1];
     ASSERT_TRUE(third_tab_info.is_dict());
 
     std::vector<int> expected_tabs_ids;
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index 199efedb..a39671b 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -32,7 +32,6 @@
 #include "third_party/blink/public/common/page/page_zoom.h"
 
 using base::DictionaryValue;
-using base::ListValue;
 using base::Value;
 using content::WebContents;
 using zoom::ZoomController;
@@ -445,7 +444,7 @@
     const ui::ListSelectionModel& old_model) {
   ui::ListSelectionModel::SelectedIndices new_selection =
       tab_strip_model->selection_model().selected_indices();
-  base::ListValue all_tabs;
+  base::Value::List all_tabs;
 
   for (int index : new_selection) {
     WebContents* contents = tab_strip_model->GetWebContentsAt(index);
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc
index 7ff0251..fe0782a 100644
--- a/chrome/browser/extensions/api/tabs/windows_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -41,10 +41,11 @@
     return false;
 
   // If there is no filter the visibility is based on the extension.
-  const base::ListValue* filter_value = nullptr;
-  if (listener_filter)
-    listener_filter->GetList(extensions::tabs_constants::kWindowTypesKey,
-                             &filter_value);
+  const base::Value::List* filter_value = nullptr;
+  if (listener_filter) {
+    filter_value = listener_filter->GetDict().FindList(
+        extensions::tabs_constants::kWindowTypesKey);
+  }
 
   // TODO(https://crbug.com/807313): Remove this.
   bool allow_dev_tools_windows = !!filter_value;
diff --git a/chrome/browser/extensions/window_controller.cc b/chrome/browser/extensions/window_controller.cc
index 15c6424..6513041 100644
--- a/chrome/browser/extensions/window_controller.cc
+++ b/chrome/browser/extensions/window_controller.cc
@@ -42,14 +42,14 @@
 
 // static
 WindowController::TypeFilter WindowController::GetFilterFromWindowTypesValues(
-    const base::ListValue* types) {
+    const base::Value::List* types) {
   WindowController::TypeFilter filter = WindowController::kNoWindowFilter;
   if (!types)
     return filter;
-  for (const base::Value& type : types->GetList()) {
-    const std::string* window_type = type.GetIfString();
-    if (window_type)
-      filter |= 1 << api::windows::ParseWindowType(*window_type);
+  for (const base::Value& type : *types) {
+    if (!type.is_string())
+      continue;
+    filter |= 1 << api::windows::ParseWindowType(type.GetString());
   }
   return filter;
 }
diff --git a/chrome/browser/extensions/window_controller.h b/chrome/browser/extensions/window_controller.h
index 23a193d0d..b4a8c05f 100644
--- a/chrome/browser/extensions/window_controller.h
+++ b/chrome/browser/extensions/window_controller.h
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
+#include "base/values.h"
 #include "chrome/common/extensions/api/tabs.h"
 #include "chrome/common/extensions/api/windows.h"
 
@@ -52,7 +53,7 @@
       const std::vector<api::windows::WindowType>& types);
 
   static TypeFilter GetFilterFromWindowTypesValues(
-      const base::ListValue* types);
+      const base::Value::List* types);
 
   WindowController(ui::BaseWindow* window, Profile* profile);
   WindowController(const WindowController&) = delete;
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProvider.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProvider.java
index 21caf19..5eb0aa3e 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProvider.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProvider.java
@@ -23,7 +23,6 @@
 import org.chromium.chrome.browser.xsurface.LoggingParameters;
 import org.chromium.chrome.browser.xsurface.PersistentKeyValueCache;
 import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider;
-import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider.VisibilityLogType;
 import org.chromium.components.version_info.VersionConstants;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 
@@ -48,7 +47,7 @@
         mPersistentKeyValueCache = new FeedPersistentKeyValueCache();
         mPrivacyPreferencesManager = privacyPreferencesManager;
         mApiKey = apiKey;
-        if (BundleUtils.isIsolatedSplitInstalled(mContext, FEED_SPLIT_NAME)) {
+        if (BundleUtils.isIsolatedSplitInstalled(FEED_SPLIT_NAME)) {
             mLibraryResolver = (libName) -> {
                 return BundleUtils.getNativeLibraryPath(libName, FEED_SPLIT_NAME);
             };
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
index 627d07f..a23f0a6 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
@@ -674,12 +674,19 @@
         mFeedAutoplaySettingsDelegate = feedAutoplaySettingsDelegate;
         mRotationObserver = new RotationObserver();
         mFeedContentFirstLoadWatcher = feedContentFirstLoadWatcher;
-        WebFeedSnackbarController.FeedLauncher switchToFollowing = () -> {
-            // Note: for now there's no need to store streamsMediator as an instance variable.
-            streamsMediator.switchToStreamKind(StreamKind.FOLLOWING);
-        };
-        mWebFeedSnackbarController = new WebFeedSnackbarController(activity, switchToFollowing,
-                windowAndroid.getModalDialogManager(), snackbarManager);
+        WebFeedSnackbarController.FeedLauncher snackbarAction;
+        // Note: for now there's no need to store streamsMediator as an instance variable.
+        if (mStreamKind == StreamKind.FOLLOWING) {
+            snackbarAction = () -> {
+                streamsMediator.refreshStream();
+            };
+        } else {
+            snackbarAction = () -> {
+                streamsMediator.switchToStreamKind(StreamKind.FOLLOWING);
+            };
+        }
+        mWebFeedSnackbarController = new WebFeedSnackbarController(
+                activity, snackbarAction, windowAndroid.getModalDialogManager(), snackbarManager);
 
         mHandlersMap = new HashMap<>();
         mHandlersMap.put(SurfaceActionsHandler.KEY, new FeedSurfaceActionsHandler(actionDelegate));
@@ -803,6 +810,7 @@
             mSnackManager.dismissSnackbars(controller);
         }
         mSnackbarControllers.clear();
+        mWebFeedSnackbarController.dismissSnackbars();
 
         mSliceViewTracker.destroy();
         mSliceViewTracker = null;
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
index 40a76b9..997cf37 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
@@ -28,6 +28,11 @@
          * @param streamKind The {@link StreamKind} of the stream to switch to.
          */
         void switchToStreamKind(@StreamKind int streamKind);
+
+        /**
+         * Request the immediate refresh of the contents of the active stream.
+         */
+        void refreshStream();
     }
     /** Called when the Stream is no longer needed. */
     default void destroy() {}
@@ -64,7 +69,7 @@
     /**
      * Allow the container to trigger a refresh of the stream.
      *
-     * <p>Note: this will assume {@link RequestReason.HOST_REQUESTED}.
+     * <p>Note: this will assume {@link RequestReason.MANUAL_REFRESH}.
      */
     void triggerRefresh(Callback<Boolean> callback);
 
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java
index f91f1c87..e7c85b1f 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java
@@ -59,6 +59,7 @@
 
     /** Expands this view to full height. */
     private void expand() {
+        if (this.getParent() == null) return;
         // Width is match_parent and height is wrap_content.
         int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
                 ((ViewGroup) getParent()).getWidth(), View.MeasureSpec.EXACTLY);
@@ -96,6 +97,7 @@
 
     /** Collapses this view to 0 height and then marks it GONE. */
     private void collapse() {
+        if (this.getParent() == null) return;
         int initialHeight = getMeasuredHeight();
 
         Animation animation = new Animation() {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogCoordinator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogCoordinator.java
index 7519928..c67abe64 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogCoordinator.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogCoordinator.java
@@ -71,7 +71,8 @@
             feedLauncher.openFollowingFeed();
         };
         initializeInternal(context, positiveAction,
-                R.string.web_feed_post_follow_dialog_go_to_following, title, isActive);
+                R.string.web_feed_post_follow_dialog_go_to_following, title, isActive,
+                /*hasCloseAction=*/true);
     }
 
     /**
@@ -90,16 +91,16 @@
             if (activeAction != null) activeAction.run();
         };
         initializeInternal(context, positiveAction, R.string.web_feed_post_follow_dialog_got_it,
-                title, isActive);
+                title, isActive, /*hasCloseAction=*/false);
     }
 
     private void initializeInternal(Context context, Runnable positiveAction,
-            int positiveActionLabelId, String title, boolean isActive) {
+            int positiveActionLabelId, String title, boolean isActive, boolean hasCloseAction) {
         mContext = context;
         View webFeedDialogView =
                 LayoutInflater.from(context).inflate(R.layout.web_feed_dialog, null);
-        WebFeedDialogContents dialogContents =
-                buildDialogContents(positiveAction, positiveActionLabelId, title, isActive);
+        WebFeedDialogContents dialogContents = buildDialogContents(
+                positiveAction, positiveActionLabelId, title, isActive, hasCloseAction);
         PropertyModel model = buildModel(dialogContents);
         mMediator.initialize(webFeedDialogView, dialogContents);
         PropertyModelChangeProcessor.create(
@@ -110,8 +111,8 @@
         mMediator.showDialog();
     }
 
-    private WebFeedDialogContents buildDialogContents(
-            Runnable positiveAction, int positiveActionLabelId, String title, boolean isActive) {
+    private WebFeedDialogContents buildDialogContents(Runnable positiveAction,
+            int positiveActionLabelId, String title, boolean isActive, boolean hasCloseAction) {
         RecordHistogram.recordEnumeratedHistogram(
                 "ContentSuggestions.Feed.WebFeed.PostFollowDialog.Show",
                 isActive ? WebFeedPostFollowDialogPresentation.AVAILABLE
@@ -126,11 +127,12 @@
             description = mContext.getString(
                     R.string.web_feed_post_follow_dialog_stories_ready_description, title);
             primaryButtonText = mContext.getString(positiveActionLabelId);
-            secondaryButtonText = mContext.getString(R.string.close);
+            secondaryButtonText = hasCloseAction ? mContext.getString(R.string.close) : null;
             buttonClickCallback = dismissalCause -> {
                 if (dismissalCause.equals(DialogDismissalCause.POSITIVE_BUTTON_CLICKED)) {
                     positiveAction.run();
                 } else {
+                    assert hasCloseAction : "Secondary close action must be enabled";
                     FeedServiceBridge.reportOtherUserAction(StreamKind.UNKNOWN,
                             FeedUserActionType.TAPPED_DISMISS_POST_FOLLOW_ACTIVE_HELP);
                 }
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarController.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarController.java
index c4e2d53..d8db18ae 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarController.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarController.java
@@ -26,6 +26,8 @@
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.url.GURL;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -34,6 +36,8 @@
 public class WebFeedSnackbarController {
     /**
      * A helper interface for exposing a method to launch the feed.
+     * TODO(carlosk): replace this interface with a standard Runnable because the action executed is
+     * not always opening the Following feed.
      */
     @FunctionalInterface
     public interface FeedLauncher {
@@ -46,6 +50,7 @@
     private final FeedLauncher mFeedLauncher;
     private final SnackbarManager mSnackbarManager;
     private final WebFeedDialogCoordinator mWebFeedDialogCoordinator;
+    private final List<SnackbarController> mActiveControllers = new ArrayList<>();
 
     /**
      * Constructs an instance of {@link WebFeedSnackbarController}.
@@ -134,27 +139,48 @@
                         .shouldTriggerHelpUI(
                                 FeatureConstants.IPH_WEB_FEED_POST_FOLLOW_DIALOG_FEATURE)) {
             if (followFromFeed == StreamKind.FOLLOWING) {
+                Runnable launchSnackbar = null;
+                if (isActive) {
+                    // A snackback will be shown after the dialog is closed to offer the refresh
+                    // action.
+                    launchSnackbar = () -> {
+                        showPostSuccessfulSnackbar(title, followFromFeed);
+                    };
+                };
                 mWebFeedDialogCoordinator.initializeForInFollowingFollow(
-                        mContext, null, title, isActive);
+                        mContext, launchSnackbar, title, isActive);
             } else {
                 mWebFeedDialogCoordinator.initialize(mContext, mFeedLauncher, title, isActive);
             }
             mWebFeedDialogCoordinator.showDialog();
-        } else if (followFromFeed != StreamKind.FOLLOWING) {
-            SnackbarController snackbarController = new PinnedSnackbarController() {
-                @Override
-                public void onAction(Object actionData) {
-                    super.onAction(actionData);
-                    mFeedLauncher.openFollowingFeed();
-                }
-            };
-            showSnackbar(
-                    mContext.getString(R.string.web_feed_follow_success_snackbar_message, title),
-                    snackbarController, Snackbar.UMA_WEB_FEED_FOLLOW_SUCCESS,
-                    R.string.web_feed_follow_success_snackbar_action_go_to_following);
+        } else {
+            showPostSuccessfulSnackbar(title, followFromFeed);
         }
     }
 
+    private void showPostSuccessfulSnackbar(String title, @StreamKind int followFromFeed) {
+        SnackbarController snackbarController = new PinnedSnackbarController() {
+            @Override
+            public void onAction(Object actionData) {
+                super.onAction(actionData);
+                @FeedUserActionType
+                int userActionType = followFromFeed == StreamKind.FOLLOWING
+                        ? FeedUserActionType.TAPPED_REFRESH_FOLLOWING_FEED_ON_SNACKBAR
+                        : FeedUserActionType.TAPPED_GO_TO_FEED_ON_SNACKBAR;
+                FeedServiceBridge.reportOtherUserAction(StreamKind.UNKNOWN, userActionType);
+                // TODO(carlosk): The openFollowingFeed call may actually also cause the refresh of
+                // the Following feed, hence the need to replace FeeLauncher with a more generic
+                // interface.
+                mFeedLauncher.openFollowingFeed();
+            }
+        };
+        int actionLabelId = followFromFeed == StreamKind.FOLLOWING
+                ? R.string.web_feed_follow_success_snackbar_action_refresh
+                : R.string.web_feed_follow_success_snackbar_action_go_to_following;
+        showSnackbar(mContext.getString(R.string.web_feed_follow_success_snackbar_message, title),
+                snackbarController, Snackbar.UMA_WEB_FEED_FOLLOW_SUCCESS, actionLabelId);
+    }
+
     private void showUnfollowSuccessSnackbar(
             byte[] followId, GURL url, String title, int webFeedChangeReason) {
         showSnackbar(mContext.getString(R.string.web_feed_unfollow_success_snackbar_message, title),
@@ -203,6 +229,16 @@
     }
 
     /**
+     * Dismisses all active snackbars created by this conotroller.
+     */
+    public void dismissSnackbars() {
+        // A copy is needed as controllers will self-remove from the list.
+        List<SnackbarController> controllersCopy = new ArrayList(mActiveControllers);
+        controllersCopy.forEach((c) -> { mSnackbarManager.dismissSnackbars(c); });
+        assert mActiveControllers.isEmpty();
+    }
+
+    /**
      * A snackbar controller which dismisses the snackbar if the feed surface is shown, and
      *  optionally, upon navigation to a different URL.
      */
@@ -214,16 +250,19 @@
 
         PinnedSnackbarController() {
             FeedSurfaceTracker.getInstance().addObserver(this);
+            mActiveControllers.add(this);
         }
 
         @Override
         public void onAction(Object actionData) {
             unregisterObservers();
+            mActiveControllers.remove(this);
         }
 
         @Override
         public void onDismissNoAction(Object actionData) {
             unregisterObservers();
+            mActiveControllers.remove(this);
         }
 
         @Override
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarControllerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarControllerTest.java
index 2ba9f65..0f2944e 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarControllerTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedSnackbarControllerTest.java
@@ -55,6 +55,7 @@
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.components.feature_engagement.TriggerDetails;
+import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
 import org.chromium.url.GURL;
@@ -171,14 +172,28 @@
                 mContext.getString(R.string.web_feed_follow_success_snackbar_message,
                         getSuccessfulFollowResult().metadata.title),
                 snackbar.getTextForTesting());
+        assertEquals("Snackbar action should be for going to the Following feed.",
+                mContext.getString(
+                        R.string.web_feed_follow_success_snackbar_action_go_to_following),
+                snackbar.getActionText());
     }
 
     @Test
-    public void showPostSuccessfulFollowHelp_NoSnackbar_FromFollowingFeed() {
+    public void showPostSuccessfulFollowHelp_ShowsSnackbar_FromFollowingFeed() {
         mWebFeedSnackbarController.showPostSuccessfulFollowHelp(sTitle, true, StreamKind.FOLLOWING);
 
         assertFalse("Dialog should not be showing.", mDialogManager.isShowing());
-        verify(mSnackbarManager, times(0)).showSnackbar(any());
+        verify(mSnackbarManager).showSnackbar(mSnackbarCaptor.capture());
+        Snackbar snackbar = mSnackbarCaptor.getValue();
+        assertEquals("Snackbar should be for successful follow.",
+                Snackbar.UMA_WEB_FEED_FOLLOW_SUCCESS, snackbar.getIdentifierForTesting());
+        assertEquals("Snackbar message should be for successful follow with title from metadata.",
+                mContext.getString(R.string.web_feed_follow_success_snackbar_message,
+                        getSuccessfulFollowResult().metadata.title),
+                snackbar.getTextForTesting());
+        assertEquals("Snackbar action should be for refreshing the contents of the feed.",
+                mContext.getString(R.string.web_feed_follow_success_snackbar_action_refresh),
+                snackbar.getActionText());
     }
 
     @Test
@@ -249,10 +264,45 @@
 
         View currentDialog =
                 mDialogManager.getCurrentDialogForTest().get(ModalDialogProperties.CUSTOM_VIEW);
-        verify(mSnackbarManager, times(0)).showSnackbar(any());
         assertTrue("Dialog should be showing.", mDialogManager.isShowing());
         // TODO(b/243676323): figure out how to test the positive_button label, which is out of the
         // currentDialog hierarchy.
+
+        // No snackbar should be shown after the dialog is closed.
+        mDialogManager.dismissAllDialogs(DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
+        verify(mSnackbarManager, times(0)).showSnackbar(any());
+    }
+
+    @Test
+    public void showPostSuccessfulFollowHelp_DialogAndSnackbar_FromFollowingFeed() {
+        when(mTracker.shouldTriggerHelpUI(FeatureConstants.IPH_WEB_FEED_POST_FOLLOW_DIALOG_FEATURE))
+                .thenReturn(true);
+        when(mTracker.shouldTriggerHelpUIWithSnooze(
+                     FeatureConstants.IPH_WEB_FEED_POST_FOLLOW_DIALOG_FEATURE))
+                .thenReturn(new TriggerDetails(true, false));
+
+        mWebFeedSnackbarController.showPostSuccessfulFollowHelp(sTitle, true, StreamKind.FOLLOWING);
+
+        verify(mSnackbarManager, times(0)).showSnackbar(any());
+        View currentDialog =
+                mDialogManager.getCurrentDialogForTest().get(ModalDialogProperties.CUSTOM_VIEW);
+        assertTrue("Dialog should be showing.", mDialogManager.isShowing());
+        // TODO(b/243676323): figure out how to test the positive_button label, which is out of the
+        // currentDialog hierarchy.
+
+        // A snackbar should be shown when the dialog is closed, offering the refresh action.
+        mDialogManager.dismissAllDialogs(DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
+        verify(mSnackbarManager).showSnackbar(mSnackbarCaptor.capture());
+        Snackbar snackbar = mSnackbarCaptor.getValue();
+        assertEquals("Snackbar should be for successful follow.",
+                Snackbar.UMA_WEB_FEED_FOLLOW_SUCCESS, snackbar.getIdentifierForTesting());
+        assertEquals("Snackbar message should be for successful follow with title from metadata.",
+                mContext.getString(R.string.web_feed_follow_success_snackbar_message,
+                        getSuccessfulFollowResult().metadata.title),
+                snackbar.getTextForTesting());
+        assertEquals("Snackbar action should be for refreshing the contents of the feed.",
+                mContext.getString(R.string.web_feed_follow_success_snackbar_action_refresh),
+                snackbar.getActionText());
     }
 
     @Test
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index b86e5c0b..6a7ea382 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -288,7 +288,7 @@
   {
     "name": "ash-bento-bar",
     "owners": [ "minch", "janetmac" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 116
   },
   {
     "name": "ash-debug-shortcuts",
@@ -566,11 +566,6 @@
     "expiry_milestone": 112
   },
   {
-    "name": "autofill-parse-merchant-promo-code-fields",
-    "owners": [ "jsaul@google.com", "payments-autofill-team@google.com" ],
-    "expiry_milestone": 112
-  },
-  {
     "name": "autofill-parse-vcn-card-on-file-standalone-cvc-fields",
     "owners": [ "jsaul@google.com", "alexandertekle@google.com" ],
     "expiry_milestone": 120
@@ -2138,6 +2133,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "enable-download-service-foreground-session",
+    "owners": [ "rajendrant", "mcrouse", "chrome-intelligence-core@google.com" ],
+    "expiry_milestone": 116
+  },
+  {
     "name": "enable-drdc",
     "owners": [ "vikassoni", "sunnyps" ],
     "expiry_milestone": 118
@@ -2185,12 +2185,12 @@
   {
     "name": "enable-experimental-accessibility-language-detection",
     "owners": [ "chrishall", "//ui/accessibility/OWNERS" ],
-    "expiry_milestone": 106
+    "expiry_milestone": 130
   },
   {
     "name": "enable-experimental-accessibility-language-detection-dynamic",
     "owners": [ "chrishall", "//ui/accessibility/OWNERS" ],
-    "expiry_milestone": 106
+    "expiry_milestone": 130
   },
   {
     "name": "enable-experimental-accessibility-select-to-speak-voice-switching",
@@ -3112,12 +3112,12 @@
   {
     "name": "enable-tflite-language-detection",
     "owners": [ "sophiechang", "chrome-intelligence-core@google.com" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 116
   },
   {
     "name": "enable-tflite-language-detection-ignore",
     "owners": [ "mcrouse", "chrome-intelligence-core@google.com" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 116
   },
   {
     "name": "enable-throttle-display-none-and-visibility-hidden-cross-origin-iframes",
@@ -3853,7 +3853,7 @@
   {
     "name": "fullscreen-promos-manager",
     "owners": [ "bwwilliams@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 109
+    "expiry_milestone": 113
   },
   {
     "name": "fullscreen-promos-manager-skip-internal-limits",
@@ -5535,11 +5535,6 @@
     "expiry_milestone": 118
   },
   {
-    "name": "performant-split-view-resizing",
-    "owners": [ "dandersson", "riomat" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "permission-chip",
     "owners": [ "elklm", "bsep", "engedy", "olesiamarukhno@google.com" ],
     "expiry_milestone": 110
@@ -6297,7 +6292,7 @@
   {
     "name": "sim-lock-policy",
     "owners": [ "hsuregan@google.com", "cros-connectivity@google.com" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 112
   },
   {
     "name": "site-data-improvements",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 2e87ed4e..ac6cb01d 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -492,12 +492,6 @@
     "When enabled, Autofill will attempt to find International Bank Account "
     "Number (IBAN) fields when parsing forms.";
 
-const char kAutofillParseMerchantPromoCodeFieldsName[] =
-    "Parse promo code fields in forms";
-const char kAutofillParseMerchantPromoCodeFieldsDescription[] =
-    "When enabled, Autofill will attempt to find merchant promo/coupon/gift "
-    "code fields when parsing forms.";
-
 const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsName[] =
     "Parse standalone CVC fields for VCN card on file in forms";
 const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 4375e79..1945323 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -271,9 +271,6 @@
 extern const char kAutofillParseIBANFieldsName[];
 extern const char kAutofillParseIBANFieldsDescription[];
 
-extern const char kAutofillParseMerchantPromoCodeFieldsName[];
-extern const char kAutofillParseMerchantPromoCodeFieldsDescription[];
-
 extern const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsName[];
 extern const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsDescription[];
 
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn
index 998075fc..a2ac4f3 100644
--- a/chrome/browser/flags/BUILD.gn
+++ b/chrome/browser/flags/BUILD.gn
@@ -16,7 +16,6 @@
     "android/java/src/org/chromium/chrome/browser/flags/ChromeSessionState.java",
     "android/java/src/org/chromium/chrome/browser/flags/DoubleCachedFieldTrialParameter.java",
     "android/java/src/org/chromium/chrome/browser/flags/FeatureParamUtils.java",
-    "android/java/src/org/chromium/chrome/browser/flags/Flag.java",
     "android/java/src/org/chromium/chrome/browser/flags/IntCachedFieldTrialParameter.java",
     "android/java/src/org/chromium/chrome/browser/flags/MutableFlagWithSafeDefault.java",
     "android/java/src/org/chromium/chrome/browser/flags/PostNativeFlag.java",
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/BaseFlagTestRule.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/BaseFlagTestRule.java
index f80cf58..a6a6a00 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/BaseFlagTestRule.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/BaseFlagTestRule.java
@@ -11,6 +11,7 @@
 import org.junit.runners.model.Statement;
 
 import org.chromium.base.FeatureList;
+import org.chromium.base.Flag;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlag.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlag.java
index 0c716b2..f4ed5ec 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlag.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlag.java
@@ -7,6 +7,8 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.base.Flag;
+
 /**
  * Flags of this type may be used before native is loaded and return the value read
  * from native and cached to SharedPreferences in a previous run.
@@ -25,6 +27,9 @@
         return CachedFeatureFlags.isEnabled(mFeatureName, mDefaultValue);
     }
 
+    @Override
+    protected void clearInMemoryCachedValueForTesting() {}
+
     @VisibleForTesting
     public void setForTesting(@Nullable Boolean value) {
         CachedFeatureFlags.setForTesting(mFeatureName, value);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/Flag.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/Flag.java
deleted file mode 100644
index 22f577c..0000000
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/Flag.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.flags;
-
-import java.util.HashSet;
-
-/**
- * Defines a feature flag for use in Java.
- *
- * Duplicate flag definitions are not permitted, so only a single
- * instance can be created with a given feature name.
- *
- * To create a flag, instantiate a subclass of Flag, either {@link CachedFlag},
- * {@link MutableFlagWithSafeDefault} or {@link PostNativeFlag}.
- */
-public abstract class Flag {
-    private static HashSet<String> sFlagsCreated = new HashSet<>();
-    protected final String mFeatureName;
-
-    Flag(String featureName) {
-        assert !sFlagsCreated.contains(featureName);
-        mFeatureName = featureName;
-        sFlagsCreated.add(mFeatureName);
-    }
-
-    /**
-     * Checks if a feature flag is enabled.
-     * @return whether the feature should be considered enabled.
-     */
-    public abstract boolean isEnabled();
-
-    static void resetFlagsForTesting() {
-        sFlagsCreated.clear();
-    }
-}
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FlagUnitTest.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FlagUnitTest.java
index 3aa4cfd..97d619a 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FlagUnitTest.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FlagUnitTest.java
@@ -10,6 +10,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.Flag;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 
 /**
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/MutableFlagWithSafeDefault.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/MutableFlagWithSafeDefault.java
index fa106b2..421d3bb14 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/MutableFlagWithSafeDefault.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/MutableFlagWithSafeDefault.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.flags;
 
 import org.chromium.base.FeatureList;
+import org.chromium.base.Flag;
 
 /**
  * Flags of this type are un-cached flags that may be called before native,
@@ -17,6 +18,7 @@
  */
 public class MutableFlagWithSafeDefault extends Flag {
     private final boolean mDefaultValue;
+    private Boolean mInMemoryCachedValue;
 
     public MutableFlagWithSafeDefault(String featureName, boolean defaultValue) {
         super(featureName);
@@ -25,14 +27,21 @@
 
     @Override
     public boolean isEnabled() {
-        if (isFeatureListInitialized(mFeatureName)) {
+        if (mInMemoryCachedValue != null) return mInMemoryCachedValue;
+        if (FeatureList.hasTestFeature(mFeatureName)) {
             return ChromeFeatureList.isEnabled(mFeatureName);
-        } else {
-            return mDefaultValue;
         }
+
+        if (FeatureList.isNativeInitialized()) {
+            mInMemoryCachedValue = ChromeFeatureList.isEnabled(mFeatureName);
+            return mInMemoryCachedValue;
+        }
+
+        return mDefaultValue;
     }
 
-    private static boolean isFeatureListInitialized(String featureName) {
-        return FeatureList.hasTestFeature(featureName) || FeatureList.isNativeInitialized();
+    @Override
+    protected void clearInMemoryCachedValueForTesting() {
+        mInMemoryCachedValue = null;
     }
-}
+}
\ No newline at end of file
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/PostNativeFlag.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/PostNativeFlag.java
index e1c18d4..30732c9a 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/PostNativeFlag.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/PostNativeFlag.java
@@ -4,16 +4,32 @@
 
 package org.chromium.chrome.browser.flags;
 
+import org.chromium.base.FeatureList;
+import org.chromium.base.Flag;
+
 /**
  * Flags of this type assume native is loaded and the value can be retrieved directly from native.
  */
 public class PostNativeFlag extends Flag {
+    private Boolean mInMemoryCachedValue;
     public PostNativeFlag(String featureName) {
         super(featureName);
     }
 
     @Override
     public boolean isEnabled() {
-        return ChromeFeatureList.isEnabled(mFeatureName);
+        if (mInMemoryCachedValue != null) return mInMemoryCachedValue;
+
+        if (FeatureList.hasTestFeature(mFeatureName)) {
+            return ChromeFeatureList.isEnabled(mFeatureName);
+        }
+
+        mInMemoryCachedValue = ChromeFeatureList.isEnabled(mFeatureName);
+        return mInMemoryCachedValue;
+    }
+
+    @Override
+    protected void clearInMemoryCachedValueForTesting() {
+        mInMemoryCachedValue = null;
     }
 }
diff --git a/chrome/browser/metrics/power/battery_discharge_reporter.cc b/chrome/browser/metrics/power/battery_discharge_reporter.cc
index 3c6a40f..61bd158 100644
--- a/chrome/browser/metrics/power/battery_discharge_reporter.cc
+++ b/chrome/browser/metrics/power/battery_discharge_reporter.cc
@@ -82,8 +82,8 @@
   // suffix.
   const std::vector<const char*> long_interval_suffixes{
       "", long_interval_scenario_params.histogram_suffix};
-  ReportAlignedBatteryHistograms(sampling_event_delta, battery_discharge,
-                                 is_initial_interval_, long_interval_suffixes);
+  ReportBatteryHistograms(sampling_event_delta, battery_discharge,
+                          is_initial_interval_, long_interval_suffixes);
   is_initial_interval_ = false;
 }
 
diff --git a/chrome/browser/metrics/power/battery_discharge_reporter_unittest.cc b/chrome/browser/metrics/power/battery_discharge_reporter_unittest.cc
index 91c226ca..5c22859 100644
--- a/chrome/browser/metrics/power/battery_discharge_reporter_unittest.cc
+++ b/chrome/browser/metrics/power/battery_discharge_reporter_unittest.cc
@@ -104,6 +104,33 @@
       const BatteryDischargeReporterTest& rhs) = delete;
   ~BatteryDischargeReporterTest() override = default;
 
+  // Tests that the right BatteryDischargeMode histogram sample is emitted given
+  // the battery states before and after an interval.
+  void TestBatteryDischargeMode(
+      const absl::optional<base::BatteryLevelProvider::BatteryState>&
+          previous_battery_state,
+      const absl::optional<base::BatteryLevelProvider::BatteryState>&
+          new_battery_state,
+      BatteryDischargeMode expected_mode) {
+    TestUsageScenarioDataStoreImpl usage_scenario_data_store;
+
+    base::BatteryStateSampler battery_state_sampler(
+        std::make_unique<NoopSamplingEventSource>(),
+        std::make_unique<NoopBatteryLevelProvider>());
+    BatteryDischargeReporter battery_discharge_reporter(
+        &battery_state_sampler, &usage_scenario_data_store);
+
+    battery_discharge_reporter.OnBatteryStateSampled(previous_battery_state);
+    task_environment_.FastForwardBy(base::Minutes(1));
+    battery_discharge_reporter.OnBatteryStateSampled(new_battery_state);
+
+    const std::vector<const char*> suffixes(
+        {"", ".Initial", ".ZeroWindow", ".ZeroWindow.Initial"});
+    ExpectHistogramSamples(&histogram_tester_, suffixes,
+                           {{kBatteryDischargeModeHistogramName,
+                             static_cast<int>(expected_mode)}});
+  }
+
  protected:
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
@@ -253,3 +280,145 @@
   histogram_tester_.ExpectTotalCount(kBatteryDischargeRateRelativeHistogramName,
                                      1);
 }
+
+TEST_F(BatteryDischargeReporterTest, RetrievalError) {
+  TestBatteryDischargeMode(absl::nullopt, absl::nullopt,
+                           BatteryDischargeMode::kRetrievalError);
+}
+
+TEST_F(BatteryDischargeReporterTest, StateChanged_Battery) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 0,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+      },
+      BatteryDischargeMode::kStateChanged);
+}
+
+TEST_F(BatteryDischargeReporterTest, StateChanged_PluggedIn) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = true,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+      },
+      BatteryDischargeMode::kStateChanged);
+}
+
+TEST_F(BatteryDischargeReporterTest, NoBattery) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 0,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 0,
+      },
+      BatteryDischargeMode::kNoBattery);
+}
+
+TEST_F(BatteryDischargeReporterTest, PluggedIn) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = true,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = true,
+      },
+      BatteryDischargeMode::kPluggedIn);
+}
+
+TEST_F(BatteryDischargeReporterTest, MultipleBatteries) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 2,
+          .is_external_power_connected = false,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 2,
+          .is_external_power_connected = false,
+      },
+      BatteryDischargeMode::kMultipleBatteries);
+}
+
+TEST_F(BatteryDischargeReporterTest, InsufficientResolution) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .charge_unit =
+              base::BatteryLevelProvider::BatteryLevelUnit::kRelative,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .charge_unit =
+              base::BatteryLevelProvider::BatteryLevelUnit::kRelative,
+      },
+      BatteryDischargeMode::kInsufficientResolution);
+}
+
+#if BUILDFLAG(IS_MAC)
+TEST_F(BatteryDischargeReporterTest, MacFullyCharged) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 100,
+          .full_charged_capacity = 100,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 99,
+          .full_charged_capacity = 100,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      BatteryDischargeMode::kMacFullyCharged);
+}
+#endif  // BUILDFLAG(IS_MAC)
+
+TEST_F(BatteryDischargeReporterTest, FullChargedCapacityIsZero) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 10,
+          .full_charged_capacity = 0,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 10,
+          .full_charged_capacity = 0,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      BatteryDischargeMode::kFullChargedCapacityIsZero);
+}
+
+TEST_F(BatteryDischargeReporterTest, BatteryLevelIncreased) {
+  TestBatteryDischargeMode(
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 40,
+          .full_charged_capacity = 100,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      base::BatteryLevelProvider::BatteryState{
+          .battery_count = 1,
+          .is_external_power_connected = false,
+          .current_capacity = 50,
+          .full_charged_capacity = 100,
+          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
+      },
+      BatteryDischargeMode::kBatteryLevelIncreased);
+}
diff --git a/chrome/browser/metrics/power/power_metrics.cc b/chrome/browser/metrics/power/power_metrics.cc
index 54c8cfa..1eeaac4 100644
--- a/chrome/browser/metrics/power/power_metrics.cc
+++ b/chrome/browser/metrics/power/power_metrics.cc
@@ -16,16 +16,11 @@
 
 namespace {
 
-constexpr const char* kBatteryDischargeRateHistogramName =
-    "Power.BatteryDischargeRate2";
-constexpr const char* kBatteryDischargeModeHistogramName =
-    "Power.BatteryDischargeMode2";
-
-constexpr const char* kAlignedBatteryDischargeRateMilliwattsHistogramName =
+constexpr const char* kBatteryDischargeRateMilliwattsHistogramName =
     "Power.BatteryDischargeRateMilliwatts5";
-constexpr const char* kAlignedBatteryDischargeRateRelativeHistogramName =
+constexpr const char* kBatteryDischargeRateRelativeHistogramName =
     "Power.BatteryDischargeRateRelative5";
-constexpr const char* kAlignedBatteryDischargeModeHistogramName =
+constexpr const char* kBatteryDischargeModeHistogramName =
     "Power.BatteryDischargeMode5";
 
 #if BUILDFLAG(IS_MAC)
@@ -177,8 +172,9 @@
   const auto discharge_rate_mw = CalculateDischargeRateMilliwatts(
       previous_battery_state, new_battery_state, interval_duration);
 
-  if (discharge_rate_relative < 0 || discharge_rate_mw < 0)
+  if (discharge_rate_relative < 0 || discharge_rate_mw < 0) {
     return {BatteryDischargeMode::kBatteryLevelIncreased, absl::nullopt};
+  }
   return {BatteryDischargeMode::kDischarging, discharge_rate_mw,
           discharge_rate_relative};
 }
@@ -186,24 +182,6 @@
 void ReportBatteryHistograms(
     base::TimeDelta interval_duration,
     BatteryDischarge battery_discharge,
-    const std::vector<const char*>& scenario_suffixes) {
-  for (const char* scenario_suffix : scenario_suffixes) {
-    base::UmaHistogramEnumeration(
-        base::StrCat({kBatteryDischargeModeHistogramName, scenario_suffix}),
-        battery_discharge.mode);
-
-    if (battery_discharge.mode == BatteryDischargeMode::kDischarging) {
-      DCHECK(battery_discharge.rate_relative.has_value());
-      base::UmaHistogramCounts1000(
-          base::StrCat({kBatteryDischargeRateHistogramName, scenario_suffix}),
-          *battery_discharge.rate_relative);
-    }
-  }
-}
-
-void ReportAlignedBatteryHistograms(
-    base::TimeDelta interval_duration,
-    BatteryDischarge battery_discharge,
     bool is_initial_interval,
     const std::vector<const char*>& scenario_suffixes) {
   const char* interval_type_suffixes[] = {
@@ -212,19 +190,19 @@
   for (const char* scenario_suffix : scenario_suffixes) {
     for (const char* interval_type_suffix : interval_type_suffixes) {
       base::UmaHistogramEnumeration(
-          base::StrCat({kAlignedBatteryDischargeModeHistogramName,
-                        scenario_suffix, interval_type_suffix}),
+          base::StrCat({kBatteryDischargeModeHistogramName, scenario_suffix,
+                        interval_type_suffix}),
           battery_discharge.mode);
 
       if (battery_discharge.mode == BatteryDischargeMode::kDischarging) {
         DCHECK(battery_discharge.rate_milliwatts.has_value());
         base::UmaHistogramCounts100000(
-            base::StrCat({kAlignedBatteryDischargeRateMilliwattsHistogramName,
+            base::StrCat({kBatteryDischargeRateMilliwattsHistogramName,
                           scenario_suffix, interval_type_suffix}),
             *battery_discharge.rate_milliwatts);
         DCHECK(battery_discharge.rate_relative.has_value());
         base::UmaHistogramCounts1000(
-            base::StrCat({kAlignedBatteryDischargeRateRelativeHistogramName,
+            base::StrCat({kBatteryDischargeRateRelativeHistogramName,
                           scenario_suffix, interval_type_suffix}),
             *battery_discharge.rate_relative);
       }
diff --git a/chrome/browser/metrics/power/power_metrics.h b/chrome/browser/metrics/power/power_metrics.h
index 00cf194..c9fd6af 100644
--- a/chrome/browser/metrics/power/power_metrics.h
+++ b/chrome/browser/metrics/power/power_metrics.h
@@ -61,17 +61,9 @@
 // Report battery metrics to histograms with |scenario_suffixes|.
 void ReportBatteryHistograms(base::TimeDelta interval_duration,
                              BatteryDischarge battery_discharge,
+                             bool is_initial_interval,
                              const std::vector<const char*>& scenario_suffixes);
 
-// Report battery metrics to histograms with |scenario_suffixes|. The difference
-// with the above version is that when possible, the intervals are aligned with
-// battery discharge notifications from the OS (MacOS only for now).
-void ReportAlignedBatteryHistograms(
-    base::TimeDelta interval_duration,
-    BatteryDischarge battery_discharge,
-    bool is_initial_interval,
-    const std::vector<const char*>& scenario_suffixes);
-
 #if BUILDFLAG(IS_MAC)
 void ReportShortIntervalHistograms(
     const char* scenario_suffix,
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.cc b/chrome/browser/metrics/power/power_metrics_reporter.cc
index b3e430d..b495992 100644
--- a/chrome/browser/metrics/power/power_metrics_reporter.cc
+++ b/chrome/browser/metrics/power/power_metrics_reporter.cc
@@ -32,12 +32,6 @@
 constexpr const char* kBatterySamplingDelayHistogramName =
     "Power.BatterySamplingDelay";
 
-bool IsWithinTolerance(base::TimeDelta value,
-                       base::TimeDelta expected,
-                       base::TimeDelta tolerance) {
-  return (value - expected).magnitude() < tolerance;
-}
-
 // Calculates the UKM bucket |value| falls in and returns it. This uses an
 // exponential bucketing approach with an exponent base of 1.3, resulting in
 // 17 buckets for an interval of 120 seconds.
@@ -348,22 +342,6 @@
   // Report UKMs.
   ReportBatteryUKMs(long_interval_data, aggregated_process_metrics,
                     interval_duration, battery_discharge);
-
-  // Ratio by which the time elapsed can deviate from
-  // |kLongPowerMetricsIntervalDuration| without invalidating this sample.
-  // TODO(pmonette): Change to DCHECK after ensuring this never triggers.
-  CHECK_GE(interval_duration, kLongPowerMetricsIntervalDuration);
-  constexpr double kTolerableTimeElapsedRatio = 0.10;
-  if (battery_discharge.mode == BatteryDischargeMode::kDischarging &&
-      !IsWithinTolerance(
-          interval_duration, kLongPowerMetricsIntervalDuration,
-          kLongPowerMetricsIntervalDuration * kTolerableTimeElapsedRatio)) {
-    battery_discharge.mode = BatteryDischargeMode::kInvalidInterval;
-  }
-
-  ReportBatteryHistograms(
-      interval_duration, battery_discharge,
-      {"", GetLongIntervalScenario(long_interval_data).histogram_suffix});
 }
 
 void PowerMetricsReporter::ReportBatteryUKMs(
diff --git a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
index b239e87..709a7a36 100644
--- a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
+++ b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
@@ -29,14 +29,6 @@
 
 namespace {
 
-constexpr const char* kBatteryDischargeRateHistogramName =
-    "Power.BatteryDischargeRate2";
-constexpr const char* kBatteryDischargeModeHistogramName =
-    "Power.BatteryDischargeMode2";
-
-constexpr double kTolerableTimeElapsedRatio = 0.10;
-constexpr double kTolerablePositiveDrift = 1 + kTolerableTimeElapsedRatio;
-
 base::BatteryLevelProvider::BatteryState MakeBatteryDischargingState(
     int battery_percent) {
   return base::BatteryLevelProvider::BatteryState{
@@ -327,43 +319,6 @@
 }
 #endif
 
-TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsTooLate) {
-  ProcessMonitor::Metrics aggregated_process_metrics = {};
-  process_monitor_.SetMetricsToReturn(aggregated_process_metrics);
-
-  // Pretend that the battery has dropped by 2%.
-  battery_states_.push(MakeBatteryDischargingState(48));
-
-  const base::TimeDelta kTooLate =
-      kLongPowerMetricsIntervalDuration * kTolerablePositiveDrift +
-      base::Microseconds(1);
-  process_monitor_.ForceSampleAllProcessesIn(power_metrics_reporter_.get(),
-                                             &task_environment_, kTooLate);
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kInvalidInterval,
-                                       1);
-}
-
-TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsLate) {
-  ProcessMonitor::Metrics aggregated_process_metrics = {};
-  process_monitor_.SetMetricsToReturn(aggregated_process_metrics);
-
-  // Pretend that the battery has dropped by 2%.
-  battery_states_.push(MakeBatteryDischargingState(48));
-
-  const base::TimeDelta kLate =
-      kLongPowerMetricsIntervalDuration * kTolerablePositiveDrift -
-      base::Microseconds(1);
-  process_monitor_.ForceSampleAllProcessesIn(power_metrics_reporter_.get(),
-                                             &task_environment_, kLate);
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 1);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kDischarging, 1);
-}
-
 TEST_F(PowerMetricsReporterUnitTest, UKMs) {
   int fake_value = 42;
 
@@ -490,11 +445,6 @@
           fake_interval_data.longest_visible_origin_duration));
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kDeviceSleptDuringIntervalName, false);
-
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeRateHistogramName, 2500,
-                                       1);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kDischarging, 1);
 }
 
 TEST_F(PowerMetricsReporterUnitTest, UKMsBrowserShuttingDown) {
@@ -565,10 +515,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kPluggedIn));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kPluggedIn, 1);
 }
 
 TEST_F(PowerMetricsReporterUnitTest, UKMsBatteryStateChanges) {
@@ -599,10 +545,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kStateChanged));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kStateChanged, 1);
 }
 
 TEST_F(PowerMetricsReporterUnitTest, UKMsBatteryStateUnavailable) {
@@ -626,11 +568,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kRetrievalError));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kRetrievalError,
-                                       1);
 }
 
 TEST_F(PowerMetricsReporterUnitTest, UKMsNoBattery) {
@@ -664,10 +601,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kNoBattery));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kNoBattery, 1);
 }
 
 #if BUILDFLAG(IS_MAC)
@@ -695,11 +628,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kMacFullyCharged));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName,
-                                       BatteryDischargeMode::kMacFullyCharged,
-                                       1);
 }
 #endif  // BUILDFLAG(IS_MAC)
 
@@ -725,11 +653,6 @@
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kBatteryDischargeModeName,
       static_cast<int64_t>(BatteryDischargeMode::kBatteryLevelIncreased));
-
-  histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0);
-  histogram_tester_.ExpectUniqueSample(
-      kBatteryDischargeModeHistogramName,
-      BatteryDischargeMode::kBatteryLevelIncreased, 1);
 }
 
 TEST_F(PowerMetricsReporterUnitTest, UKMsNoTab) {
diff --git a/chrome/browser/notifications/notification_interactive_uitest.cc b/chrome/browser/notifications/notification_interactive_uitest.cc
index 6753c01..8b7441dd 100644
--- a/chrome/browser/notifications/notification_interactive_uitest.cc
+++ b/chrome/browser/notifications/notification_interactive_uitest.cc
@@ -709,6 +709,8 @@
   ASSERT_TRUE(
       other_browser->exclusive_access_manager()->context()->IsFullscreen());
 
+  ui_test_utils::BrowserActivationWaiter waiter(other_browser);
+  waiter.WaitForActivation();
   ASSERT_FALSE(browser()->window()->IsActive());
   ASSERT_TRUE(other_browser->window()->IsActive());
 
diff --git a/chrome/browser/password_manager/account_password_store_factory.cc b/chrome/browser/password_manager/account_password_store_factory.cc
index b42fdd2..0217acf 100644
--- a/chrome/browser/password_manager/account_password_store_factory.cc
+++ b/chrome/browser/password_manager/account_password_store_factory.cc
@@ -47,6 +47,10 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 using password_manager::PasswordStore;
 using password_manager::PasswordStoreInterface;
 using password_manager::UnsyncedCredentialsDeletionNotifier;
@@ -140,6 +144,20 @@
 
   Profile* profile = Profile::FromBrowserContext(context);
 
+  DCHECK(!profile->IsOffTheRecord());
+
+  // Incognito profiles don't have their own password stores. Guest, or system
+  // profiles aren't relevant for Password Manager, and no PasswordStore should
+  // even be created for those types of profiles.
+  if (!profile->IsRegularProfile())
+    return nullptr;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // On Ash, there are additional non-interesting profile types (sign-in
+  // profile and lockscreen profile).
+  if (!ash::ProfileHelper::IsUserProfile(profile))
+    return nullptr;
+#endif
+
   std::unique_ptr<password_manager::LoginDatabase> login_db(
       password_manager::CreateLoginDatabaseForAccountStorage(
           profile->GetPath()));
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc
index 685b5920..3ceb44bc 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -62,7 +62,7 @@
 constexpr char kRetryHistogramBase[] =
     "PasswordManager.PasswordStoreAndroidBackend.Retry";
 constexpr char kUPMActiveHistogram[] =
-    "PasswordManager.UnifiedPasswordManager.ActiveStatus";
+    "PasswordManager.UnifiedPasswordManager.ActiveStatus2";
 constexpr char kAliveAfterApiNotConnectedHistogram[] =
     "PasswordManager.AliveAfterApiNotConnectedError";
 constexpr char kAliveAfterConnectionSuspendedHistogram[] =
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
index 20b8f01..a94f53a 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
@@ -59,7 +59,7 @@
 constexpr char kUnenrollmentHistogram[] =
     "PasswordManager.UnenrolledFromUPMDueToErrors";
 constexpr char kUPMActiveHistogram[] =
-    "PasswordManager.UnifiedPasswordManager.ActiveStatus";
+    "PasswordManager.UnifiedPasswordManager.ActiveStatus2";
 constexpr char kUptimeOnAPIErrorHistogram[] =
     "PasswordManager.PasswordStoreAndroidBackend.UptimeOnAPIError";
 constexpr char kRetryHistogramBase[] =
diff --git a/chrome/browser/password_manager/password_reuse_manager_factory.cc b/chrome/browser/password_manager/password_reuse_manager_factory.cc
index 72b274b..ac0bbe7 100644
--- a/chrome/browser/password_manager/password_reuse_manager_factory.cc
+++ b/chrome/browser/password_manager/password_reuse_manager_factory.cc
@@ -75,6 +75,15 @@
 
   Profile* profile = Profile::FromBrowserContext(context);
 
+  password_manager::PasswordStoreInterface* store =
+      PasswordStoreFactory::GetForProfile(profile,
+                                          ServiceAccessType::EXPLICIT_ACCESS)
+          .get();
+  // Incognito, guest, or system profiles doesn't have PasswordStore so
+  // PasswordReuseManager shouldn't be created as well.
+  if (!store)
+    return nullptr;
+
   password_manager::PasswordReuseManager* reuse_manager =
       new password_manager::PasswordReuseManagerImpl();
   reuse_manager->Init(profile->GetPrefs(),
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index ad66e6d..6908fda 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -26,6 +26,10 @@
 #include "content/public/browser/storage_partition.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 using password_manager::AffiliatedMatchHelper;
 using password_manager::PasswordStore;
 using password_manager::PasswordStoreInterface;
@@ -64,6 +68,20 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
 
+  DCHECK(!profile->IsOffTheRecord());
+
+  // Incognito profiles don't have their own password stores. Guest, or system
+  // profiles aren't relevant for Password Manager, and no PasswordStore should
+  // even be created for those types of profiles.
+  if (!profile->IsRegularProfile())
+    return nullptr;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // On Ash, there are additional non-interesting profile types (sign-in
+  // profile and lockscreen profile).
+  if (!ash::ProfileHelper::IsUserProfile(profile))
+    return nullptr;
+#endif
+
   scoped_refptr<PasswordStore> ps;
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || \
     BUILDFLAG(IS_OZONE)
@@ -105,8 +123,7 @@
       CredentialsCleanerRunnerFactory::GetForProfile(profile), ps,
       profile->GetPrefs(), base::Seconds(60), network_context_getter);
 
-  if (profile->IsRegularProfile())
-    DelayReportingPasswordStoreMetrics(profile);
+  DelayReportingPasswordStoreMetrics(profile);
 
   return ps;
 }
diff --git a/chrome/browser/policy/BUILD.gn b/chrome/browser/policy/BUILD.gn
index d48b4f2..ee3f8eb9 100644
--- a/chrome/browser/policy/BUILD.gn
+++ b/chrome/browser/policy/BUILD.gn
@@ -386,7 +386,6 @@
   if (!is_android) {
     sources += [
       "cloud/component_cloud_policy_browsertest.cc",
-      "test/isolated_apps_developer_mode_allowed_browsertest.cc",
       "test/promotional_tabs_enabled_policy_browsertest.cc",
     ]
 
diff --git a/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc b/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc
deleted file mode 100644
index 668f0c65..0000000
--- a/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc
+++ /dev/null
@@ -1,114 +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 <string>
-
-#include "base/base_switches.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/values.h"
-#include "chrome/browser/policy/policy_test_utils.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/policy/core/browser/browser_policy_connector.h"
-#include "components/policy/core/common/policy_map.h"
-#include "components/policy/core/common/policy_pref_names.h"
-#include "components/policy/core/common/policy_types.h"
-#include "components/policy/policy_constants.h"
-#include "components/prefs/pref_service.h"
-#include "components/user_prefs/user_prefs.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using PolicyVerdictPair = std::tuple<policy::PolicyTest::BooleanPolicy, bool>;
-using BooleanPolicy = policy::PolicyTest::BooleanPolicy;
-
-base::FilePath::StringType kSimpleIsolatedWebAppPath =
-    FILE_PATH_LITERAL("web_apps/simple_isolated_app");
-
-class IsolatedWebAppsDeveloperModeAllowedPolicyTest
-    : public web_app::IsolatedWebAppBrowserTestHarness,
-      public testing::WithParamInterface<PolicyVerdictPair> {
- public:
-  IsolatedWebAppsDeveloperModeAllowedPolicyTest() {
-    scoped_feature_list_.InitAndEnableFeature(features::kIsolatedWebApps);
-  }
-
-  void SetUpInProcessBrowserTestFixture() override {
-    provider_.SetDefaultReturns(
-        true /* is_initialization_complete_return */,
-        true /* is_first_policy_load_complete_return */);
-    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
-    provider_.UpdateChromePolicy(
-        GenerateIsolatedWebAppsDeveloperModeAllowedPolicy());
-  }
-
- private:
-  policy::PolicyMap GenerateIsolatedWebAppsDeveloperModeAllowedPolicy() {
-    policy::PolicyMap policies;
-
-    const BooleanPolicy policy = std::get<0>(GetParam());
-    if (policy != BooleanPolicy::kNotConfigured) {
-      const bool policy_bool = (policy == BooleanPolicy::kTrue);
-      policies.Set(policy::key::kIsolatedAppsDeveloperModeAllowed,
-                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-                   policy::POLICY_SOURCE_ENTERPRISE_DEFAULT,
-                   base::Value(policy_bool), nullptr);
-    }
-
-    return policies;
-  }
-
-  testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_;
-
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_P(IsolatedWebAppsDeveloperModeAllowedPolicyTest, MockTcp) {
-  std::unique_ptr<net::EmbeddedTestServer> isolated_web_app_dev_server =
-      CreateAndStartServer(kSimpleIsolatedWebAppPath);
-  web_app::IsolatedWebAppUrlInfo url_info = InstallDevModeProxyIsolatedWebApp(
-      isolated_web_app_dev_server->GetOrigin());
-  content::RenderFrameHost* app_frame = OpenApp(url_info.app_id());
-
-  content::RenderFrameHost* navigated_frame = ui_test_utils::NavigateToURL(
-      GetBrowserFromFrame(app_frame),
-      url_info.origin().GetURL().Resolve("/direct_sockets.html"));
-
-  const bool enabled = std::get<1>(GetParam());
-  ASSERT_EQ(enabled, EvalJs(navigated_frame, "mockTcp()"));
-}
-
-IN_PROC_BROWSER_TEST_P(IsolatedWebAppsDeveloperModeAllowedPolicyTest, MockUdp) {
-  std::unique_ptr<net::EmbeddedTestServer> isolated_web_app_dev_server =
-      CreateAndStartServer(kSimpleIsolatedWebAppPath);
-  web_app::IsolatedWebAppUrlInfo url_info = InstallDevModeProxyIsolatedWebApp(
-      isolated_web_app_dev_server->GetOrigin());
-  content::RenderFrameHost* app_frame = OpenApp(url_info.app_id());
-
-  content::RenderFrameHost* navigated_frame = ui_test_utils::NavigateToURL(
-      GetBrowserFromFrame(app_frame),
-      url_info.origin().GetURL().Resolve("/direct_sockets.html"));
-
-  const bool enabled = std::get<1>(GetParam());
-  ASSERT_EQ(enabled, EvalJs(navigated_frame, "mockUdp()"));
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    /*empty*/,
-    IsolatedWebAppsDeveloperModeAllowedPolicyTest,
-    ::testing::Values(
-        PolicyVerdictPair{policy::PolicyTest::BooleanPolicy::kNotConfigured,
-                          true},
-        PolicyVerdictPair{policy::PolicyTest::BooleanPolicy::kFalse, false},
-        PolicyVerdictPair{policy::PolicyTest::BooleanPolicy::kTrue, true}));
diff --git a/chrome/browser/policy/test/send_mouse_events_disabled_form_controls_policy_browsertest.cc b/chrome/browser/policy/test/send_mouse_events_disabled_form_controls_policy_browsertest.cc
index 2009b3c..adf4ca32 100644
--- a/chrome/browser/policy/test/send_mouse_events_disabled_form_controls_policy_browsertest.cc
+++ b/chrome/browser/policy/test/send_mouse_events_disabled_form_controls_policy_browsertest.cc
@@ -73,14 +73,8 @@
 };
 
 IN_PROC_BROWSER_TEST_P(SendMouseEventsDisabledFormControlsPolicyTest, Test) {
-  bool expected_enabled;
-  if (GetParam() == SendMouseEventsDisabledFormControlsPolicyValue::kUnset) {
-    // SendMouseEventsDisabledFormControls should be enabled by default.
-    expected_enabled = true;
-  } else {
-    expected_enabled =
-        GetParam() == SendMouseEventsDisabledFormControlsPolicyValue::kEnabled;
-  }
+  bool expected_enabled =
+      GetParam() == SendMouseEventsDisabledFormControlsPolicyValue::kEnabled;
   AssertSendMouseEventsDisabledFormControlsEnabled(expected_enabled);
 }
 
@@ -88,13 +82,6 @@
     /* no prefix */,
     SendMouseEventsDisabledFormControlsPolicyTest,
     ::testing::Values(
-// The linux-chromeos-chrome trybot has this feature disabled by default, unlike
-// all other trybots which have it enabled. It is currently set to experimental
-// in runtime_enabled_features.json5 and I plan to enable it via finch, so this
-// is acceptable.
-#if !BUILDFLAG(IS_CHROMEOS)
-        SendMouseEventsDisabledFormControlsPolicyValue::kUnset,
-#endif
         SendMouseEventsDisabledFormControlsPolicyValue::kEnabled,
         SendMouseEventsDisabledFormControlsPolicyValue::kDisabled));
 
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.cc b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.cc
index 1963209..de6d28c 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.cc
+++ b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.cc
@@ -59,11 +59,11 @@
   // Copy the search term args, so we can modify them for just the prefetch.
   auto search_terms_args = search_terms_args_from_match;
   search_terms_args.is_prefetch = attach_prefetch_information;
-  return GURL(template_url_service->GetDefaultSearchProvider()
-                  ->url_ref()
-                  .ReplaceSearchTerms(search_terms_args,
-                                      template_url_service->search_terms_data(),
-                                      nullptr));
+  const TemplateURL* default_provider =
+      template_url_service->GetDefaultSearchProvider();
+  DCHECK(default_provider);
+  return GURL(default_provider->url_ref().ReplaceSearchTerms(
+      search_terms_args, template_url_service->search_terms_data(), nullptr));
 }
 
 struct SearchPrefetchEligibilityReasonRecorder {
@@ -947,8 +947,10 @@
   if (!observer_.IsObserving()) {
     observer_.Observe(template_url_service);
 
-    template_url_service_data_ =
-        template_url_service->GetDefaultSearchProvider()->data();
+    const TemplateURL* default_provider =
+        template_url_service->GetDefaultSearchProvider();
+    DCHECK(default_provider);
+    template_url_service_data_ = default_provider->data();
   }
 }
 
diff --git a/chrome/browser/preloading/prerender/prerender_manager.cc b/chrome/browser/preloading/prerender/prerender_manager.cc
index d64aad3..08849e6 100644
--- a/chrome/browser/preloading/prerender/prerender_manager.cc
+++ b/chrome/browser/preloading/prerender/prerender_manager.cc
@@ -432,12 +432,12 @@
       // Undo the change. This information might be used during activation so
       // we should not change it.
       base::AutoReset<bool> resetter(&search_terms_args.is_prefetch, true);
-      prerender_url = GURL(
-          template_url_service->GetDefaultSearchProvider()
-              ->url_ref()
-              .ReplaceSearchTerms(search_terms_args,
-                                  template_url_service->search_terms_data(),
-                                  /*post_content=*/nullptr));
+      const TemplateURL* default_provider =
+          template_url_service->GetDefaultSearchProvider();
+      DCHECK(default_provider);
+      prerender_url = GURL(default_provider->url_ref().ReplaceSearchTerms(
+          search_terms_args, template_url_service->search_terms_data(),
+          /*post_content=*/nullptr));
     }
     DCHECK(!search_terms_args.is_prefetch);
   }
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index 895fa72..02f3002 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -24,6 +24,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/printing/print_error_dialog.h"
 #include "chrome/browser/printing/print_job.h"
@@ -3555,6 +3556,8 @@
                 &ContentAnalysisPrintBrowserTest::ScanningResponse,
                 base::Unretained(this)),
             kFakeDmToken));
+    enterprise_connectors::ContentAnalysisDialog::SetShowDialogDelayForTesting(
+        base::Milliseconds(0));
 
     feature_list_.InitAndEnableFeature(features::kEnablePrintContentAnalysis);
   }
@@ -3640,13 +3643,7 @@
 };
 
 #if !BUILDFLAG(IS_CHROMEOS)
-// TODO(crbug.com/1384459): Flaky on MSan builds.
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_PrintNow DISABLED_PrintNow
-#else
-#define MAYBE_PrintNow PrintNow
-#endif
-IN_PROC_BROWSER_TEST_P(ContentAnalysisPrintBrowserTest, MAYBE_PrintNow) {
+IN_PROC_BROWSER_TEST_P(ContentAnalysisPrintBrowserTest, PrintNow) {
   AddPrinter("printer_name");
   ASSERT_TRUE(embedded_test_server()->Started());
   GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
@@ -3678,14 +3675,7 @@
   ASSERT_EQ(new_document_called_count(), 0);
 }
 
-// TODO(crbug.com/1384459): Flaky on MSan builds.
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_PrintWithPreview DISABLED_PrintWithPreview
-#else
-#define MAYBE_PrintWithPreview PrintWithPreview
-#endif
-IN_PROC_BROWSER_TEST_P(ContentAnalysisPrintBrowserTest,
-                       MAYBE_PrintWithPreview) {
+IN_PROC_BROWSER_TEST_P(ContentAnalysisPrintBrowserTest, PrintWithPreview) {
   AddPrinter("printer_name");
   ASSERT_TRUE(embedded_test_server()->Started());
   GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
index 84bf264..5cbc88d 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
@@ -156,12 +156,14 @@
   InformSentimentService(action);
   switch (action) {
     case (PromptAction::kNoticeShown): {
-      DCHECK_EQ(PromptType::kNotice, GetRequiredPromptType());
-      // The new Privacy Sandbox pref can be enabled when the notice has been
-      // shown. Note that a notice will not have been shown if the user disabled
-      // the old Privacy Sandbox pref.
-      pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabledV2, true);
-      pref_service_->SetBoolean(prefs::kPrivacySandboxNoticeDisplayed, true);
+      // TODO(crbug.com/1378703): Handle new prompt types.
+      if (PromptType::kNotice == GetRequiredPromptType()) {
+        // The new Privacy Sandbox pref can be enabled when the notice has been
+        // shown. Note that a notice will not have been shown if the user
+        // disabled the old Privacy Sandbox pref.
+        pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabledV2, true);
+        pref_service_->SetBoolean(prefs::kPrivacySandboxNoticeDisplayed, true);
+      }
       base::RecordAction(
           base::UserMetricsAction("Settings.PrivacySandbox.Notice.Shown"));
       break;
diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
index 13911bf..85fbbf3 100644
--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
@@ -246,13 +246,11 @@
     "AboutSigninInternals",
     "AboutThisSiteServiceFactory",
     "AccountInvestigator",
-    "AccountPasswordStore",
     "AccountReconcilor",
     "ActivityLog",
     "ActivityLogPrivateAPI",
     "AdaptiveQuietNotificationPermissionUiEnabler",
     "AdvancedProtectionStatusManager",
-    "AffiliationService",
     "AlarmManager",
     "AnnouncementNotificationService",
     "AppLifetimeMonitor",
@@ -291,7 +289,6 @@
     "ContentSettingsService",
     "CookieSettings",
     "CookiesAPI",
-    "CredentialsCleanerRunner",
     "DeveloperPrivateAPI",
     "DeviceInfoSyncService",
     "EventRouter",
@@ -351,7 +348,6 @@
     "OmniboxAPI",
     "OptimizationGuideKeyedService",
     "PageContentAnnotationsService",
-    "PasswordStore",
     "PasswordsPrivateEventRouter",
     "PermissionHelper",
     "PermissionsManager",
@@ -542,13 +538,11 @@
     "AboutSigninInternals",
     "AboutThisSiteServiceFactory",
     "AccountInvestigator",
-    "AccountPasswordStore",
     "AccountReconcilor",
     "ActivityLog",
     "ActivityLogPrivateAPI",
     "AdaptiveQuietNotificationPermissionUiEnabler",
     "AdvancedProtectionStatusManager",
-    "AffiliationService",
     "AlarmManager",
     "AnnouncementNotificationService",
     "AppLifetimeMonitor",
@@ -587,7 +581,6 @@
     "ContentSettingsService",
     "CookieSettings",
     "CookiesAPI",
-    "CredentialsCleanerRunner",
     "DeveloperPrivateAPI",
     "DeviceInfoSyncService",
     "DownloadCoreService",
@@ -649,7 +642,6 @@
     "OmniboxAPI",
     "OptimizationGuideKeyedService",
     "PageContentAnnotationsService",
-    "PasswordStore",
     "PasswordsPrivateEventRouter",
     "PermissionHelper",
     "PermissionsManager",
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc b/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc
index d018c032..76b3e21 100644
--- a/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/resource_coordinator/time.h"
 #include "chrome/browser/sessions/session_restore.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/swap_metrics_driver.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 
@@ -51,45 +50,6 @@
 
 }  // namespace
 
-class TabManagerStatsCollector::SwapMetricsDelegate
-    : public content::SwapMetricsDriver::Delegate {
- public:
-  explicit SwapMetricsDelegate(
-      TabManagerStatsCollector* tab_manager_stats_collector)
-      : tab_manager_stats_collector_(tab_manager_stats_collector) {}
-
-  ~SwapMetricsDelegate() override = default;
-
-  void OnSwapInCount(uint64_t count, base::TimeDelta interval) override {
-    tab_manager_stats_collector_->RecordSwapMetrics("SwapInPerSecond", count,
-                                                    interval);
-  }
-
-  void OnSwapOutCount(uint64_t count, base::TimeDelta interval) override {
-    tab_manager_stats_collector_->RecordSwapMetrics("SwapOutPerSecond", count,
-                                                    interval);
-  }
-
-  void OnDecompressedPageCount(uint64_t count,
-                               base::TimeDelta interval) override {
-    tab_manager_stats_collector_->RecordSwapMetrics(
-        "DecompressedPagesPerSecond", count, interval);
-  }
-
-  void OnCompressedPageCount(uint64_t count,
-                             base::TimeDelta interval) override {
-    tab_manager_stats_collector_->RecordSwapMetrics("CompressedPagesPerSecond",
-                                                    count, interval);
-  }
-
-  void OnUpdateMetricsFailed() override {
-    tab_manager_stats_collector_->OnUpdateSwapMetricsFailed();
-  }
-
- private:
-  raw_ptr<TabManagerStatsCollector> tab_manager_stats_collector_;
-};
-
 TabManagerStatsCollector::TabManagerStatsCollector() {
   SessionRestore::AddObserver(this);
 }
@@ -127,48 +87,14 @@
 void TabManagerStatsCollector::OnSessionRestoreStartedLoadingTabs() {
   DCHECK(!is_session_restore_loading_tabs_);
   UpdateSessionAndSequence();
-
-  CreateAndInitSwapMetricsDriverIfNeeded();
-
   is_session_restore_loading_tabs_ = true;
 }
 
 void TabManagerStatsCollector::OnSessionRestoreFinishedLoadingTabs() {
   DCHECK(is_session_restore_loading_tabs_);
-
-  UMA_HISTOGRAM_BOOLEAN(kHistogramSessionOverlapSessionRestore, false);
-  if (swap_metrics_driver_)
-    swap_metrics_driver_->UpdateMetrics();
-
   is_session_restore_loading_tabs_ = false;
 }
 
-void TabManagerStatsCollector::CreateAndInitSwapMetricsDriverIfNeeded() {
-  swap_metrics_driver_ = content::SwapMetricsDriver::Create(
-      base::WrapUnique<content::SwapMetricsDriver::Delegate>(
-          new SwapMetricsDelegate(this)),
-      base::Seconds(0));
-  // The driver could still be null on a platform with no swap driver support.
-  if (swap_metrics_driver_)
-    swap_metrics_driver_->InitializeMetrics();
-}
-
-void TabManagerStatsCollector::RecordSwapMetrics(const std::string& metric_name,
-                                                 uint64_t count,
-                                                 base::TimeDelta interval) {
-  base::HistogramBase* histogram = base::Histogram::FactoryGet(
-      "TabManager.Experimental.SessionRestore." + metric_name,
-      1,      // minimum
-      10000,  // maximum
-      50,     // bucket_count
-      base::HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(static_cast<double>(count) / interval.InSecondsF());
-}
-
-void TabManagerStatsCollector::OnUpdateSwapMetricsFailed() {
-  swap_metrics_driver_ = nullptr;
-}
-
 void TabManagerStatsCollector::OnDidStartMainFrameNavigation(
     content::WebContents* contents) {
   foreground_contents_switched_to_times_.erase(contents);
@@ -228,10 +154,6 @@
         "UntilTabIsLoaded";
 
 // static
-const char TabManagerStatsCollector::kHistogramSessionOverlapSessionRestore[] =
-    "TabManager.SessionOverlap.SessionRestore";
-
-// static
 constexpr base::TimeDelta
     TabManagerStatsCollector::kLowFrequencySamplingInterval;
 
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector.h b/chrome/browser/resource_coordinator/tab_manager_stats_collector.h
index 072017f..6be6116 100644
--- a/chrome/browser/resource_coordinator/tab_manager_stats_collector.h
+++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector.h
@@ -22,7 +22,6 @@
 #include "services/metrics/public/cpp/ukm_source_id.h"
 
 namespace content {
-class SwapMetricsDriver;
 class WebContents;
 }  // namespace content
 
@@ -59,14 +58,6 @@
   void OnSessionRestoreStartedLoadingTabs() override;
   void OnSessionRestoreFinishedLoadingTabs() override;
 
-  // Record UMA histograms for system swap metrics.
-  void RecordSwapMetrics(const std::string& metric_name,
-                         uint64_t count,
-                         base::TimeDelta interval);
-
-  // Handles the situation when failing to update swap metrics.
-  void OnUpdateSwapMetricsFailed();
-
   // Called by WebContentsData when a tab starts loading. Used to clean up
   // |foreground_contents_switched_to_times_| if we were tracking this tab and
   // OnDidStopLoading has not yet been called for it, which will happen if the
@@ -83,7 +74,6 @@
   void OnWebContentsDestroyed(content::WebContents* contents);
 
  private:
-  class SwapMetricsDelegate;
   FRIEND_TEST_ALL_PREFIXES(TabManagerStatsCollectorTabSwitchTest,
                            HistogramsSwitchToTab);
   FRIEND_TEST_ALL_PREFIXES(TabManagerStatsCollectorTabSwitchTest,
@@ -93,15 +83,11 @@
   FRIEND_TEST_ALL_PREFIXES(TabManagerStatsCollectorPrerenderingTest,
                            KeepingWebContentsMapInPrerendering);
 
-  // Create and initialize the swap metrics driver if needed.
-  void CreateAndInitSwapMetricsDriverIfNeeded();
-
   // Update session and sequence information for UKM recording.
   void UpdateSessionAndSequence();
 
   static const char kHistogramSessionRestoreSwitchToTab[];
   static const char kHistogramSessionRestoreTabSwitchLoadTime[];
-  static const char kHistogramSessionOverlapSessionRestore[];
 
   // The rough sampling interval for low-frequency sampled stats. This should
   // be O(minutes).
@@ -116,8 +102,6 @@
 
   bool is_session_restore_loading_tabs_ = false;
 
-  std::unique_ptr<content::SwapMetricsDriver> swap_metrics_driver_;
-
   // The set of foreground tabs during session restore that were switched to
   // that have not yet finished loading, mapped to the time that they were
   // switched to. It's possible to have multiple session restores happening
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/macros/repeatable_key_press_macro.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/macros/repeatable_key_press_macro.js
index f171379a..10c39156 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/macros/repeatable_key_press_macro.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/macros/repeatable_key_press_macro.js
@@ -269,8 +269,10 @@
 
   /** @override */
   doKeyPress() {
-    EventGenerator.sendKeyPress(KeyCode.A, {ctrl: true});
-    EventGenerator.sendKeyPress(KeyCode.LEFT, {});
+    // TODO(b/259397131): Migrate this implementation to use
+    // chrome.automation.setDocumentSelection.
+    EventGenerator.sendKeyPress(
+        KeyCode.LEFT, {search: true, ctrl: true}, /*useRewriters=*/ true);
   }
 }
 
@@ -282,8 +284,10 @@
 
   /** @override */
   doKeyPress() {
-    EventGenerator.sendKeyPress(KeyCode.A, {ctrl: true});
-    EventGenerator.sendKeyPress(KeyCode.RIGHT, {});
+    // TODO(b/259397131): Migrate this implementation to use
+    // chrome.automation.setDocumentSelection.
+    EventGenerator.sendKeyPress(
+        KeyCode.RIGHT, {search: true, ctrl: true}, /*useRewriters=*/ true);
   }
 }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_input_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_input_handler_test.js
index 1e76fb92..9f8b006 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_input_handler_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_input_handler_test.js
@@ -452,8 +452,9 @@
     chrome.virtualKeyboardPrivate.getKeyboardConfig = function(callback) {
       callback({a11ymode: true});
     };
-    chrome.accessibilityPrivate.sendSyntheticKeyEvent = (event, opt_callback) =>
-        this.storeKeyEvent(event, opt_callback);
+    chrome.accessibilityPrivate.sendSyntheticKeyEvent =
+        (event, useRewriters, opt_callback) =>
+            this.storeKeyEvent(event, useRewriters, opt_callback);
     chrome.accessibilityPrivate.SyntheticKeyboardEventType = {};
     chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN = 'keydown';
     chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP = 'keyup';
@@ -527,7 +528,7 @@
         this.inputHandler.getExpansionType());
   }
 
-  storeKeyEvent(event, opt_callback) {
+  storeKeyEvent(event, useRewriters, opt_callback) {
     const storedCopy = {keyCode: event.keyCode};
     if (event.type === 'keydown') {
       this.keyEvents.push(storedCopy);
diff --git a/chrome/browser/resources/chromeos/accessibility/common/event_generator.js b/chrome/browser/resources/chromeos/accessibility/common/event_generator.js
index b5a41567..6a10f227 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/event_generator.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/event_generator.js
@@ -12,15 +12,18 @@
    *     being held).
    * @param {!KeyCode} keyCode
    * @param {!chrome.accessibilityPrivate.SyntheticKeyboardModifiers} modifiers
+   * @param {boolean} useRewriters If true, uses rewriters for the key event;
+   *     only allowed if used from Dictation. Otherwise indicates that rewriters
+   *     should be skipped.
    */
-  static sendKeyPress(keyCode, modifiers = {}) {
+  static sendKeyPress(keyCode, modifiers = {}, useRewriters = false) {
     let type = chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN;
     chrome.accessibilityPrivate.sendSyntheticKeyEvent(
-        {type, keyCode, modifiers});
+        {type, keyCode, modifiers}, useRewriters);
 
     type = chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP;
     chrome.accessibilityPrivate.sendSyntheticKeyEvent(
-        {type, keyCode, modifiers});
+        {type, keyCode, modifiers}, useRewriters);
   }
 
   /**
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_after.html b/chrome/browser/resources/chromeos/parent_access/parent_access_after.html
index 5c18b08..2e6db4e 100644
--- a/chrome/browser/resources/chromeos/parent_access/parent_access_after.html
+++ b/chrome/browser/resources/chromeos/parent_access/parent_access_after.html
@@ -2,7 +2,7 @@
   .action-button {
     margin-inline-start: 8px;
   }
-  
+
   #after-screen {
     background-color: var(--cros-bg-color-elevation-1);
     box-sizing: border-box;
@@ -12,10 +12,11 @@
     justify-content: flex-start;
     padding: 26px 24px 20px;
   }
-  
+
   #after-screen-buttons {
     display: flex;
-    justify-content: flex-end;
+    /* Allows the button that appears first visually to be last in tab order */
+    flex-direction: row-reverse; 
     margin-top: auto; /* position at end of flexbox */
     width: 100%;
   }
@@ -31,11 +32,11 @@
   </img>
   <div id="after-screen-body"></div>
   <div id="after-screen-buttons">
-    <cr-button class="decline-button" on-click="onParentDeclined_">
-      $i18n{denyButtonText}
-    </cr-button>
     <cr-button class="action-button" on-click="onParentApproved_">
       $i18n{approveButtonText}
     </cr-button>
+    <cr-button class="decline-button" on-click="onParentDeclined_">
+      $i18n{denyButtonText}
+    </cr-button>
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_after.js b/chrome/browser/resources/chromeos/parent_access/parent_access_after.js
index 2ba64929..176b24ab 100644
--- a/chrome/browser/resources/chromeos/parent_access/parent_access_after.js
+++ b/chrome/browser/resources/chromeos/parent_access/parent_access_after.js
@@ -31,6 +31,10 @@
     this.renderFlowSpecificContent_();
   }
 
+  onShowAfterScreen() {
+    this.shadowRoot.querySelector('.action-button').focus();
+  }
+
   /**
    * Renders the correct after screen based on the ParentAccessParams flowtype.
    * @private
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_app.js b/chrome/browser/resources/chromeos/parent_access/parent_access_app.js
index 463991c..9f64031 100644
--- a/chrome/browser/resources/chromeos/parent_access/parent_access_app.js
+++ b/chrome/browser/resources/chromeos/parent_access/parent_access_app.js
@@ -47,6 +47,7 @@
       this.currentScreen_ = Screens.AFTER_FLOW;
       /** @type {CrViewManagerElement} */ (this.$.viewManager)
           .switchView(this.currentScreen_);
+      this.shadowRoot.querySelector('parent-access-after').onShowAfterScreen();
     });
 
     // TODO(b/200187536): Show offline screen if device is offline.
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn
index 4cb10ee..2fbe1e2 100644
--- a/chrome/browser/resources/password_manager/BUILD.gn
+++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -23,6 +23,7 @@
     "password_manager_app.ts",
     "password_list_item.ts",
     "passwords_section.ts",
+    "password_details_section.ts",
     "prefs/pref_toggle_button.ts",
     "settings_section.ts",
     "side_bar.ts",
diff --git a/chrome/browser/resources/password_manager/checkup_section.ts b/chrome/browser/resources/password_manager/checkup_section.ts
index 0206e4a..3799df69 100644
--- a/chrome/browser/resources/password_manager/checkup_section.ts
+++ b/chrome/browser/resources/password_manager/checkup_section.ts
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// 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.
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
diff --git a/chrome/browser/resources/password_manager/password_details_section.html b/chrome/browser/resources/password_manager/password_details_section.html
new file mode 100644
index 0000000..cd44f5d
--- /dev/null
+++ b/chrome/browser/resources/password_manager/password_details_section.html
@@ -0,0 +1,25 @@
+<style include="shared-style cr-shared-style">
+  #header {
+    align-items: center;
+    display: flex;
+  }
+
+  #backButton {
+    --cr-icon-button-margin-end: 6px;
+    --cr-icon-button-margin-start: 0px;
+  }
+
+  #favicon {
+    margin-inline-end: 12px;
+    --site-favicon-height: 20px;
+    --site-favicon-width: 20px;
+  }
+</style>
+<div id="header">
+  <cr-icon-button class="icon-arrow-back" id="backButton"
+      on-click="navigateBack_">
+  </cr-icon-button>
+  <!-- TODO(crbug.com/1350947): Use selectedGroup_.iconUrl. -->
+  <site-favicon id="favicon" url="[[selectedGroup_.name]]"></site-favicon>
+  <h2 id="title" class="page-title">[[selectedGroup_.name]]</h2>
+</div>
diff --git a/chrome/browser/resources/password_manager/password_details_section.ts b/chrome/browser/resources/password_manager/password_details_section.ts
new file mode 100644
index 0000000..caa35a2
--- /dev/null
+++ b/chrome/browser/resources/password_manager/password_details_section.ts
@@ -0,0 +1,85 @@
+// 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.
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
+import 'chrome://resources/cr_elements/cr_icons.css.js';
+import 'chrome://resources/cr_elements/cr_shared_style.css.js';
+import './shared_style.css.js';
+import './site_favicon.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 {getTemplate} from './password_details_section.html.js';
+import {PasswordManagerImpl} from './password_manager_proxy.js';
+import {Page, Route, RouteObserverMixin, Router} from './router.js';
+
+export interface PasswordDetailsSectionElement {
+  $: {
+    backButton: CrIconButtonElement,
+    title: HTMLElement,
+  };
+}
+
+const PasswordDetailsSectionElementBase = RouteObserverMixin(PolymerElement);
+
+export class PasswordDetailsSectionElement extends
+    PasswordDetailsSectionElementBase {
+  static get is() {
+    return 'password-details-section';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {selectedGroup_: Object};
+  }
+
+  private selectedGroup_: chrome.passwordsPrivate.CredentialGroup|undefined;
+
+  override currentRouteChanged(route: Route, _: Route): void {
+    if (route.page !== Page.PASSWORD_DETAILS) {
+      this.selectedGroup_ = undefined;
+      return;
+    }
+
+    const group = route.details as chrome.passwordsPrivate.CredentialGroup;
+    if (group && group.name) {
+      this.selectedGroup_ = group;
+    } else {
+      // Navigation happened directly. Find group with matching name.
+      this.assignMatchingGroup(route.details as string);
+    }
+  }
+
+  private navigateBack_() {
+    Router.getInstance().navigateTo(Page.PASSWORDS);
+  }
+
+  private getGroupName_(): string {
+    return this.selectedGroup_ ? this.selectedGroup_!.name : '';
+  }
+
+  private async assignMatchingGroup(groupName: string) {
+    const groups =
+        await PasswordManagerImpl.getInstance().getCredentialGroups();
+    const selectedGroup = groups.find(group => group.name === groupName);
+    if (selectedGroup) {
+      // TODO(crbug.com/1350947): Request passwords and notes.
+      this.selectedGroup_ = selectedGroup;
+    } else {
+      this.navigateBack_();
+    }
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'password-details-section': PasswordDetailsSectionElement;
+  }
+}
+
+customElements.define(
+    PasswordDetailsSectionElement.is, PasswordDetailsSectionElement);
diff --git a/chrome/browser/resources/password_manager/password_list_item.ts b/chrome/browser/resources/password_manager/password_list_item.ts
index b2b90925..c68a052 100644
--- a/chrome/browser/resources/password_manager/password_list_item.ts
+++ b/chrome/browser/resources/password_manager/password_list_item.ts
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// 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.
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
diff --git a/chrome/browser/resources/password_manager/password_manager.ts b/chrome/browser/resources/password_manager/password_manager.ts
index 5fec4ef..543207f 100644
--- a/chrome/browser/resources/password_manager/password_manager.ts
+++ b/chrome/browser/resources/password_manager/password_manager.ts
@@ -4,6 +4,7 @@
 
 import './password_manager_app.js';
 
+export {PasswordDetailsSectionElement} from './password_details_section.js';
 export {PasswordManagerAppElement} from './password_manager_app.js';
 export {BlockedSite, BlockedSitesListChangedListener, CredentialsChangedListener, PasswordCheckInteraction, PasswordCheckStatusChangedListener, PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js';
 export {PasswordsSectionElement} from './passwords_section.js';
diff --git a/chrome/browser/resources/password_manager/password_manager_app.html b/chrome/browser/resources/password_manager/password_manager_app.html
index b4447b65..2bec812 100644
--- a/chrome/browser/resources/password_manager/password_manager_app.html
+++ b/chrome/browser/resources/password_manager/password_manager_app.html
@@ -65,9 +65,9 @@
     <settings-section id="settings" path="settings"
         class="cr-centered-card-container">
     </settings-section>
-    <div id="passwordDetails" path="password-details"
+    <password-details-section id="passwordDetails" path="password-details"
       class="cr-centered-card-container">
-    </div>
+    </password-details-section>
   </iron-pages>
   <!-- An additional child of the flex #container to take up space,
       aligned with the right-hand child of the flex toolbar. -->
diff --git a/chrome/browser/resources/password_manager/password_manager_app.ts b/chrome/browser/resources/password_manager/password_manager_app.ts
index c511dac..8775134 100644
--- a/chrome/browser/resources/password_manager/password_manager_app.ts
+++ b/chrome/browser/resources/password_manager/password_manager_app.ts
@@ -7,6 +7,7 @@
 import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
 import './checkup_section.js';
 import './passwords_section.js';
+import './password_details_section.js';
 import './settings_section.js';
 import './shared_style.css.js';
 import './side_bar.js';
diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts
index 12173c9..ef38fb8 100644
--- a/chrome/browser/resources/pdf/pdf_viewer.ts
+++ b/chrome/browser/resources/pdf/pdf_viewer.ts
@@ -449,6 +449,7 @@
       const result =
           await this.pluginController_!.save(SaveRequestType.ANNOTATION);
       // Data always exists when save is called with requestType = ANNOTATION.
+      assert(result);
 
       record(UserAction.ENTER_ANNOTATION_MODE);
       this.annotationMode_ = true;
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_combined_dialog_app.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_combined_dialog_app.ts
index 4d9ad76..ead0458 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_combined_dialog_app.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_combined_dialog_app.ts
@@ -15,6 +15,7 @@
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './privacy_sandbox_combined_dialog_app.html.js';
+import {PrivacySandboxDialogBrowserProxy, PrivacySandboxPromptAction} from './privacy_sandbox_dialog_browser_proxy.js';
 import {PrivacySandboxDialogResizeMixin} from './privacy_sandbox_dialog_resize_mixin.js';
 
 export enum PrivacySandboxCombinedDialogStep {
@@ -53,37 +54,55 @@
   }
 
   private step_: PrivacySandboxCombinedDialogStep;
+  private animationsEnabled_: boolean = true;
 
   override ready() {
     super.ready();
 
     // Support starting with notice step instead of starting with consent step.
     const step = new URLSearchParams(window.location.search).get('step');
+    const startWithNotice = step === PrivacySandboxCombinedDialogStep.NOTICE;
     let promise: Promise<void>;
-    if (step === PrivacySandboxCombinedDialogStep.NOTICE) {
+    if (startWithNotice) {
       promise = this.navigateToStep_(PrivacySandboxCombinedDialogStep.NOTICE);
     } else {
       promise = this.navigateToStep_(PrivacySandboxCombinedDialogStep.CONSENT);
     }
-    // After the initial step was loaded, resize the native dialog to fit it..
-    promise.then(() => this.resizeNativeDialog());
+    // After the initial step was loaded, resize the native dialog to fit it.
+    promise.then(() => this.resizeAndShowNativeDialog())
+        .then(
+            () => this.promptActionOccurred(
+                startWithNotice ? PrivacySandboxPromptAction.NOTICE_SHOWN :
+                                  PrivacySandboxPromptAction.CONSENT_SHOWN));
+  }
+
+  disableAnimationsForTesting() {
+    this.animationsEnabled_ = false;
   }
 
   private onConsentStepResolved_() {
-    const savingDurationMs = 1500;
+    const savingDurationMs = this.animationsEnabled_ ? 1500 : 0;
     this.navigateToStep_(PrivacySandboxCombinedDialogStep.SAVING)
+        .then(() => new Promise(r => setTimeout(r, savingDurationMs)))
         .then(
-            () => new Promise(r => setTimeout(r, savingDurationMs))
-                      .then(
-                          () => this.navigateToStep_(
-                              PrivacySandboxCombinedDialogStep.NOTICE)));
+            () => this.navigateToStep_(PrivacySandboxCombinedDialogStep.NOTICE))
+        .then(
+            () => this.promptActionOccurred(
+                PrivacySandboxPromptAction.NOTICE_SHOWN));
   }
 
   private navigateToStep_(step: PrivacySandboxCombinedDialogStep):
       Promise<void> {
     assert(step !== this.step_);
     this.step_ = step;
-    return this.$.viewManager.switchView(this.step_);
+    const enterAnimation = this.animationsEnabled_ ? 'fade-in' : 'no-animation';
+    const exitAnimation = this.animationsEnabled_ ? 'fade-out' : 'no-animation';
+    return this.$.viewManager.switchView(
+        this.step_, enterAnimation, exitAnimation);
+  }
+
+  private promptActionOccurred(action: PrivacySandboxPromptAction) {
+    PrivacySandboxDialogBrowserProxy.getInstance().promptActionOccurred(action);
   }
 }
 
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.ts
index ecf96d7..b448855 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.ts
@@ -45,13 +45,13 @@
   }
 
   private onConsentAccepted_() {
-    // TODO(crbug.com/1378703): Handle user action.
+    this.promptActionOccurred(PrivacySandboxPromptAction.CONSENT_ACCEPTED);
     this.dispatchEvent(
         new CustomEvent('consent-resolved', {bubbles: true, composed: true}));
   }
 
   private onConsentDeclined_() {
-    // TODO(crbug.com/1378703): Handle user action.
+    this.promptActionOccurred(PrivacySandboxPromptAction.CONSENT_DECLINED);
     this.dispatchEvent(
         new CustomEvent('consent-resolved', {bubbles: true, composed: true}));
   }
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_mixin.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_mixin.ts
index 9aa2e78..c97c5bc 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_mixin.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_mixin.ts
@@ -28,16 +28,16 @@
         }
 
         onNoticeOpenSettings() {
-          this.promptActionOccurred_(
+          this.promptActionOccurred(
               PrivacySandboxPromptAction.NOTICE_OPEN_SETTINGS);
         }
 
         onNoticeAcknowledge() {
-          this.promptActionOccurred_(
+          this.promptActionOccurred(
               PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
         }
 
-        private promptActionOccurred_(action: PrivacySandboxPromptAction) {
+        promptActionOccurred(action: PrivacySandboxPromptAction) {
           PrivacySandboxDialogBrowserProxy.getInstance().promptActionOccurred(
               action);
         }
@@ -49,4 +49,5 @@
 export interface PrivacySandboxDialogNoticeMixinInterface {
   onNoticeOpenSettings(): void;
   onNoticeAcknowledge(): void;
+  promptActionOccurred(action: PrivacySandboxPromptAction): void;
 }
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_resize_mixin.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_resize_mixin.ts
index 0686c24..8e338db 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_resize_mixin.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_resize_mixin.ts
@@ -21,33 +21,36 @@
          * class. This should be called once per dialog after the UI has
          * finished rendering.
          */
-        resizeNativeDialog(): void {
-          afterNextRender(this, async () => {
-            const proxy = PrivacySandboxDialogBrowserProxy.getInstance();
-            // Prefer using |document.body.offsetHeight| instead of
-            // |document.body.scrollHeight| as it returns the correct height of
-            // the page even when the page zoom in Chrome is different than
-            // 100%.
-            await proxy.resizeDialog(document.body.offsetHeight);
+        resizeAndShowNativeDialog(): Promise<void> {
+          return new Promise(
+              resolve => afterNextRender(this, async () => {
+                const proxy = PrivacySandboxDialogBrowserProxy.getInstance();
+                // Prefer using |document.body.offsetHeight| instead of
+                // |document.body.scrollHeight| as it returns the correct height
+                // of the page even when the page zoom in Chrome is different
+                // than 100%.
+                await proxy.resizeDialog(document.body.offsetHeight);
 
-            // After the content was rendered at size it requires, toggle a
-            // class to fit the content into native dialog bounds...
-            const elements = this.shadowRoot!.querySelectorAll<HTMLElement>(
-                '[fill-content]');
-            for (const element of elements) {
-              element.classList.toggle('fill-content', true);
-            }
+                // After the content was rendered at size it requires, toggle a
+                // class to fit the content into native dialog bounds...
+                const elements = this.shadowRoot!.querySelectorAll<HTMLElement>(
+                    '[fill-content]');
+                for (const element of elements) {
+                  element.classList.toggle('fill-content', true);
+                }
 
-            // ...and hide any overflow on the body. 'fill-content' element
-            // fills the dialog and any scrolling will be happening inside it.
-            document.body.style.overflow = 'hidden';
+                // ...and hide any overflow on the body. 'fill-content' element
+                // fills the dialog and any scrolling will be happening inside
+                // it.
+                document.body.style.overflow = 'hidden';
 
-            // After the layout is adjusted to fit into the dialog...
-            afterNextRender(this, () => {
-              // ...show the native dialog.
-              proxy.showDialog();
-            });
-          });
+                // After the layout is adjusted to fit into the dialog...
+                afterNextRender(this, () => {
+                  // ...show the native dialog.
+                  proxy.showDialog();
+                  resolve();
+                });
+              }));
         }
       }
 
@@ -55,5 +58,5 @@
     });
 
 export interface PrivacySandboxDialogResizeMixinInterface {
-  resizeNativeDialog(): void;
+  resizeAndShowNativeDialog(): Promise<void>;
 }
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.ts
index 22458b86e3..8d7ca2e 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.ts
@@ -10,6 +10,7 @@
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {PrivacySandboxPromptAction} from './privacy_sandbox_dialog_browser_proxy.js';
 import {PrivacySandboxDialogNoticeMixin} from './privacy_sandbox_dialog_notice_mixin.js';
 import {PrivacySandboxDialogResizeMixin} from './privacy_sandbox_dialog_resize_mixin.js';
 import {getTemplate} from './privacy_sandbox_notice_dialog_app.html.js';
@@ -31,7 +32,9 @@
   override ready() {
     super.ready();
 
-    this.resizeNativeDialog();
+    this.resizeAndShowNativeDialog().then(
+        () =>
+            this.promptActionOccurred(PrivacySandboxPromptAction.NOTICE_SHOWN));
   }
 }
 
diff --git a/chrome/browser/resources/settings/chromeos/OWNERS b/chrome/browser/resources/settings/chromeos/OWNERS
index 29fe59d..ffe990e2 100644
--- a/chrome/browser/resources/settings/chromeos/OWNERS
+++ b/chrome/browser/resources/settings/chromeos/OWNERS
@@ -10,16 +10,16 @@
 xiaohuic@chromium.org
 
 # Backup reviewers
-chadduffin@chromium.org
 cowmoo@chromium.org
-gordonseto@google.com
-hsuregan@chromium.org
-jimmyxgong@chromium.org
-jonmann@chromium.org
-khorimoto@chromium.org
-zentaro@chromium.org
 
-# For APAC timezone build file related changes only.
-per-file BUILD.gn=file://chrome/browser/resources/settings/chromeos/os_apps_page/OWNERS
-per-file os_settings.gni=file://chrome/browser/resources/settings/chromeos/os_apps_page/OWNERS
-per-file os_settings.js=file://chrome/browser/resources/settings/chromeos/os_apps_page/OWNERS
+# Subdir OWNERS can approve global changes related to their subdir.
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/crostini_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/device_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/guest_os/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/internet_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/keyboard_shortcut_banner/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/multidevice_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/os_apps_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/os_bluetooth_page/OWNERS
+per-file BUILD.gn,lazy_load.js,os_settings.gni,os_settings.js=file://chrome/browser/resources/settings/chromeos/os_languages_page/OWNERS
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index e0fc4a95..111f215 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -185,6 +185,7 @@
     "//ash/webui/common/resources:web_ui_listener_behavior",
     "//ash/webui/common/resources/cellular_setup:cellular_types",
     "//ash/webui/common/resources/cellular_setup:esim_manager_utils",
+    "//ash/webui/common/resources/network:apn_detail_dialog",
     "//ash/webui/common/resources/network:cellular_utils",
     "//ash/webui/common/resources/network:mojo_interface_provider",
     "//ash/webui/common/resources/network:network_listener_behavior",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
index 3c8b652a..a38c25d 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
@@ -150,6 +150,11 @@
   </internet-config>
 </template>
 
+<template is="dom-if" if="[[shouldShowApnDetailDialog_]]" restamp>
+  <apn-detail-dialog id="apnDetailDialog" on-close="onApnDetailDialogClose_">
+  </apn-detail-dialog>
+</template>
+
 <template is="dom-if" if="[[showCellularSetupDialog_]]" restamp>
   <os-settings-cellular-setup-dialog id="cellularSetupDialog"
       on-close="onCloseCellularSetupDialog_"
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
index 8b2b16a..d96f95d2 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
@@ -10,6 +10,7 @@
 
 import 'chrome://resources/ash/common/cellular_setup/cellular_setup_icons.html.js';
 import 'chrome://resources/ash/common/network/sim_lock_dialogs.js';
+import 'chrome://resources/ash/common/network/apn_detail_dialog.js';
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
@@ -32,11 +33,11 @@
 
 import {CellularSetupPageName} from 'chrome://resources/ash/common/cellular_setup/cellular_types.js';
 import {getNumESimProfiles} from 'chrome://resources/ash/common/cellular_setup/esim_manager_utils.js';
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js';
 import {hasActiveCellularNetwork, isConnectedToNonCellularNetwork} from 'chrome://resources/ash/common/network/cellular_utils.js';
 import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js';
 import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/ash/common/network/network_listener_behavior.js';
 import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js';
 import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/ash/common/web_ui_listener_behavior.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
@@ -184,6 +185,23 @@
       },
 
       /**
+       * @private
+       */
+      isApnRevampEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.valueExists('isApnRevampEnabled') &&
+              loadTimeData.getBoolean('isApnRevampEnabled');
+        },
+      },
+
+      /** @private */
+      shouldShowApnDetailDialog_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /**
        * Page name, if defined, indicating that the next deviceStates update
        * should call attemptShowCellularSetupDialog_().
        * @private {CellularSetupPageName|null}
@@ -667,6 +685,23 @@
   }
 
   /**
+   * TODO(b/162365553): We should pass a network's GUID in here, and what mode
+   * the dialog should be in (create/edit/view)
+   * @private
+   */
+  showApnDetailDialog_() {
+    if (!this.isApnRevampEnabled_) {
+      return;
+    }
+    this.shouldShowApnDetailDialog_ = true;
+  }
+
+  /** @private */
+  onApnDetailDialogClose_() {
+    this.shouldShowApnDetailDialog_ = false;
+  }
+
+  /**
    * @param {!CustomEvent<!OncMojo.NetworkStateProperties>} event
    * @private
    */
@@ -1001,10 +1036,14 @@
 
   /**
    * Handles UI requests to add new APN.
-   * TODO(b/162365553): Implement.
    * @private
    */
-  onCreateCustomApnClicked_() {}
+  onCreateCustomApnClicked_() {
+    if (this.shouldShowApnDetailDialog_) {
+      return;
+    }
+    this.showApnDetailDialog_();
+  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.js
index 20c8b511..4a55c3f 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.js
@@ -80,7 +80,7 @@
    * @param {number} index
    * @return {!Promise<boolean>}
    */
-  removeEnrollment(index) {}
+  removeEnrollment(index, authToken) {}
 
   /**
    * @param {number} index
@@ -140,8 +140,8 @@
   }
 
   /** @override */
-  removeEnrollment(index) {
-    return sendWithPromise('removeEnrollment', index);
+  removeEnrollment(index, authToken) {
+    return sendWithPromise('removeEnrollment', index, authToken);
   }
 
   /** @override */
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
index 19b04b7..b0da48a 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
@@ -186,12 +186,13 @@
    * @private
    */
   onFingerprintDeleteTapped_(e) {
-    this.browserProxy_.removeEnrollment(e.model.index).then(success => {
-      if (success) {
-        recordSettingChange();
-        this.updateFingerprintsList_();
-      }
-    });
+    this.browserProxy_.removeEnrollment(e.model.index, this.authToken)
+        .then(success => {
+          if (success) {
+            recordSettingChange();
+            this.updateFingerprintsList_();
+          }
+        });
   }
 
   /**
diff --git a/chrome/browser/resources/settings/chromeos/settings_controls_types.js b/chrome/browser/resources/settings/chromeos/settings_controls_types.js
index d3c139c5..63c5ec7e 100644
--- a/chrome/browser/resources/settings/chromeos/settings_controls_types.js
+++ b/chrome/browser/resources/settings/chromeos/settings_controls_types.js
@@ -141,6 +141,8 @@
  *   preferencesSynced: boolean,
  *   readingListRegistered: boolean,
  *   readingListSynced: boolean,
+ *   savedTabGroupsRegistered: boolean,
+ *   savedTabGroupsSynced: boolean,
  *   syncAllDataTypes: boolean,
  *   tabsRegistered: boolean,
  *   tabsSynced: boolean,
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html
index 74f8601..649d4c8 100644
--- a/chrome/browser/resources/settings/controls/settings_checkbox.html
+++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -28,7 +28,7 @@
       aria-label="[[label]]">
     <div id="label" class="label">[[label]] <slot></slot></div>
     <div id="subLabel" class="secondary label">
-      <div inner-h-t-m-l="[[subLabelHtml]]"></div>
+      <div inner-h-t-m-l="[[sanitizeInnerHtml_(subLabelHtml)]]"></div>
       [[subLabel]]
     </div>
   </cr-checkbox>
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.ts b/chrome/browser/resources/settings/controls/settings_checkbox.ts
index 6b86c7b..7e605284 100644
--- a/chrome/browser/resources/settings/controls/settings_checkbox.ts
+++ b/chrome/browser/resources/settings/controls/settings_checkbox.ts
@@ -11,6 +11,7 @@
 import '../settings_shared.css.js';
 
 import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js';
+import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {SettingsBooleanControlMixin} from './settings_boolean_control_mixin.js';
@@ -75,6 +76,10 @@
   private hasSubLabel_(subLabel: string, subLabelHtml: string): boolean {
     return !!subLabel || !!subLabelHtml;
   }
+
+  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
+    return sanitizeInnerHtml(rawString);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/ensure_lazy_loaded.ts b/chrome/browser/resources/settings/ensure_lazy_loaded.ts
index b44d2aa6..a4b3fdc2 100644
--- a/chrome/browser/resources/settings/ensure_lazy_loaded.ts
+++ b/chrome/browser/resources/settings/ensure_lazy_loaded.ts
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {getTrustedScriptURL} from 'chrome://resources/js/static_types.js';
+
 let lazyLoadPromise: Promise<void>|null = null;
 
 /** @return Resolves when the lazy load module is imported. */
@@ -9,7 +11,7 @@
   if (lazyLoadPromise === null) {
     const script = document.createElement('script');
     script.type = 'module';
-    script.src = './lazy_load.js';
+    script.src = getTrustedScriptURL`./lazy_load.js`;
     document.body.appendChild(script);
 
     lazyLoadPromise =
diff --git a/chrome/browser/resources/settings/people_page/signout_dialog.ts b/chrome/browser/resources/settings/people_page/signout_dialog.ts
index cee7ad1..7bc56c17 100644
--- a/chrome/browser/resources/settings/people_page/signout_dialog.ts
+++ b/chrome/browser/resources/settings/people_page/signout_dialog.ts
@@ -18,6 +18,7 @@
 
 import {CrDialogElement} from '//resources/cr_elements/cr_dialog/cr_dialog.js';
 import {WebUiListenerMixin} from '//resources/cr_elements/web_ui_listener_mixin.js';
+import {sanitizeInnerHtml} from '//resources/js/parse_html_subset.js';
 import {microTask, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {loadTimeData} from '../i18n_setup.js';
@@ -126,19 +127,20 @@
   }
 
   // <if expr="not chromeos_ash">
-  private getDisconnectExplanationHtml_(domain: string): string {
+  private getDisconnectExplanationHtml_(domain: string): TrustedHTML {
     if (domain) {
-      return loadTimeData.getStringF(
-          'syncDisconnectManagedProfileExplanation',
-          '<span id="managed-by-domain-name">' + domain + '</span>');
+      return sanitizeInnerHtml(loadTimeData.getStringF(
+          'syncDisconnectManagedProfileExplanation', `<span>${domain}</span>`));
     }
-    return loadTimeData.getString('syncDisconnectExplanation');
+    return sanitizeInnerHtml(
+        loadTimeData.getString('syncDisconnectExplanation'));
   }
   // </if>
 
   // <if expr="chromeos_ash">
-  private getDisconnectExplanationHtml_(_domain: string): string {
-    return loadTimeData.getString('syncDisconnectExplanation');
+  private getDisconnectExplanationHtml_(_domain: string): TrustedHTML {
+    return sanitizeInnerHtml(
+        loadTimeData.getString('syncDisconnectExplanation'));
   }
   // </if>
 
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.ts b/chrome/browser/resources/settings/people_page/sync_browser_proxy.ts
index d2ce22c..94bdc51 100644
--- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.ts
+++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.ts
@@ -110,6 +110,7 @@
   'passwordsSynced',
   'paymentsIntegrationEnabled',
   'preferencesSynced',
+  'savedTabGroupsSynced',
   'tabsSynced',
   'themesSynced',
   'typedUrlsSynced',
diff --git a/chrome/browser/resources/settings/people_page/sync_page.ts b/chrome/browser/resources/settings/people_page/sync_page.ts
index 4e6a8aa..39b10aa 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.ts
+++ b/chrome/browser/resources/settings/people_page/sync_page.ts
@@ -236,7 +236,7 @@
   // </if>
 
   private enterPassphraseLabel_: TrustedHTML;
-  private existingPassphraseLabel_: string;
+  private existingPassphraseLabel_: TrustedHTML;
 
   private browserProxy_: SyncBrowserProxy = SyncBrowserProxyImpl.getInstance();
   private collapsibleSectionsInitialized_: boolean;
@@ -566,18 +566,18 @@
     });
   }
 
-  private computeExistingPassphraseLabel_(): string {
+  private computeExistingPassphraseLabel_(): TrustedHTML {
     if (!this.syncPrefs || !this.syncPrefs.encryptAllData) {
-      return '';
+      return window.trustedTypes!.emptyHTML;
     }
 
     if (!this.syncPrefs.explicitPassphraseTime) {
-      return this.i18n('existingPassphraseLabel');
+      return this.i18nAdvanced('existingPassphraseLabel');
     }
 
-    return this.i18n(
-        'existingPassphraseLabelWithDate',
-        this.syncPrefs.explicitPassphraseTime);
+    return this.i18nAdvanced('existingPassphraseLabelWithDate', {
+      substitutions: [this.syncPrefs.explicitPassphraseTime],
+    });
   }
 
   /**
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
index ce0fbea..099fd43 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
@@ -25,7 +25,7 @@
 <div id="descriptionItemWrapper">
   <iron-icon icon="[[icon]]" aria-hidden="true"></iron-icon>
   <div class="secondary">
-    <div inner-h-t-m-l="[[labelHtml]]"></div>
+    <div inner-h-t-m-l="[[sanitizeInnerHtml_(labelHtml)]]"></div>
     [[label]]
   </div>
 </div>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
index c4153bb..d61b535 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
@@ -11,6 +11,7 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../../settings_shared.css.js';
 
+import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './privacy_guide_description_item.html.js';
@@ -42,6 +43,10 @@
       },
     };
   }
+
+  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
+    return sanitizeInnerHtml(rawString);
+  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/settings/privacy_page/secure_dns.ts b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
index e6c5dab5..4b3de5aa 100644
--- a/chrome/browser/resources/settings/privacy_page/secure_dns.ts
+++ b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
@@ -23,8 +23,9 @@
 import './secure_dns_input.js';
 
 import {CrRadioGroupElement} from 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.js';
-import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
+import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js';
@@ -139,7 +140,7 @@
   private secureDnsRadio_: SecureDnsMode;
   private resolverOptions_: ResolverOption[];
   private lastResolverOption_: string;
-  private privacyPolicyString_: string;
+  private privacyPolicyString_: TrustedHTML;
   private secureDnsInputValue_: string;
   private browserProxy_: PrivacyPageBrowserProxy =
       PrivacyPageBrowserProxyImpl.getInstance();
@@ -393,9 +394,9 @@
       return;
     }
 
-    this.privacyPolicyString_ = loadTimeData.substituteString(
+    this.privacyPolicyString_ = sanitizeInnerHtml(loadTimeData.substituteString(
         loadTimeData.getString('secureDnsSecureDropdownModePrivacyPolicy'),
-        resolver.policy);
+        resolver.policy));
   }
 
   /**
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
index fdc696d..703e648e 100644
--- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
+++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
@@ -14,8 +14,8 @@
         [[getPageTitle_(isTriggered_, triggeredResetToolName_)]]
       </div>
       <div id="dialog-body" slot="body">
-        <span inner-h-t-m-l="
-          [[getExplanationText_(isTriggered_, triggeredResetToolName_)]]">
+        <span inner-h-t-m-l="[[getExplanationText_(
+              isTriggered_, triggeredResetToolName_)]]">
         </span>
         <span>
           <a href="$i18nRaw{resetPageLearnMoreUrl}" target="_blank">
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
index dd01a48..3b40ac8 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
@@ -43,8 +43,9 @@
     aria-label="[[getStatusIconAriaLabel_(iconStatus)]]">
 </iron-icon>
 <div class="flex cr-padded-text">
-  <div id="label" inner-h-t-m-l="[[label]]"></div>
-  <div id="subLabel" class="secondary" no-search inner-h-t-m-l="[[subLabel]]">
+  <div id="label" inner-h-t-m-l="[[sanitizeInnerHtml_(label)]]"></div>
+  <div id="subLabel" class="secondary" no-search
+      inner-h-t-m-l="[[sanitizeInnerHtml_(subLabel)]]">
   </div>
 </div>
 <template is="dom-if" if="[[showButton_(buttonLabel)]]" restamp>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts b/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
index 670529570..ab2fe857 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
@@ -16,8 +16,9 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../settings_shared.css.js';
 
-import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
+import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './safety_check_child.html.js';
@@ -197,6 +198,10 @@
     // For cr-actionable-row-style.
     this.toggleAttribute('effectively-disabled_', !this.rowClickable);
   }
+
+  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
+    return sanitizeInnerHtml(rawString);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/settings.ts b/chrome/browser/resources/settings/settings.ts
index acd9c8e..db35018 100644
--- a/chrome/browser/resources/settings/settings.ts
+++ b/chrome/browser/resources/settings/settings.ts
@@ -14,6 +14,7 @@
 export {CrToolbarElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
 export {CrToolbarSearchFieldElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js';
 export {PluralStringProxyImpl as SettingsPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
+export {getTrustedHTML} from 'chrome://resources/js/static_types.js';
 export {SettingsAboutPageElement} from './about_page/about_page.js';
 export {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, UpdateStatus} from './about_page/about_page_browser_proxy.js';
 // <if expr="_google_chrome and is_macosx">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.ts b/chrome/browser/resources/settings/site_settings/site_details_permission.ts
index 8f57381a..a77ae8a 100644
--- a/chrome/browser/resources/settings/site_settings/site_details_permission.ts
+++ b/chrome/browser/resources/settings/site_settings/site_details_permission.ts
@@ -13,9 +13,10 @@
 import '../settings_vars.css.js';
 import '../i18n_setup.js';
 
-import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
+import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {ContentSetting, ContentSettingsTypes, SiteSettingSource} from './constants.js';
@@ -232,7 +233,7 @@
       setting: ContentSetting): boolean {
     // This method assumes that an empty string will be returned for categories
     // that have no permission info string.
-    return this.permissionInfoString_(
+    return String(this.permissionInfoString_(
                source, category, setting,
                // Set all permission info string arguments as null. This is OK
                // because there is no need to know what the information string
@@ -241,7 +242,7 @@
                // <if expr="is_win and _google_chrome">
                null,
                // </if>
-               null, null, null, null, null, null) !== '';
+               null, null, null, null, null, null)) !== '';
   }
 
   /**
@@ -343,16 +344,16 @@
    * @param setting The permission setting.
    * @param  allowlistString The string to show if the permission is
    *     allowlisted.
-   * @param adsBlacklistString The string to show if the site is
-   *     blacklisted for showing bad ads.
+   * @param adsBlocklistString The string to show if the site is
+   *     blocklisted for showing bad ads.
    * @param adsBlockString The string to show if ads are blocked, but
-   *     the site is not blacklisted.
+   *     the site is not blocklisted.
    * @return The permission information string to display in the HTML.
    */
   private permissionInfoString_(
       source: SiteSettingSource, category: ContentSettingsTypes,
       setting: ContentSetting, allowlistString: string|null,
-      adsBlacklistString: string|null, adsBlockString: string|null,
+      adsBlocklistString: string|null, adsBlockString: string|null,
       embargoString: string|null, insecureOriginString: string|null,
       killSwitchString: string|null,
       // <if expr="is_win and _google_chrome">
@@ -361,10 +362,10 @@
       extensionAllowString: string|null, extensionBlockString: string|null,
       extensionAskString: string|null, policyAllowString: string|null,
       policyBlockString: string|null,
-      policyAskString: string|null): (string|null) {
+      policyAskString: string|null): (TrustedHTML|null) {
     if (source === undefined || category === undefined ||
         setting === undefined) {
-      return null;
+      return window.trustedTypes!.emptyHTML;
     }
 
     const extensionStrings: {[key: string]: string|null} = {};
@@ -377,46 +378,50 @@
     policyStrings[ContentSetting.BLOCK] = policyBlockString;
     policyStrings[ContentSetting.ASK] = policyAskString;
 
+    function htmlOrNull(str: string|null): TrustedHTML|null {
+      return str === null ? null : sanitizeInnerHtml(str);
+    }
+
     if (source === SiteSettingSource.ALLOWLIST) {
-      return allowlistString;
+      return htmlOrNull(allowlistString);
     } else if (source === SiteSettingSource.ADS_FILTER_BLACKLIST) {
       assert(
           ContentSettingsTypes.ADS === category,
-          'The ads filter blacklist only applies to Ads.');
-      return adsBlacklistString;
+          'The ads filter blocklist only applies to Ads.');
+      return htmlOrNull(adsBlocklistString);
     } else if (
         category === ContentSettingsTypes.ADS &&
         setting === ContentSetting.BLOCK) {
-      return adsBlockString;
+      return htmlOrNull(adsBlockString);
     } else if (source === SiteSettingSource.EMBARGO) {
       assert(
           ContentSetting.BLOCK === setting,
           'Embargo is only used to block permissions.');
-      return embargoString;
+      return htmlOrNull(embargoString);
     } else if (source === SiteSettingSource.EXTENSION) {
-      return extensionStrings[setting];
+      return htmlOrNull(extensionStrings[setting]);
     } else if (source === SiteSettingSource.INSECURE_ORIGIN) {
       assert(
           ContentSetting.BLOCK === setting,
           'Permissions can only be blocked due to insecure origins.');
-      return insecureOriginString;
+      return htmlOrNull(insecureOriginString);
     } else if (source === SiteSettingSource.KILL_SWITCH) {
       assert(
           ContentSetting.BLOCK === setting,
           'The permissions kill switch can only be used to block permissions.');
-      return killSwitchString;
+      return htmlOrNull(killSwitchString);
     } else if (source === SiteSettingSource.POLICY) {
-      return policyStrings[setting];
+      return htmlOrNull(policyStrings[setting]);
       // <if expr="is_win and _google_chrome">
     } else if (
         category === ContentSettingsTypes.PROTECTED_CONTENT &&
         setting === ContentSetting.ALLOW) {
-      return protectedContentIdentifierAllowedString;
+      return htmlOrNull(protectedContentIdentifierAllowedString);
       // </if>
     } else if (
         source === SiteSettingSource.DEFAULT ||
         source === SiteSettingSource.PREFERENCE) {
-      return '';
+      return window.trustedTypes!.emptyHTML;
     }
     assertNotReached(`No string for ${category} setting source '${source}'`);
   }
diff --git a/chrome/browser/sessions/session_restore_interactive_uitest.cc b/chrome/browser/sessions/session_restore_interactive_uitest.cc
index 3801b501..8434f9a 100644
--- a/chrome/browser/sessions/session_restore_interactive_uitest.cc
+++ b/chrome/browser/sessions/session_restore_interactive_uitest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/startup/startup_tab.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
@@ -147,6 +148,9 @@
   ASSERT_EQ(url1_,
             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
 
+  ui_test_utils::BrowserActivationWaiter waiter(new_browser);
+  waiter.WaitForActivation();
+
   // Ensure window has initial focus on launch.
   EXPECT_TRUE(new_browser->tab_strip_model()
                   ->GetActiveWebContents()
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
index 8f1bae4..324ec44 100644
--- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
@@ -105,11 +105,10 @@
     boolean isSigninDisabledByPolicy();
 
     /**
-     * Returns whether the user can sign-in (maybe after an update to Google Play services).
-     * @param requireUpdatedPlayServices Indicates whether an updated version of play services is
-     *         required or not.
+     * @return Whether true if the current user is not demo user and the user has a reasonable
+     *         Google Play Services installed.
      */
-    boolean isSigninSupported(boolean requireUpdatedPlayServices);
+    boolean isSigninSupported();
 
     /**
      * @return Whether force sign-in is enabled by policy.
diff --git a/chrome/browser/supervised_user/web_approvals_manager.cc b/chrome/browser/supervised_user/web_approvals_manager.cc
index 8d9f9c9..d7955e2 100644
--- a/chrome/browser/supervised_user/web_approvals_manager.cc
+++ b/chrome/browser/supervised_user/web_approvals_manager.cc
@@ -32,6 +32,8 @@
 
 constexpr char kLocalWebApprovalDurationHistogramName[] =
     "FamilyLinkUser.LocalWebApprovalCompleteRequestTotalDuration";
+constexpr char kLocalWebApprovalResultHistogramName[] =
+    "FamilyLinkUser.LocalWebApprovalResult";
 
 void CreateURLAccessRequest(
     const GURL& url,
@@ -53,6 +55,28 @@
   }
 }
 
+void RecordLocalApprovalResultMetricForAndroidOutcome(
+    AndroidLocalWebApprovalFlowOutcome outcome) {
+  WebApprovalsManager::LocalApprovalResultMetric histogram_enum =
+      WebApprovalsManager::LocalApprovalResultMetric::kError;
+  switch (outcome) {
+    case AndroidLocalWebApprovalFlowOutcome::kApproved:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kApproved;
+      break;
+    case AndroidLocalWebApprovalFlowOutcome::kRejected:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kDeclined;
+      break;
+    case AndroidLocalWebApprovalFlowOutcome::kIncomplete:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kCanceled;
+      break;
+  }
+  base::UmaHistogramEnumeration(kLocalWebApprovalResultHistogramName,
+                                histogram_enum);
+}
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Helper method for getting human readable outcome for a local web approval.
 std::string ParentAccessResultToLoggingStringChromeOS(
@@ -68,6 +92,31 @@
       return "Error";
   }
 }
+
+void RecordLocalApprovalResultMetricForChromeOSResult(
+    ash::ParentAccessDialog::Result::Status result) {
+  WebApprovalsManager::LocalApprovalResultMetric histogram_enum =
+      WebApprovalsManager::LocalApprovalResultMetric::kError;
+  switch (result) {
+    case ash::ParentAccessDialog::Result::Status::kApproved:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kApproved;
+      break;
+    case ash::ParentAccessDialog::Result::Status::kDeclined:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kDeclined;
+      break;
+    case ash::ParentAccessDialog::Result::Status::kCancelled:
+      histogram_enum =
+          WebApprovalsManager::LocalApprovalResultMetric::kCanceled;
+      break;
+    case ash::ParentAccessDialog::Result::Status::kError:
+      histogram_enum = WebApprovalsManager::LocalApprovalResultMetric::kError;
+      break;
+  }
+  base::UmaHistogramEnumeration(kLocalWebApprovalResultHistogramName,
+                                histogram_enum);
+}
 #endif
 
 void RecordTimeToApprovalDurationMetric(base::TimeDelta durationMs) {
@@ -77,6 +126,17 @@
 
 }  // namespace
 
+// static
+const char*
+WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram() {
+  return kLocalWebApprovalDurationHistogramName;
+}
+
+// static
+const char* WebApprovalsManager::GetLocalApprovalResultHistogram() {
+  return kLocalWebApprovalResultHistogramName;
+}
+
 WebApprovalsManager::WebApprovalsManager() = default;
 
 WebApprovalsManager::~WebApprovalsManager() = default;
@@ -115,6 +175,8 @@
   if (result != ash::ParentAccessDialogProvider::ShowError::kNone) {
     LOG(ERROR) << "Error showing ParentAccessDialog: "
                << static_cast<int>(result);
+    base::UmaHistogramEnumeration(kLocalWebApprovalResultHistogramName,
+                                  LocalApprovalResultMetric::kError);
     std::move(callback).Run(false);
     return;
   }
@@ -216,6 +278,8 @@
     RecordTimeToApprovalDurationMetric(base::TimeTicks::Now() - start_time);
   }
 
+  RecordLocalApprovalResultMetricForAndroidOutcome(request_outcome);
+
   if (request_outcome == AndroidLocalWebApprovalFlowOutcome::kApproved) {
     settings_service->RecordLocalWebsiteApproval(url.host());
   }
@@ -236,7 +300,8 @@
     RecordTimeToApprovalDurationMetric(base::TimeTicks::Now() - start_time);
   }
 
-  // TODO(b/250947827): Add request result metric for CrOS.
+  RecordLocalApprovalResultMetricForChromeOSResult(result->status);
+
   if (result->status == ash::ParentAccessDialog::Result::Status::kApproved) {
     settings_service->RecordLocalWebsiteApproval(url.host());
   }
diff --git a/chrome/browser/supervised_user/web_approvals_manager.h b/chrome/browser/supervised_user/web_approvals_manager.h
index d8ff37d..5238050 100644
--- a/chrome/browser/supervised_user/web_approvals_manager.h
+++ b/chrome/browser/supervised_user/web_approvals_manager.h
@@ -50,6 +50,26 @@
   // successfully.
   using ApprovalRequestInitiatedCallback = base::OnceCallback<void(bool)>;
 
+  // The result of local web approval flow used for metrics.
+  // Those values are logged to UMA. Entries should not be renumbered and
+  // numeric values should never be reused. Please keep in sync with
+  // "FamilyLinkUserLocalWebApprovalResult" in
+  // src/tools/metrics/histograms/enums.xml.
+  enum class LocalApprovalResultMetric {
+    kApproved = 0,
+    kDeclined = 1,
+    kCanceled = 2,
+    kError = 3,
+    kMaxValue = kError
+  };
+
+  // Returns the name of the local approval duration histogram.
+  // The duration is recorded in milliseconds.
+  static const char* GetLocalApprovalDurationMillisecondsHistogram();
+
+  // Returns the name of the local approval result histogram.
+  static const char* GetLocalApprovalResultHistogram();
+
   WebApprovalsManager();
 
   WebApprovalsManager(const WebApprovalsManager&) = delete;
diff --git a/chrome/browser/supervised_user/web_approvals_manager_unittest.cc b/chrome/browser/supervised_user/web_approvals_manager_unittest.cc
index b8ed4ae..65f9daa2 100644
--- a/chrome/browser/supervised_user/web_approvals_manager_unittest.cc
+++ b/chrome/browser/supervised_user/web_approvals_manager_unittest.cc
@@ -95,9 +95,6 @@
   MOCK_METHOD1(RecordLocalWebsiteApproval, void(const std::string& host));
 };
 
-constexpr char kLocalWebApprovalDurationHistogramName[] =
-    "FamilyLinkUser.LocalWebApprovalCompleteRequestTotalDuration";
-
 }  // namespace
 
 class WebApprovalsManagerTest : public ::testing::Test {
@@ -230,16 +227,25 @@
       &supervisedUserSettingsServiceMock, url, start_time,
       AndroidLocalWebApprovalFlowOutcome::kRejected);
 
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 1);
-  histogram_tester.ExpectTimeBucketCount(kLocalWebApprovalDurationHistogramName,
-                                         elapsed_time, 1);
+  histogram_tester.ExpectBucketCount(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kDeclined, 1);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 1);
+  histogram_tester.ExpectTimeBucketCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(),
+      elapsed_time, 1);
 
   // Receive a request cancelled by the parent.
   // Check that no duration metric is recorded for incomplete requests.
   web_approvals_manager().OnLocalApprovalRequestCompleted(
       &supervisedUserSettingsServiceMock, url, start_time,
       AndroidLocalWebApprovalFlowOutcome::kIncomplete);
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 1);
+  histogram_tester.ExpectBucketCount(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kCanceled, 1);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 1);
 
   // Receive a request accepted by the parent with a total duration of 5
   // minutes. Check that duration metric is recorded.
@@ -253,9 +259,17 @@
   web_approvals_manager().OnLocalApprovalRequestCompleted(
       &supervisedUserSettingsServiceMock, url, start_time,
       AndroidLocalWebApprovalFlowOutcome::kApproved);
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 2);
-  histogram_tester.ExpectTimeBucketCount(kLocalWebApprovalDurationHistogramName,
-                                         elapsed_time, 1);
+  histogram_tester.ExpectBucketCount(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kApproved, 1);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(), 3);
+
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 2);
+  histogram_tester.ExpectTimeBucketCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(),
+      elapsed_time, 1);
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -281,9 +295,14 @@
       &supervisedUserSettingsServiceMock, url, start_time,
       std::move(dialog_result));
 
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 1);
-  histogram_tester.ExpectTimeBucketCount(kLocalWebApprovalDurationHistogramName,
-                                         approval_duration, 1);
+  histogram_tester.ExpectUniqueSample(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kApproved, 1);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 1);
+  histogram_tester.ExpectTimeBucketCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(),
+      approval_duration, 1);
 }
 
 TEST_F(WebApprovalsManagerTest, LocalWebApprovalDeclinedChromeOSTest) {
@@ -309,9 +328,14 @@
       &supervisedUserSettingsServiceMock, url, start_time,
       std::move(dialog_result));
 
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 1);
-  histogram_tester.ExpectTimeBucketCount(kLocalWebApprovalDurationHistogramName,
-                                         approval_duration, 1);
+  histogram_tester.ExpectUniqueSample(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kDeclined, 1);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 1);
+  histogram_tester.ExpectTimeBucketCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(),
+      approval_duration, 1);
 }
 
 TEST_F(WebApprovalsManagerTest, LocalWebApprovalCancelledChromeOSTest) {
@@ -338,7 +362,11 @@
       std::move(dialog_result));
 
   // Check that the approval duration was NOT recorded for canceled request.
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 0);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 0);
+  histogram_tester.ExpectUniqueSample(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kCanceled, 1);
 }
 
 TEST_F(WebApprovalsManagerTest, LocalWebApprovalErrorChromeOSTest) {
@@ -365,6 +393,10 @@
       std::move(dialog_result));
 
   // Check that the approval duration was NOT recorded on error.
-  histogram_tester.ExpectTotalCount(kLocalWebApprovalDurationHistogramName, 0);
+  histogram_tester.ExpectTotalCount(
+      WebApprovalsManager::GetLocalApprovalDurationMillisecondsHistogram(), 0);
+  histogram_tester.ExpectUniqueSample(
+      WebApprovalsManager::GetLocalApprovalResultHistogram(),
+      WebApprovalsManager::LocalApprovalResultMetric::kError, 1);
 }
 #endif
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 882278f..4f1a0e3d 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -42,6 +42,7 @@
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/themes/theme_syncable_service.h"
 #include "chrome/browser/ui/read_later/reading_list_model_factory.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/channel_info.h"
@@ -124,6 +125,13 @@
 #include "components/sync/trusted_vault/standalone_trusted_vault_client.h"  // nogncheck
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h"
+#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/components/arc/arc_util.h"
 #include "ash/constants/ash_features.h"
@@ -443,6 +451,18 @@
             GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack));
 #endif  // !BUILDFLAG(IS_ANDROID)
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+    if (features::kTabGroupsSaveSyncIntegration.Get()) {
+      controllers.push_back(std::make_unique<syncer::ModelTypeController>(
+          syncer::SAVED_TAB_GROUP,
+          std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
+              GetControllerDelegateForModelType(syncer::SAVED_TAB_GROUP)
+                  .get())));
+    }
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
+
 // Chrome prefers OS provided spell checkers where they exist. So only sync the
 // custom dictionary on platforms that typically don't provide one.
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
@@ -610,6 +630,17 @@
           ->change_processor()
           ->GetControllerDelegate();
     }
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+    case syncer::SAVED_TAB_GROUP: {
+      DCHECK(features::kTabGroupsSaveSyncIntegration.Get());
+      return SavedTabGroupServiceFactory::GetForProfile(profile_)
+          ->bridge()
+          ->change_processor()
+          ->GetControllerDelegate();
+    }
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     case syncer::PRINTERS:
       return ash::SyncedPrintersManagerFactory::GetForBrowserContext(profile_)
diff --git a/chrome/browser/sync/sync_service_factory.cc b/chrome/browser/sync/sync_service_factory.cc
index 1598ab3..6aedbbd 100644
--- a/chrome/browser/sync/sync_service_factory.cc
+++ b/chrome/browser/sync/sync_service_factory.cc
@@ -73,6 +73,12 @@
 #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
+
 namespace {
 
 std::unique_ptr<KeyedService> BuildSyncService(
@@ -244,6 +250,11 @@
 #if !BUILDFLAG(IS_ANDROID)
   DependsOn(ThemeServiceFactory::GetInstance());
 #endif  // !BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+  DependsOn(SavedTabGroupServiceFactory::GetInstance());
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
   DependsOn(WebDataServiceFactory::GetInstance());
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   DependsOn(
diff --git a/chrome/browser/sync/sync_service_factory_unittest.cc b/chrome/browser/sync/sync_service_factory_unittest.cc
index a7deb37..6b8d3000 100644
--- a/chrome/browser/sync/sync_service_factory_unittest.cc
+++ b/chrome/browser/sync/sync_service_factory_unittest.cc
@@ -15,6 +15,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/test/base/testing_profile.h"
@@ -117,6 +118,14 @@
     datatypes.Put(syncer::SEARCH_ENGINES);
 #endif  // !BUILDFLAG(IS_ANDROID)
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN)
+    if (features::kTabGroupsSaveSyncIntegration.Get()) {
+      datatypes.Put(syncer::SAVED_TAB_GROUP);
+    }
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
+        // BUILDFLAG(IS_WIN)
+
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
     datatypes.Put(syncer::DICTIONARY);
 #endif
diff --git a/chrome/browser/sync/test/integration/local_sync_test.cc b/chrome/browser/sync/test/integration/local_sync_test.cc
index 550cc015..78deb147 100644
--- a/chrome/browser/sync/test/integration/local_sync_test.cc
+++ b/chrome/browser/sync/test/integration/local_sync_test.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/browser_sync/browser_sync_switches.h"
 #include "components/sync/base/command_line_switches.h"
@@ -105,6 +106,10 @@
       syncer::PRIORITY_PREFERENCES, syncer::WEB_APPS, syncer::PROXY_TABS,
       syncer::NIGORI);
 
+  if (features::kTabGroupsSaveSyncIntegration.Get()) {
+    expected_active_data_types.Put(syncer::SAVED_TAB_GROUP);
+  }
+
   // The dictionary is currently only synced on Windows and Linux.
   // TODO(crbug.com/1052397): Reassess whether the following block needs to be
   // included
@@ -114,7 +119,6 @@
 #if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   expected_active_data_types.Put(syncer::DICTIONARY);
 #endif
-
   EXPECT_EQ(service->GetActiveDataTypes(), expected_active_data_types);
 
   // Verify certain features are disabled.
diff --git a/chrome/browser/sync/test/integration/password_manager_sync_test.cc b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
index 3addec7c..8127cb95 100644
--- a/chrome/browser/sync/test/integration/password_manager_sync_test.cc
+++ b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
@@ -887,7 +887,7 @@
   // during startup, and the credential added by the PRE_ test should be gone.
   EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), IsEmpty());
   histograms.ExpectUniqueSample(
-      "PasswordManager.AccountStorage.ClearedOnStartup",
+      "PasswordManager.AccountStorage.ClearedOnStartup2",
       /*sample=*/kNotOptedInAndHadToClear, 1);
 
   // Just as a sanity check: The credential in the profile-scoped store should
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
index e3b86598..acf839c 100644
--- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -844,7 +844,7 @@
   // fields, running into the initial sync flow is not expected. Since the
   // bridge is initialized for both account and profile store, the metric is
   // expected to be recorded twice.
-  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError",
+  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2",
                                       kNone, /*expected_bucket_count=*/2);
 }
 
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 06e8bf5f..0b73f04 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4222,6 +4222,9 @@
       <message name="IDS_WEB_FEED_FOLLOW_SUCCESS_SNACKBAR_ACTION_GO_TO_FOLLOWING" desc="The snackbar action after a successful Web Feed follow request, that will take the user to the Following feed.">
         Go to Following
       </message>
+      <message name="IDS_WEB_FEED_FOLLOW_SUCCESS_SNACKBAR_ACTION_REFRESH" desc="The snackbar action after a successful Web Feed follow request, that will refresh the Following feed contents.">
+        Refresh to view
+      </message>
       <message name="IDS_WEB_FEED_FOLLOW_GENERIC_FAILURE_SNACKBAR_MESSAGE" desc="The generic snackbar message after an unsuccessful Web Feed follow request.">
         Can’t follow. Something went wrong.
       </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEB_FEED_FOLLOW_SUCCESS_SNACKBAR_ACTION_REFRESH.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEB_FEED_FOLLOW_SUCCESS_SNACKBAR_ACTION_REFRESH.png.sha1
new file mode 100644
index 0000000..1df0e74
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEB_FEED_FOLLOW_SUCCESS_SNACKBAR_ACTION_REFRESH.png.sha1
@@ -0,0 +1 @@
+06b1466a0efb412668db3485de154770b9498dfd
\ No newline at end of file
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
index d2d14581..b1f1edb 100644
--- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -385,6 +385,32 @@
   base::RunLoop run_loop_;
 };
 
+class BrowsersRemovedObserver : public BrowserListObserver {
+ public:
+  explicit BrowsersRemovedObserver(int browser_removes_expected)
+      : browser_removes_left_(browser_removes_expected) {
+    BrowserList::AddObserver(this);
+  }
+  BrowsersRemovedObserver(const BrowsersRemovedObserver&) = delete;
+  BrowsersRemovedObserver& operator=(const BrowsersRemovedObserver&) = delete;
+  ~BrowsersRemovedObserver() override { BrowserList::RemoveObserver(this); }
+
+  void Wait() { run_loop_.Run(); }
+
+  // BrowserListObserver:
+  void OnBrowserAdded(Browser* browser) override {}
+
+  void OnBrowserRemoved(Browser* browser) override {
+    --browser_removes_left_;
+    if (browser_removes_left_ == 0)
+      run_loop_.Quit();
+  }
+
+ private:
+  int browser_removes_left_;
+  base::RunLoop run_loop_;
+};
+
 }  // namespace
 
 // Scoped class that temporarily sets a new app launch handler for testing
@@ -2789,8 +2815,7 @@
 using SaveAndRecallBrowserTest = DesksClientTest;
 
 IN_PROC_BROWSER_TEST_F(SaveAndRecallBrowserTest,
-                       // TODO(crbug.com/1360326): Re-enable this test
-                       DISABLED_SystemUIBlockingDialogAccepted) {
+                       SystemUIBlockingDialogAccepted) {
   SetupBrowserToConfirmClose(browser());
 
   // We'll now save the desk as Save & Recall. After saving desks, this
@@ -2805,8 +2830,9 @@
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
 
   // Send a key to OK the close dialog.
+  BrowsersRemovedObserver browsers_removed(/*browser_removes_expected=*/1);
   ash::SendKey(ui::VKEY_RETURN);
-  content::RunAllTasksUntilIdle();
+  browsers_removed.Wait();
 
   EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
 
diff --git a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
index b9ae706..6b80bcb 100644
--- a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
+++ b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
@@ -26,7 +26,7 @@
 // The total number of Ash accelerators.
 constexpr int kAshAcceleratorsTotalNum = 142;
 // The hash of Ash accelerators.
-constexpr char kAshAcceleratorsHash[] = "315a877b9ba123c29d1fe7019efc7069";
+constexpr char kAshAcceleratorsHash[] = "91d54520506af00e73259e0bb2a291ed";
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Internal builds add an extra accelerator for the Feedback app.
 // The total number of Chrome accelerators (available on Chrome OS).
diff --git a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc
index 6a5e284..0ffe6c3 100644
--- a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc
+++ b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc
@@ -37,12 +37,11 @@
   switch (intent_type) {
     case IntentType::kUnit:
       return l10n_util::GetStringUTF16(
-          IDS_ASH_QUICK_ANSWERS_UNIT_CONVERSION_INTENT);
+          IDS_QUICK_ANSWERS_UNIT_CONVERSION_INTENT);
     case IntentType::kDictionary:
-      return l10n_util::GetStringUTF16(IDS_ASH_QUICK_ANSWERS_DEFINITION_INTENT);
+      return l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_DEFINITION_INTENT);
     case IntentType::kTranslation:
-      return l10n_util::GetStringUTF16(
-          IDS_ASH_QUICK_ANSWERS_TRANSLATION_INTENT);
+      return l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_TRANSLATION_INTENT);
     case IntentType::kUnknown:
       return std::u16string();
   }
@@ -188,7 +187,7 @@
         std::make_unique<quick_answers::QuickAnswerText>(title_));
     quick_answer_with_no_result.first_answer_row.push_back(
         std::make_unique<quick_answers::QuickAnswerResultText>(
-            l10n_util::GetStringUTF8(IDS_ASH_QUICK_ANSWERS_VIEW_NO_RESULT_V2)));
+            l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_VIEW_NO_RESULT_V2)));
     quick_answers_ui_controller_->RenderQuickAnswersViewWithResult(
         anchor_bounds_, quick_answer_with_no_result);
     // Fallback query to title if no result is available.
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
index 2457f9bf..6be17249 100644
--- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
+++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
@@ -170,7 +170,7 @@
 
   explicit MainView(PressedCallback callback) : Button(std::move(callback)) {
     SetAccessibleName(
-        l10n_util::GetStringUTF16(IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT));
+        l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT));
     SetInstallFocusRingOnFocus(false);
     set_suppress_default_focus_handling();
 
@@ -239,7 +239,7 @@
 
     description_label_ = AddChildView(std::make_unique<Label>(
         l10n_util::GetStringUTF16(
-            IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL),
+            IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL),
         Label::CustomFont{gfx::FontList({kGoogleSansFont}, gfx::Font::ITALIC,
                                         kReportQueryViewFontSize,
                                         gfx::Font::Weight::NORMAL)}));
@@ -248,7 +248,7 @@
 
     report_label_ = AddChildView(std::make_unique<Label>(
         l10n_util::GetStringUTF16(
-            IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL),
+            IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL),
         Label::CustomFont{gfx::FontList({kGoogleSansFont}, gfx::Font::NORMAL,
                                         kReportQueryViewFontSize,
                                         gfx::Font::Weight::MEDIUM)}));
@@ -425,7 +425,7 @@
   }
 
   node_data->SetName(
-      l10n_util::GetStringUTF8(IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT));
+      l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT));
 }
 
 void QuickAnswersView::SendQuickAnswersQuery() {
@@ -464,7 +464,7 @@
   // Add error label.
   std::vector<std::unique_ptr<QuickAnswerUiElement>> description_labels;
   description_labels.push_back(std::make_unique<QuickAnswerResultText>(
-      l10n_util::GetStringUTF8(IDS_ASH_QUICK_ANSWERS_VIEW_NETWORK_ERROR)));
+      l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_VIEW_NETWORK_ERROR)));
   auto* description_container =
       AddHorizontalUiElements(description_labels, content_view_);
 
@@ -473,18 +473,17 @@
       description_container->AddChildView(std::make_unique<views::LabelButton>(
           base::BindRepeating(&QuickAnswersUiController::OnRetryLabelPressed,
                               controller_),
-          l10n_util::GetStringUTF16(IDS_ASH_QUICK_ANSWERS_VIEW_RETRY)));
+          l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_VIEW_RETRY)));
   retry_label_->SetEnabledTextColors(
       GetColorProvider()->GetColor(ui::kColorProgressBar));
   retry_label_->SetRequestFocusOnPress(true);
   retry_label_->button_controller()->set_notify_action(
       views::ButtonController::NotifyAction::kOnPress);
   retry_label_->SetAccessibleName(l10n_util::GetStringFUTF16(
-      IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE,
-      l10n_util::GetStringUTF16(IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT)));
+      IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE,
+      l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT)));
   retry_label_->GetViewAccessibility().OverrideDescription(
-      l10n_util::GetStringUTF8(
-          IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC));
+      l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC));
 }
 
 void QuickAnswersView::InitLayout() {
@@ -547,7 +546,7 @@
       std::make_unique<QuickAnswersTextLabel>(QuickAnswerText(title_)));
   title_label->SetMaximumWidthSingleLine(GetLabelWidth());
   std::string loading =
-      l10n_util::GetStringUTF8(IDS_ASH_QUICK_ANSWERS_VIEW_LOADING);
+      l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_VIEW_LOADING);
   content_view_->AddChildView(
       std::make_unique<QuickAnswersTextLabel>(QuickAnswerResultText(loading)));
 }
@@ -569,14 +568,14 @@
             &QuickAnswersUiController::OnReportQueryButtonPressed,
             controller_)));
     dogfood_feedback_button_->SetTooltipText(l10n_util::GetStringUTF16(
-        IDS_ASH_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT));
+        IDS_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT));
   }
 
   settings_button_ = buttons_view->AddChildView(
       std::make_unique<views::ImageButton>(base::BindRepeating(
           &QuickAnswersUiController::OnSettingsButtonPressed, controller_)));
   settings_button_->SetTooltipText(l10n_util::GetStringUTF16(
-      IDS_ASH_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT));
+      IDS_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT));
   settings_button_->SetBorder(
       views::CreateEmptyBorder(kSettingsButtonBorderDip));
 }
@@ -607,7 +606,7 @@
           vector_icons::kVolumeUpIcon, kPhoneticsAudioButtonSizeDip,
           GetColorProvider()->GetColor(ui::kColorButtonBackgroundProminent)));
   phonetics_audio_button_->SetTooltipText(l10n_util::GetStringUTF16(
-      IDS_ASH_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT));
+      IDS_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT));
   phonetics_audio_button_->SetBorder(
       views::CreateEmptyBorder(kPhoneticsAudioButtonBorderDip));
 }
@@ -699,7 +698,7 @@
     auto* answer_label =
         static_cast<Label*>(first_answer_view->children().front());
     GetViewAccessibility().OverrideDescription(l10n_util::GetStringFUTF8(
-        IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2,
+        IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2,
         title_label->GetText(), answer_label->GetText()));
   }
 
@@ -723,8 +722,8 @@
     RequestFocus();
   } else {
     // Announce that a Quick Answer is available.
-    GetViewAccessibility().AnnounceText(l10n_util::GetStringUTF16(
-        IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT));
+    GetViewAccessibility().AnnounceText(
+        l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT));
   }
 
   if (quick_answer.result_type == ResultType::kNoResult && is_internal_) {
diff --git a/chrome/browser/ui/quick_answers/ui/user_consent_view.cc b/chrome/browser/ui/quick_answers/ui/user_consent_view.cc
index 3a64538..771c7b5 100644
--- a/chrome/browser/ui/quick_answers/ui/user_consent_view.cc
+++ b/chrome/browser/ui/quick_answers/ui/user_consent_view.cc
@@ -129,11 +129,11 @@
                                         base::Unretained(this))) {
   if (intent_type.empty() || intent_text.empty()) {
     title_text_ = l10n_util::GetStringUTF16(
-        IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT);
+        IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT);
   } else {
     title_text_ = l10n_util::GetStringFUTF16(
-        IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT,
-        intent_type, intent_text);
+        IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT, intent_type,
+        intent_text);
   }
 
   InitLayout();
@@ -151,7 +151,7 @@
 
   // Read out user-consent text if screen-reader is active.
   GetViewAccessibility().AnnounceText(l10n_util::GetStringUTF16(
-      IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT));
+      IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT));
 }
 
 UserConsentView::~UserConsentView() = default;
@@ -193,9 +193,8 @@
   node_data->role = ax::mojom::Role::kDialog;
   node_data->SetName(title_text_);
   auto desc_text = l10n_util::GetStringFUTF8(
-      IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE,
-      l10n_util::GetStringUTF16(
-          IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT));
+      IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE,
+      l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT));
   node_data->SetDescription(desc_text);
 }
 
@@ -263,10 +262,9 @@
   title_->SetMaximumWidthSingleLine(maximum_width);
 
   // Description.
-  desc_ = content_->AddChildView(
-      CreateLabel(l10n_util::GetStringUTF16(
-                      IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT),
-                  kDescFontSizeDelta));
+  desc_ = content_->AddChildView(CreateLabel(
+      l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT),
+      kDescFontSizeDelta));
   desc_->SetMultiLine(true);
 
   desc_->SetMaximumWidth(maximum_width);
@@ -293,7 +291,7 @@
       base::BindRepeating(&QuickAnswersUiController::OnUserConsentResult,
                           controller_, false),
       l10n_util::GetStringUTF16(
-          IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON),
+          IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON),
       ShouldUseCompactButtonLayout(anchor_view_bounds_.width()));
   no_thanks_button_ = button_bar->AddChildView(std::move(no_thanks_button));
 
@@ -310,7 +308,7 @@
           },
           &event_handler_, controller_),
       l10n_util::GetStringUTF16(
-          IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON),
+          IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON),
       ShouldUseCompactButtonLayout(anchor_view_bounds_.width()));
   allow_button->SetProminent(true);
   allow_button_ = button_bar->AddChildView(std::move(allow_button));
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc
index c46e5089..2dad396 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.cc
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -237,7 +237,6 @@
   log_data.push_back(lens::mojom::LatencyLog::New(
       lens::mojom::Phase::ENCODE_END, image_original_size, gfx::Size(),
       image_format, base::Time::Now()));
-  search_args.image_thumbnail_content.assign(data.begin(), data.end());
 
   std::string additional_query_params_modified = additional_query_params;
   if (lens::features::GetEnableLatencyLogging() &&
diff --git a/chrome/browser/ui/views/OWNERS b/chrome/browser/ui/views/OWNERS
index 8797f7da..254282e 100644
--- a/chrome/browser/ui/views/OWNERS
+++ b/chrome/browser/ui/views/OWNERS
@@ -11,6 +11,7 @@
 dfried@chromium.org
 dpenning@chromium.org
 ellyjones@chromium.org
+emshack@chromium.org
 kylixrd@chromium.org
 msw@chromium.org
 pbos@chromium.org
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.cc
index a58cd6c..fcd0688 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.cc
@@ -24,13 +24,11 @@
   Hide();
 }
 
-void ExtensionsTabbedMenuCoordinator::Show(
-    views::View* anchor_view,
-    ExtensionsToolbarButton::ButtonType button_type) {
+void ExtensionsTabbedMenuCoordinator::Show(views::View* anchor_view) {
   DCHECK(base::FeatureList::IsEnabled(
       extensions_features::kExtensionsMenuAccessControl));
   auto menu = std::make_unique<ExtensionsTabbedMenuView>(
-      anchor_view, browser_, extensions_container_, button_type, allow_pining_);
+      anchor_view, browser_, extensions_container_, allow_pining_);
   extensions_tabbed_menu_view_tracker_.SetView(menu.get());
   views::BubbleDialogDelegateView::CreateBubble(std::move(menu))->Show();
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h
index 305f582..4f15578b 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h
@@ -28,10 +28,8 @@
       const ExtensionsTabbedMenuCoordinator&) = delete;
   ~ExtensionsTabbedMenuCoordinator();
 
-  // Displays the ExtensionsTabbedMenu under `anchor_view` with the selected tab
-  // open by the `selected_tab_index` given.
-  void Show(views::View* anchor_view,
-            ExtensionsToolbarButton::ButtonType button_type);
+  // Displays the ExtensionsTabbedMenu under `anchor_view`.
+  void Show(views::View* anchor_view);
 
   // Hides the currently-showing ExtensionsTabbedMenuView, if it exists.
   void Hide();
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
index b662e6d..a28a21a0 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
@@ -57,6 +57,9 @@
 
 using UserSiteSetting = extensions::PermissionsManager::UserSiteSetting;
 
+// Tabs indexes.
+constexpr int kSiteAccesssTabIndex = 0;
+constexpr int kExtensionsTabIndex = 1;
 // Radio buttons group id for site access settings.
 constexpr int kGroupId = 1;
 // Button's indexes for site access settings.
@@ -210,7 +213,6 @@
     views::View* anchor_view,
     Browser* browser,
     ExtensionsContainer* extensions_container,
-    ExtensionsToolbarButton::ButtonType button_type,
     bool allow_pinning)
     : BubbleDialogDelegateView(anchor_view,
                                views::BubbleBorder::Arrow::TOP_RIGHT),
@@ -258,9 +260,8 @@
 
   Populate();
 
-  // Tabs left to right order is 'site access tab' | 'extensions tab'.
-  tabbed_pane_->SelectTabAt(button_type ==
-                            ExtensionsToolbarButton::ButtonType::kExtensions);
+  // By default menu opens in extension tab.
+  tabbed_pane_->SelectTabAt(kExtensionsTabIndex);
 }
 
 ExtensionsTabbedMenuView::~ExtensionsTabbedMenuView() {
@@ -559,7 +560,8 @@
                       kCustomizeByExtensionIndex))
           .Build();
 
-  CreateTab(tabbed_pane_, 0, IDS_EXTENSIONS_MENU_SITE_ACCESS_TAB_TITLE,
+  CreateTab(tabbed_pane_, kSiteAccesssTabIndex,
+            IDS_EXTENSIONS_MENU_SITE_ACCESS_TAB_TITLE,
             std::move(site_access_content), std::move(site_access_footer));
 }
 
@@ -589,7 +591,8 @@
           .CopyAddressTo(&discover_more_button_)
           .Build();
 
-  CreateTab(tabbed_pane_, 1, IDS_EXTENSIONS_MENU_EXTENSIONS_TAB_TITLE,
+  CreateTab(tabbed_pane_, kExtensionsTabIndex,
+            IDS_EXTENSIONS_MENU_EXTENSIONS_TAB_TITLE,
             std::move(installed_items), std::move(installed_tab_footer));
 }
 
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
index 3e5093f..5eb9c3f 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
@@ -39,7 +39,6 @@
   ExtensionsTabbedMenuView(views::View* anchor_view,
                            Browser* browser,
                            ExtensionsContainer* extensions_container,
-                           ExtensionsToolbarButton::ButtonType button_type,
                            bool allow_pinning);
   ~ExtensionsTabbedMenuView() override;
   ExtensionsTabbedMenuView(const ExtensionsTabbedMenuView&) = delete;
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
index 0be9ec6..3c6ce0a 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
@@ -65,10 +65,9 @@
   // Asserts there is exactly one installed menu item and then returns it.
   InstalledExtensionMenuItemView* GetOnlyInstalledMenuItem();
 
-  // Opens the tabbed menu in the installed tab.
-  void ShowInstalledTabInMenu();
-  // Opens the tabbed menu in the site access tab.
-  void ShowSiteAccessTabInMenu();
+  // Opens the menu. Tab opened is not important, since both are populated at
+  // construction.
+  void ShowMenu();
 
   void ClickPrimaryButton(InstalledExtensionMenuItemView* item);
   void ClickPinButton(InstalledExtensionMenuItemView* installed_item);
@@ -91,7 +90,7 @@
   set_should_verify_dialog_bounds(false);
 #endif
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
   ASSERT_TRUE(extensions_tabbed_menu_view());
 }
 
@@ -115,18 +114,11 @@
   return *items.begin();
 }
 
-void ExtensionsTabbedMenuViewInteractiveUITest::ShowInstalledTabInMenu() {
+void ExtensionsTabbedMenuViewInteractiveUITest::ShowMenu() {
   ClickButton(GetExtensionsToolbarContainer()->GetExtensionsButton());
   WaitForAnimation();
 }
 
-void ExtensionsTabbedMenuViewInteractiveUITest::ShowSiteAccessTabInMenu() {
-  ClickButton(GetExtensionsToolbarContainer()
-                  ->GetExtensionsToolbarControls()
-                  ->site_access_button_for_testing());
-  WaitForAnimation();
-}
-
 void ExtensionsTabbedMenuViewInteractiveUITest::RightClickExtensionInToolbar(
     ToolbarActionView* extension) {
   ui::MouseEvent click_down_event(ui::ET_MOUSE_PRESSED, gfx::Point(),
@@ -164,7 +156,7 @@
                        InvocationSourceMetrics) {
   base::HistogramTester histogram_tester;
   LoadTestExtension("extensions/uitest/extension_with_action_and_command");
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   constexpr char kHistogramName[] = "Extensions.Toolbar.InvocationSource";
   histogram_tester.ExpectTotalCount(kHistogramName, 0);
@@ -308,7 +300,7 @@
     ExtensionsTabbedMenuViewInteractiveUITest,
     InstalledTab_PinnedExtensionShowsCorrectContextMenuPinOption) {
   LoadTestExtension("extensions/simple_with_popup");
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   ASSERT_TRUE(VerifyUi());
   ASSERT_EQ(installed_items().size(), 1u);
@@ -350,7 +342,7 @@
     ExtensionsTabbedMenuViewInteractiveUITest,
     InstalledTab_UnpinnedExtensionShowsCorrectContextMenuPinOption) {
   LoadTestExtension("extensions/simple_with_popup");
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   ExtensionsToolbarContainer* const extensions_container =
       GetExtensionsToolbarContainer();
@@ -387,13 +379,7 @@
   GURL url = embedded_test_server()->GetURL("example.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  // Verify site access button is visible, and trigger it to open site access
-  // tab in the extension menu so we can test the UI when permissions change.
-  auto* site_access_button = GetExtensionsToolbarContainer()
-                                 ->GetExtensionsToolbarControls()
-                                 ->site_access_button_for_testing();
-  EXPECT_TRUE(site_access_button);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Extension with <all_urls> permission has site access by default (except for
   // forbidden websites such as chrome:-scheme), and it should be in the has
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
index 69fe86ed..8de67ec 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
@@ -115,11 +115,6 @@
         ->GetExtensionsToolbarControls()
         ->extensions_button();
   }
-  ExtensionsToolbarButton* site_access_button() {
-    return extensions_container()
-        ->GetExtensionsToolbarControls()
-        ->site_access_button_for_testing();
-  }
   ExtensionsTabbedMenuCoordinator* extensions_coordinator() {
     // If we create our own ExtensionsTabbedMenuCoordinator in the test, use
     // that one. Otherwise use the ExtensionsTabbedMenuCoordinator created by
@@ -166,12 +161,10 @@
   // tab.
   bool IsSiteSettingsButtonDisplayed();
 
-  // Opens the tabbed menu in the installed tab.
-  void ShowInstalledTabInMenu();
-  // Opens the tabbed menu in the site access tab.
-  void ShowSiteAccessTabInMenu();
+  // Opens the menu. Tab opened is not important, since both are populated at
+  // construction.
+  void ShowMenu();
 
-  void ClickSiteAccessButton();
   void ClickExtensionsButton();
 
   void ClickPrimaryActionButton(InstalledExtensionMenuItemView* item);
@@ -251,25 +244,11 @@
       ->GetVisible();
 }
 
-void ExtensionsTabbedMenuViewUnitTest::ShowInstalledTabInMenu() {
+void ExtensionsTabbedMenuViewUnitTest::ShowMenu() {
   test_extensions_coordinator_ =
       std::make_unique<ExtensionsTabbedMenuCoordinator>(
           browser(), extensions_container(), true);
-  test_extensions_coordinator_->Show(
-      extensions_button(), ExtensionsToolbarButton::ButtonType::kExtensions);
-}
-
-void ExtensionsTabbedMenuViewUnitTest::ShowSiteAccessTabInMenu() {
-  test_extensions_coordinator_ =
-      std::make_unique<ExtensionsTabbedMenuCoordinator>(
-          browser(), extensions_container(), true);
-  test_extensions_coordinator_->Show(
-      site_access_button(), ExtensionsToolbarButton::ButtonType::kSiteAccess);
-}
-
-void ExtensionsTabbedMenuViewUnitTest::ClickSiteAccessButton() {
-  ClickButton(site_access_button());
-  LayoutContainerIfNecessary();
+  test_extensions_coordinator_->Show(extensions_button());
 }
 
 void ExtensionsTabbedMenuViewUnitTest::ClickExtensionsButton() {
@@ -333,7 +312,6 @@
   const GURL url("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url);
   WaitForAnimation();
-  EXPECT_TRUE(site_access_button()->GetVisible());
   EXPECT_FALSE(extensions_coordinator()->IsShowing());
 
   // Click on the extensions button when the menu is closed. Extensions menu
@@ -346,59 +324,11 @@
   // should be closed.
   ClickExtensionsButton();
   EXPECT_FALSE(extensions_coordinator()->IsShowing());
-
-  // Click on the site access button when the menu is closed. Extensions menu
-  // should open in the site access tab.
-  ClickSiteAccessButton();
-  EXPECT_TRUE(extensions_coordinator()->IsShowing());
-  EXPECT_EQ(extensions_tabbed_menu()->GetSelectedTabIndex(), 0u);
-
-  // Click on the site access button when the menu is open. Extensions menu
-  // should close.
-  ClickSiteAccessButton();
-  EXPECT_FALSE(extensions_coordinator()->IsShowing());
-}
-
-TEST_F(ExtensionsTabbedMenuViewUnitTest, TogglingButtonsClosesMenu) {
-  // Load an extension with all urls permissions so the site access button is
-  // visible.
-  InstallExtensionWithHostPermissions("all_urls", {"<all_urls>"});
-
-  // Navigate to an url where the extension should have access to.
-  const GURL url("http://www.a.com");
-  web_contents_tester()->NavigateAndCommit(url);
-  WaitForAnimation();
-  EXPECT_TRUE(site_access_button()->GetVisible());
-  EXPECT_FALSE(extensions_coordinator()->IsShowing());
-
-  // Click on the extensions button when the menu is closed. Extensions menu
-  // should open.
-  ClickExtensionsButton();
-  EXPECT_TRUE(extensions_coordinator()->IsShowing());
-
-  // Click on the site access button when the menu is open. Extensions menu
-  // should close since the button click is treated as a click outside the menu,
-  // and therefore closing the menu, instead of triggering the button's click
-  // action.
-  // TODO(crbug.com/1263311): Toggle to the corresponding tab when clicking on
-  // the other control when the menu is open.
-  ClickSiteAccessButton();
-  EXPECT_FALSE(extensions_coordinator()->IsShowing());
-
-  // Click on the site access button when the menu is closed. Extensions menu
-  // should open.
-  ClickSiteAccessButton();
-  EXPECT_TRUE(extensions_coordinator()->IsShowing());
-
-  // Click on the extensions button when the menu is open. Extensions menu
-  // should close, as explained previously.
-  ClickExtensionsButton();
-  EXPECT_FALSE(extensions_coordinator()->IsShowing());
 }
 
 TEST_F(ExtensionsTabbedMenuViewUnitTest,
        InstalledTab_InstalledExtensionsAreShownInInstalledTab) {
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   // To start, there should be no extensions in the menu.
   EXPECT_EQ(installed_items().size(), 0u);
@@ -425,7 +355,7 @@
   constexpr char kExtensionCName[] = "C Extension";
   InstallExtension(kExtensionCName);
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   std::vector<InstalledExtensionMenuItemView*> items = installed_items();
   ASSERT_EQ(items.size(), 4u);
@@ -441,7 +371,7 @@
   constexpr char kName[] = "Test Name";
   InstallExtension(kName);
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   ASSERT_TRUE(installed_item);
@@ -470,7 +400,7 @@
   constexpr char kExtensionC[] = "C Extension";
   InstallExtension(kExtensionC);
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   std::vector<InstalledExtensionMenuItemView*> items = installed_items();
 
@@ -529,7 +459,7 @@
        InstalledTab_PinnedExtensionAppearsInAnotherWindow) {
   InstallExtension("Test Name");
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   AdditionalBrowser browser2(
       CreateBrowser(browser()->profile(), browser()->type(),
@@ -559,7 +489,7 @@
   InstallExtension(kExtensionA);
   InstallExtension(kExtensionC);
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   // Verify the order of the extensions is A,C.
   {
@@ -602,7 +532,7 @@
   constexpr char kName[] = "Test Extension";
   auto extension_id = InstallExtension(kName)->id();
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   InstalledExtensionMenuItemView* menu_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
@@ -638,7 +568,7 @@
   scoped_refptr<const extensions::Extension> extension =
       loader.LoadExtension(extension_directory.UnpackedPath());
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
@@ -676,7 +606,7 @@
   scoped_refptr<const extensions::Extension> extension =
       loader.LoadExtension(extension_directory.UnpackedPath());
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
@@ -709,7 +639,7 @@
        InstalledTab_DiscoverMoreButtonOpenWebstorePage) {
   InstallExtension("Test Extension");
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
   EXPECT_TRUE(extensions_coordinator()->IsShowing());
 
   ClickButton(extensions_tabbed_menu()->GetDiscoverMoreButtonForTesting());
@@ -726,7 +656,7 @@
 
   const GURL url("http://www.url.com");
   web_contents_tester()->NavigateAndCommit(url);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   auto no_extensions_have_access_text = l10n_util::GetStringFUTF16(
       IDS_EXTENSIONS_MENU_SITE_ACCESS_TAB_NO_EXTENSIONS_HAVE_ACCESS_TEXT,
@@ -747,7 +677,7 @@
 
   std::u16string restricted_url_text(u"chrome://extensions");
   web_contents_tester()->NavigateAndCommit(GURL(restricted_url_text));
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   auto restricted_site_text = l10n_util::GetStringFUTF16(
       IDS_EXTENSIONS_MENU_SITE_ACCESS_TAB_RESTRICTED_SITE_TEXT,
@@ -771,7 +701,7 @@
 
   const GURL url_a("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url_a);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Site access message should not be displayed since there is at least one
   // extension with host permissions.
@@ -803,7 +733,7 @@
 
   const GURL url_a("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url_a);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Verify extension is in the "has access" section with "on all sites" access.
   ASSERT_EQ(has_access_items().size(), 1u);
@@ -847,7 +777,7 @@
 
   const GURL url_a("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url_a);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   extensions::ExtensionContextMenuModel menu(
       extension.get(), browser(), extensions::ExtensionContextMenuModel::PINNED,
@@ -909,7 +839,7 @@
 
   const GURL url_a("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url_a);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Change extension's site access to run "on click" using the combobox. By
   // default, extension has site access.
@@ -949,7 +879,7 @@
 
   const GURL url_a("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url_a);
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Verify the order of the extensions is A,C under the has access section.
   // Note that extensions installed with all urls permissions have access by
@@ -998,7 +928,7 @@
 
   InstallExtensionWithHostPermissions(
       kExtension, {url_a.spec(), url_b.spec(), url_c.spec()});
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Navigate to a url where the extension does not want access.
   const GURL url_no_access("http://www.noaccess.com");
@@ -1076,7 +1006,7 @@
   const GURL url("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url);
   WaitForAnimation();
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Verify the site settings are hidden by default
   auto* site_settings = extensions_tabbed_menu()->GetSiteSettingsForTesting();
@@ -1110,7 +1040,7 @@
       /*new_access=*/extensions::SitePermissionsHelper::SiteAccess::kOnClick);
   waiter.WaitForExtensionPermissionsUpdate();
   WaitForAnimation();
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
 
   // Verify site has "customize by extensions" site setting by default, and
   // items with dropdowns are displayed in both site access sections.
@@ -1186,7 +1116,7 @@
   const GURL url("http://www.url.com");
   web_contents_tester()->NavigateAndCommit(url);
 
-  ShowSiteAccessTabInMenu();
+  ShowMenu();
   ASSERT_EQ(
       GetUserSiteSetting(url),
       extensions::PermissionsManager::UserSiteSetting::kCustomizeByExtension);
@@ -1216,7 +1146,7 @@
 TEST_F(ExtensionsTabbedMenuViewUnitTest, WindowTitle) {
   InstallExtension("Test Extension");
 
-  ShowInstalledTabInMenu();
+  ShowMenu();
 
   ExtensionsTabbedMenuView* menu = extensions_tabbed_menu();
   EXPECT_FALSE(menu->GetWindowTitle().empty());
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
index 2ed9814d9..2aa6aaf 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
@@ -7,53 +7,32 @@
 #include "base/feature_list.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/extensions/extensions_menu_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h"
 #include "chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/vector_icons/vector_icons.h"
-#include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension_features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/pointer/touch_ui_controller.h"
-#include "ui/base/theme_provider.h"
-#include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/controls/button/button_controller.h"
 
 namespace {
 
-const gfx::VectorIcon& GetIcon(
-    ExtensionsToolbarButton::ButtonType button_type) {
-  return button_type == ExtensionsToolbarButton::ButtonType::kExtensions
-             ? vector_icons::kExtensionIcon
-             : kEyeIcon;
-}
-
-const std::u16string GetIconTooltip(
-    ExtensionsToolbarButton::ButtonType button_type) {
-  return l10n_util::GetStringUTF16(
-      button_type == ExtensionsToolbarButton::ButtonType::kExtensions
-          ? IDS_TOOLTIP_EXTENSIONS_BUTTON
-          : IDS_TOOLTIP_EXTENSIONS_SITE_ACCESS_BUTTON);
-}
+const gfx::VectorIcon& kExtensionIcon = vector_icons::kExtensionIcon;
 
 }  // namespace
 
 ExtensionsToolbarButton::ExtensionsToolbarButton(
     Browser* browser,
     ExtensionsToolbarContainer* extensions_container,
-    ButtonType button_type,
     ExtensionsTabbedMenuCoordinator* extensions_tabbed_menu_coordinator)
     : ToolbarButton(PressedCallback()),
       browser_(browser),
-      button_type_(button_type),
       extensions_container_(extensions_container),
       extensions_tabbed_menu_coordinator_(extensions_tabbed_menu_coordinator) {
   std::unique_ptr<views::MenuButtonController> menu_button_controller =
@@ -68,14 +47,8 @@
   button_controller()->set_notify_action(
       views::ButtonController::NotifyAction::kOnPress);
 
-  SetTooltipText(GetIconTooltip(button_type_));
-  SetVectorIcon(GetIcon(button_type_));
-
-  if (button_type == ButtonType::kExtensions) {
-    // Do not flip the Extensions icon in RTL.
-    SetFlipCanvasOnPaintForRTLUI(false);
-    SetID(VIEW_ID_EXTENSIONS_MENU_BUTTON);
-  }
+  SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_EXTENSIONS_BUTTON));
+  SetVectorIcon(kExtensionIcon);
 
   GetViewAccessibility().OverrideHasPopup(ax::mojom::HasPopup::kMenu);
 }
@@ -126,8 +99,8 @@
     // and ToolbarButton can pick up icon sizes outside of a static lookup.
     SetImageModel(views::Button::STATE_NORMAL,
                   ui::ImageModel::FromVectorIcon(
-                      GetIcon(button_type_),
-                      extensions_container_->GetIconColor(), GetIconSize()));
+                      kExtensionIcon, extensions_container_->GetIconColor(),
+                      GetIconSize()));
     return;
   }
 
@@ -156,7 +129,7 @@
   views::Widget* menu;
   if (base::FeatureList::IsEnabled(
           extensions_features::kExtensionsMenuAccessControl)) {
-    extensions_tabbed_menu_coordinator_->Show(this, button_type_);
+    extensions_tabbed_menu_coordinator_->Show(this);
     menu = extensions_tabbed_menu_coordinator_->GetExtensionsTabbedMenuView()
                ->GetWidget();
   } else {
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
index e343c888..ce2a1e4 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
@@ -24,18 +24,8 @@
  public:
   METADATA_HEADER(ExtensionsToolbarButton);
 
-  enum class ButtonType {
-    // Indicates that at least one extension is enabled, and opens the installed
-    // extensions tab in the menu.
-    kExtensions,
-    // Indicates that at least one extension has access to the current page, and
-    // opens the permissions tab in the menu.
-    kSiteAccess
-  };
-
   ExtensionsToolbarButton(Browser* browser,
                           ExtensionsToolbarContainer* extensions_container,
-                          ButtonType button_type,
                           ExtensionsTabbedMenuCoordinator* coordinator);
   ExtensionsToolbarButton(const ExtensionsToolbarButton&) = delete;
   ExtensionsToolbarButton& operator=(const ExtensionsToolbarButton&) = delete;
@@ -63,7 +53,6 @@
   std::unique_ptr<views::MenuButtonController::PressedLock> pressed_lock_;
 
   const raw_ptr<Browser> browser_;
-  const ButtonType button_type_;
   raw_ptr<views::MenuButtonController> menu_button_controller_;
   const raw_ptr<ExtensionsToolbarContainer> extensions_container_;
   // This can be nullptr before ExtensionsTabbedMenu is fully rolled out.
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
index fd78b66..1f48a59 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -28,9 +28,9 @@
 #include "chrome/browser/ui/views/extensions/extensions_tabbed_menu_coordinator.h"
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_button.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h"
-#include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h"
 #include "extensions/common/extension_features.h"
 #include "ui/base/dragdrop/drag_drop_types.h"
 #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
@@ -102,15 +102,13 @@
                     this,
                     CanShowIconInToolbar())
               : nullptr),
-      extensions_button_(
-          base::FeatureList::IsEnabled(
-              extensions_features::kExtensionsMenuAccessControl)
-              ? nullptr
-              : new ExtensionsToolbarButton(
-                    browser,
-                    this,
-                    ExtensionsToolbarButton::ButtonType::kExtensions,
-                    extensions_tabbed_menu_coordinator_.get())),
+      extensions_button_(base::FeatureList::IsEnabled(
+                             extensions_features::kExtensionsMenuAccessControl)
+                             ? nullptr
+                             : new ExtensionsToolbarButton(
+                                   browser,
+                                   this,
+                                   extensions_tabbed_menu_coordinator_.get())),
       extensions_controls_(
           base::FeatureList::IsEnabled(
               extensions_features::kExtensionsMenuAccessControl)
@@ -118,12 +116,6 @@
                     std::make_unique<ExtensionsToolbarButton>(
                         browser,
                         this,
-                        ExtensionsToolbarButton::ButtonType::kExtensions,
-                        extensions_tabbed_menu_coordinator_.get()),
-                    std::make_unique<ExtensionsToolbarButton>(
-                        browser,
-                        this,
-                        ExtensionsToolbarButton::ButtonType::kSiteAccess,
                         extensions_tabbed_menu_coordinator_.get()),
                     std::make_unique<ExtensionsRequestAccessButton>(browser_))
               : nullptr),
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
index c8ede99..905c6dd 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
@@ -17,13 +17,10 @@
 
 ExtensionsToolbarControls::ExtensionsToolbarControls(
     std::unique_ptr<ExtensionsToolbarButton> extensions_button,
-    std::unique_ptr<ExtensionsToolbarButton> site_access_button,
     std::unique_ptr<ExtensionsRequestAccessButton> request_access_button)
     : ToolbarIconContainerView(/*uses_highlight=*/true),
       request_access_button_(AddChildView(std::move(request_access_button))),
-      site_access_button_(AddChildView(std::move(site_access_button))),
       extensions_button_(extensions_button.get()) {
-  site_access_button_->SetVisible(false);
   request_access_button_->SetVisible(false);
   // TODO(emiliapaz): Consider changing AddMainItem() to receive a unique_ptr.
   AddMainItem(extensions_button.release());
@@ -37,14 +34,12 @@
     const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
     extensions::PermissionsManager::UserSiteSetting site_setting,
     content::WebContents* current_web_contents) {
-  UpdateSiteAccessButton(actions, current_web_contents);
   UpdateRequestAccessButton(actions, site_setting, current_web_contents);
 
   // Display background only when multiple buttons are visible. Since
-  // the extensions button is always visible, check if any of the other
-  // buttons is too.
-  SetBackground(site_access_button_->GetVisible() ||
-                        request_access_button_->GetVisible()
+  // the extensions button is always visible, check if the request access
+  // button is too.
+  SetBackground(request_access_button_->GetVisible()
                     ? views::CreateThemedRoundedRectBackground(
                           kColorExtensionsToolbarControlsBackground,
                           extensions_button_->GetPreferredSize().height())
@@ -55,14 +50,6 @@
   GetAnimatingLayoutManager()->ResetLayout();
 }
 
-void ExtensionsToolbarControls::UpdateSiteAccessButton(
-    const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
-    content::WebContents* web_contents) {
-  site_access_button_->SetVisible(
-      ExtensionActionViewController::AnyActionHasCurrentSiteAccess(
-          actions, web_contents));
-}
-
 void ExtensionsToolbarControls::UpdateRequestAccessButton(
     const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
     extensions::PermissionsManager::UserSiteSetting site_setting,
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
index 6429d0a..923331c 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
@@ -25,7 +25,6 @@
 
   explicit ExtensionsToolbarControls(
       std::unique_ptr<ExtensionsToolbarButton> extensions_button,
-      std::unique_ptr<ExtensionsToolbarButton> site_access_button,
       std::unique_ptr<ExtensionsRequestAccessButton> request_button);
   ExtensionsToolbarControls(const ExtensionsToolbarControls&) = delete;
   ExtensionsToolbarControls operator=(const ExtensionsToolbarControls&) =
@@ -37,9 +36,6 @@
   }
 
   // Methods for testing.
-  ExtensionsToolbarButton* site_access_button_for_testing() const {
-    return site_access_button_;
-  }
   ExtensionsRequestAccessButton* request_access_button_for_testing() const {
     return request_access_button_;
   }
@@ -55,11 +51,6 @@
   void UpdateAllIcons() override;
 
  private:
-  // Updates `site_access_button_` visibility given `actions` in `web_contents`.
-  void UpdateSiteAccessButton(
-      const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
-      content::WebContents* web_contents);
-
   // Updates `request_access_button_` visibility given the user `site_setting`
   // and `actions` in `web_contents`.
   void UpdateRequestAccessButton(
@@ -68,7 +59,6 @@
       content::WebContents* web_contents);
 
   const raw_ptr<ExtensionsRequestAccessButton> request_access_button_;
-  const raw_ptr<ExtensionsToolbarButton> site_access_button_;
   const raw_ptr<ExtensionsToolbarButton> extensions_button_;
 };
 
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
index e84b189..d04f4e1 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
@@ -33,14 +33,10 @@
       const ExtensionsToolbarControlsUnitTest&) = delete;
 
   ExtensionsRequestAccessButton* request_access_button();
-  ExtensionsToolbarButton* site_access_button();
 
   // Returns whether the request access button is visible or not.
   bool IsRequestAccessButtonVisible();
 
-  // Returns whether the site access button is visible or not.
-  bool IsSiteAccessButtonVisible();
-
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 };
@@ -57,120 +53,10 @@
       ->request_access_button_for_testing();
 }
 
-ExtensionsToolbarButton*
-ExtensionsToolbarControlsUnitTest::site_access_button() {
-  return extensions_container()
-      ->GetExtensionsToolbarControls()
-      ->site_access_button_for_testing();
-}
-
 bool ExtensionsToolbarControlsUnitTest::IsRequestAccessButtonVisible() {
   return request_access_button()->GetVisible();
 }
 
-bool ExtensionsToolbarControlsUnitTest::IsSiteAccessButtonVisible() {
-  return site_access_button()->GetVisible();
-}
-
-TEST_F(ExtensionsToolbarControlsUnitTest,
-       SiteAccessButtonVisibility_NavigationBetweenPages) {
-  content::WebContentsTester* web_contents_tester =
-      AddWebContentsAndGetTester();
-  const GURL url_a("http://www.a.com");
-  const GURL url_b("http://www.b.com");
-
-  // Add an extension that only requests access to a specific url.
-  InstallExtensionWithHostPermissions("specific_url", {url_a.spec()});
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Navigate to an url the extension should have access to.
-  web_contents_tester->NavigateAndCommit(url_a);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-
-  // Navigate to an url the extension should not have access to.
-  web_contents_tester->NavigateAndCommit(url_b);
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-}
-
-TEST_F(ExtensionsToolbarControlsUnitTest,
-       SiteAccessButtonVisibility_ContextMenuChangesHostPermissions) {
-  content::WebContentsTester* web_contents_tester =
-      AddWebContentsAndGetTester();
-  const GURL url_a("http://www.a.com");
-  const GURL url_b("http://www.b.com");
-
-  // Add an extension with all urls host permissions. Since we haven't navigated
-  // to an url yet, the extension should not have access.
-  auto extension =
-      InstallExtensionWithHostPermissions("all_urls", {"<all_urls>"});
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Navigate to an url the extension should have access to as part of
-  // <all_urls>.
-  web_contents_tester->NavigateAndCommit(url_a);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-
-  // Change the extension to run only on the current site using the context
-  // menu. The extension should still have access to the current site.
-  extensions::ExtensionContextMenuModel context_menu(
-      extension.get(), browser(), extensions::ExtensionContextMenuModel::PINNED,
-      nullptr, true,
-      extensions::ExtensionContextMenuModel::ContextMenuSource::kToolbarAction);
-  context_menu.ExecuteCommand(
-      extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE, 0);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-
-  // Navigate to a different url. The extension should not have access.
-  web_contents_tester->NavigateAndCommit(url_b);
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Go back to the original url. The extension should have access.
-  web_contents_tester->NavigateAndCommit(url_a);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-}
-
-TEST_F(ExtensionsToolbarControlsUnitTest,
-       SiteAccessButtonVisibility_MultipleExtensions) {
-  content::WebContentsTester* web_contents_tester =
-      AddWebContentsAndGetTester();
-  const GURL url_a("http://www.a.com");
-  const GURL url_b("http://www.b.com");
-
-  // There are no extensions installed yet, so no extension has access to the
-  // current site.
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Add an extension that doesn't request host permissions. Extension should
-  // not have access to the current site.
-  InstallExtension("no_permissions");
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Add an extension that only requests access to url_a. Extension should not
-  // have access to the current site.
-  InstallExtensionWithHostPermissions("specific_url", {url_a.spec()});
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Add an extension with all urls host permissions. Extension should not have
-  // access because there isn't a real url yet.
-  auto extension_all_urls =
-      InstallExtensionWithHostPermissions("all_urls", {"<all_urls>"});
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-
-  // Navigate to the url that "specific_url" extension has access to. Both
-  // "all_urls" and "specific_urls" should have accessn to the current site.
-  web_contents_tester->NavigateAndCommit(url_a);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-
-  // Navigate to a different url. Only "all_urls" should have access.
-  web_contents_tester->NavigateAndCommit(url_b);
-  EXPECT_TRUE(IsSiteAccessButtonVisible());
-
-  // Remove the only extension that has access to the current site.
-  UninstallExtension(extension_all_urls->id());
-  LayoutContainerIfNecessary();
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
-}
-
 TEST_F(ExtensionsToolbarControlsUnitTest,
        RequestAccessButtonVisibility_NavigationBetweenPages) {
   content::WebContentsTester* web_contents_tester =
@@ -299,7 +185,7 @@
   // Remove the only extension that requests access to the current site.
   UninstallExtension(extension_all_urls->id());
   LayoutContainerIfNecessary();
-  EXPECT_FALSE(IsSiteAccessButtonVisible());
+  EXPECT_FALSE(IsRequestAccessButtonVisible());
 }
 
 // Tests that extensions with activeTab and requested url with withheld access
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index c923ca1..ada3734 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -46,8 +46,8 @@
 #include "ui/views/window/client_view.h"
 
 using views::View;
-using web_modal::WebContentsModalDialogHost;
 using web_modal::ModalDialogHostObserver;
+using web_modal::WebContentsModalDialogHost;
 
 namespace {
 
@@ -81,8 +81,7 @@
  public:
   explicit WebContentsModalDialogHostViews(
       BrowserViewLayout* browser_view_layout)
-          : browser_view_layout_(browser_view_layout) {
-  }
+      : browser_view_layout_(browser_view_layout) {}
 
   WebContentsModalDialogHostViews(const WebContentsModalDialogHostViews&) =
       delete;
@@ -180,8 +179,7 @@
 
 BrowserViewLayout::~BrowserViewLayout() = default;
 
-WebContentsModalDialogHost*
-    BrowserViewLayout::GetWebContentsModalDialogHost() {
+WebContentsModalDialogHost* BrowserViewLayout::GetWebContentsModalDialogHost() {
   return dialog_host_.get();
 }
 
@@ -257,8 +255,8 @@
   views::View* parent = browser_view_->parent();
 
   gfx::Point point_in_browser_view_coords(point);
-  views::View::ConvertPointToTarget(
-      parent, browser_view_, &point_in_browser_view_coords);
+  views::View::ConvertPointToTarget(parent, browser_view_,
+                                    &point_in_browser_view_coords);
 
   // Let the frame handle any events that fall within the bounds of the window
   // controls overlay.
@@ -559,8 +557,7 @@
   TRACE_EVENT0("ui", "BrowserViewLayout::LayoutContentsContainerView");
   // |contents_container_| contains web page contents and devtools.
   // See browser_view.h for details.
-  gfx::Rect contents_container_bounds(vertical_layout_rect_.x(),
-                                      top,
+  gfx::Rect contents_container_bounds(vertical_layout_rect_.x(), top,
                                       vertical_layout_rect_.width(),
                                       std::max(0, bottom - top));
   if (webui_tab_strip_ && webui_tab_strip_->GetVisible()) {
@@ -737,7 +734,14 @@
   }
 
   gfx::Point contents_top_left;
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   views::View::ConvertPointToScreen(contents_container_, &contents_top_left);
+#else
+  // On Ash placing the border widget on top of the contents container
+  // does not require an offset -- see crbug.com/1030925.
+  contents_top_left =
+      gfx::Point(contents_container_->x(), contents_container_->y());
+#endif
 
   gfx::Rect rect;
   if (dynamic_content_border_bounds_) {
diff --git a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
index 28493ea..a0713248 100644
--- a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
@@ -121,6 +121,7 @@
           .CopyAddressTo(&window_title_)
           .SetText(location_bar_model_->GetURLForDisplay())
           .SetHorizontalAlignment(gfx::ALIGN_LEFT)
+          .SetElideBehavior(gfx::ELIDE_HEAD)
           .Build());
   controls_container_view_->SetFlexForView(window_title_, 1);
 
diff --git a/chrome/browser/ui/views/permissions/chip_controller.cc b/chrome/browser/ui/views/permissions/chip_controller.cc
index 543b769..5d027582 100644
--- a/chrome/browser/ui/views/permissions/chip_controller.cc
+++ b/chrome/browser/ui/views/permissions/chip_controller.cc
@@ -387,7 +387,7 @@
       chip_->SetVisible(true);
       chip_->AnimateExpand(kExpandDuration);
     }
-    chip_->RequestFocus();
+
     chip_->SetCallback(base::BindRepeating(&ChipController::ShowPageInfoDialog,
                                            base::Unretained(this)));
     collapse_timer_.Start(FROM_HERE, kConfirmationDisplayDuration, this,
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
index 9fe89c1..d474fd08 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
@@ -77,8 +77,8 @@
   return model_->GetColorsModel();
 }
 
-void ReadAnythingController::SetIconColorIds(ui::ColorId color_id) {
-  return model_->SetIconColorIds(color_id);
+ui::ColorId ReadAnythingController::GetForegroundColorId() {
+  return model_->GetForegroundColorId();
 }
 
 void ReadAnythingController::OnLineSpacingChanged(int new_index) {
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
index ee4ad09a..0fd1ca0 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
@@ -60,7 +60,7 @@
   void OnFontSizeChanged(bool increase) override;
   void OnColorsChanged(int new_index) override;
   ui::ComboboxModel* GetColorsModel() override;
-  void SetIconColorIds(ui::ColorId color_id) override;
+  ui::ColorId GetForegroundColorId() override;
   void OnLineSpacingChanged(int new_index) override;
   ui::ComboboxModel* GetLineSpacingModel() override;
   void OnLetterSpacingChanged(int new_index) override;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
index 5b184ff..afa29b86 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_constants.h"
 #include "chrome/grit/component_extension_resources.h"
 #include "chrome/grit/generated_resources.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/image_model.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -23,6 +24,7 @@
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/paint_vector_icon.h"
 
+using read_anything::mojom::ReadAnythingTheme;
 using read_anything::mojom::Spacing;
 
 ReadAnythingModel::ReadAnythingModel()
@@ -67,8 +69,8 @@
 
   colors_combobox_index_ = colors_model_->GetStartingStateIndex();
   auto& initial_colors = colors_model_->GetColorsAt(colors_combobox_index_);
-  foreground_color_id_ = initial_colors.foreground_color_id;
-  background_color_id_ = initial_colors.background_color_id;
+  foreground_color_ = initial_colors.foreground;
+  background_color_ = initial_colors.background;
   SetIconColorIds(initial_colors.foreground_color_id);
 
   line_spacing = line_spacing_model_->GetLineSpacingAt(
@@ -101,8 +103,9 @@
 
   colors_combobox_index_ = new_index;
   auto& new_colors = colors_model_->GetColorsAt(new_index);
-  foreground_color_id_ = new_colors.foreground_color_id;
-  background_color_id_ = new_colors.background_color_id;
+  foreground_color_ = new_colors.foreground;
+  background_color_ = new_colors.background;
+  SetIconColorIds(new_colors.foreground_color_id);
 
   NotifyThemeChanged();
 }
@@ -113,6 +116,13 @@
   letter_spacing_model_->SetIconColorId(color_id);
 }
 
+ui::ColorId ReadAnythingModel::GetForegroundColorId() {
+  // Check that the index is valid.
+  DCHECK(colors_model_->IsValidColorsIndex(colors_combobox_index_));
+
+  return colors_model_->GetForegroundColorId(colors_combobox_index_);
+}
+
 void ReadAnythingModel::SetSelectedLineSpacingByIndex(size_t new_index) {
   // Check that the index is valid.
   DCHECK(line_spacing_model_->IsValidLineSpacingIndex(new_index));
@@ -173,9 +183,9 @@
 
 void ReadAnythingModel::NotifyThemeChanged() {
   for (Observer& obs : observers_) {
-    obs.OnReadAnythingThemeChanged(font_name_, font_scale_,
-                                   foreground_color_id_, background_color_id_,
-                                   line_spacing_, letter_spacing_);
+    obs.OnReadAnythingThemeChanged(ReadAnythingTheme::New(
+        font_name_, font_scale_, foreground_color_, background_color_,
+        line_spacing_, letter_spacing_));
   }
 }
 
@@ -253,21 +263,22 @@
 
 ReadAnythingColorsModel::ReadAnythingColorsModel() {
   // Define the possible sets of colors available to the user.
+  // TODO (crbug.com/1266555): Define default colors from system theme.
   ColorInfo kDefaultColors = {u"Default", IDS_READ_ANYTHING_DEFAULT_PNG,
-                              ui::kColorReadAnythingForeground,
-                              ui::kColorReadAnythingBackground};
+                              gfx::kGoogleGrey800, gfx::kGoogleGrey050,
+                              ui::kColorReadAnythingForegroundLight};
 
   ColorInfo kLightColors = {u"Light", IDS_READ_ANYTHING_LIGHT_PNG,
-                            ui::kColorReadAnythingForegroundLight,
-                            ui::kColorReadAnythingBackgroundLight};
+                            gfx::kGoogleGrey800, gfx::kGoogleGrey050,
+                            ui::kColorReadAnythingForegroundLight};
 
   ColorInfo kDarkColors = {u"Dark", IDS_READ_ANYTHING_DARK_PNG,
-                           ui::kColorReadAnythingForegroundDark,
-                           ui::kColorReadAnythingBackgroundDark};
+                           gfx::kGoogleGrey200, gfx::kGoogleGrey900,
+                           ui::kColorReadAnythingForegroundDark};
 
   ColorInfo kYellowColors = {u"Yellow", IDS_READ_ANYTHING_YELLOW_PNG,
-                             ui::kColorReadAnythingForegroundYellow,
-                             ui::kColorReadAnythingBackgroundYellow};
+                             gfx::kGoogleGrey800, gfx::kGoogleYellow200,
+                             ui::kColorReadAnythingForegroundYellow};
 
   colors_choices_.emplace_back(kDefaultColors);
   colors_choices_.emplace_back(kLightColors);
@@ -288,6 +299,10 @@
   return colors_choices_[index];
 }
 
+ui::ColorId ReadAnythingColorsModel::GetForegroundColorId(size_t index) {
+  return GetColorsAt(index).foreground_color_id;
+}
+
 absl::optional<size_t> ReadAnythingColorsModel::GetDefaultIndex() const {
   return default_index_;
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
index 215f566..4ee4909 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
@@ -12,6 +12,7 @@
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
 #include "chrome/common/accessibility/read_anything.mojom.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/accessibility/ax_node_id_forward.h"
 #include "ui/accessibility/ax_tree_update.h"
 #include "ui/base/models/combobox_model.h"
@@ -76,15 +77,19 @@
     int icon_asset;
 
     // The foreground color, used for text and icon hints.
-    ui::ColorId foreground_color_id;
+    SkColor foreground;
 
     // The background color, used for text background.
-    ui::ColorId background_color_id;
+    SkColor background;
+
+    // The foreground color as a ColorId, used for separators.
+    ui::ColorId foreground_color_id;
   };
 
   bool IsValidColorsIndex(size_t index);
   void SetDefaultColorsIndexFromPref(size_t index);
   ColorInfo& GetColorsAt(size_t index);
+  ui::ColorId GetForegroundColorId(size_t index);
   void SetIconColorId(ui::ColorId color_id);
 
   // Simple pass-through method so Init can set the starting state colors.
@@ -215,12 +220,7 @@
         const ui::AXTreeUpdate& snapshot,
         const std::vector<ui::AXNodeID>& content_node_ids) {}
     virtual void OnReadAnythingThemeChanged(
-        std::string& font_name,
-        double font_scale,
-        ui::ColorId foreground_color_id,
-        ui::ColorId background_color_id,
-        read_anything::mojom::Spacing line_spacing,
-        read_anything::mojom::Spacing letter_spacing) = 0;
+        read_anything::mojom::ReadAnythingThemePtr new_theme) = 0;
   };
 
   ReadAnythingModel();
@@ -244,7 +244,6 @@
   double GetValidFontScale(double font_scale);
   void DecreaseTextSize();
   void IncreaseTextSize();
-  void SetIconColorIds(ui::ColorId color_id);
   void SetSelectedColorsByIndex(size_t new_index);
   void SetSelectedLineSpacingByIndex(size_t new_index);
   void SetSelectedLetterSpacingByIndex(size_t new_index);
@@ -252,6 +251,7 @@
   ReadAnythingFontModel* GetFontModel() { return font_model_.get(); }
   double GetFontScale() { return font_scale_; }
   ReadAnythingColorsModel* GetColorsModel() { return colors_model_.get(); }
+  ui::ColorId GetForegroundColorId();
   ReadAnythingLineSpacingModel* GetLineSpacingModel() {
     return line_spacing_model_.get();
   }
@@ -262,13 +262,14 @@
  private:
   void NotifyAXTreeDistilled();
   void NotifyThemeChanged();
+  void SetIconColorIds(ui::ColorId color_id);
 
   // State:
 
   // Members of read_anything::mojom::ReadAnythingTheme:
   std::string font_name_;
-  ui::ColorId foreground_color_id_;
-  ui::ColorId background_color_id_;
+  SkColor foreground_color_;
+  SkColor background_color_;
 
   // A scale multiplier for font size (internal use only, not shown to user).
   float font_scale_;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
index 2604935..d86a793 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
@@ -14,6 +14,7 @@
 
 #include "ui/accessibility/accessibility_features.h"
 
+using read_anything::mojom::ReadAnythingThemePtr;
 using testing::_;
 using testing::FloatNear;
 
@@ -26,12 +27,7 @@
               (override));
   MOCK_METHOD(void,
               OnReadAnythingThemeChanged,
-              (std::string & font_name,
-               double font_scale,
-               ui::ColorId foreground_color_id,
-               ui::ColorId background_color_id,
-               read_anything::mojom::Spacing line_spacing,
-               read_anything::mojom::Spacing letter_spacing),
+              (ReadAnythingThemePtr new_theme),
               (override));
 };
 
@@ -67,12 +63,10 @@
   model_->AddObserver(&model_observer_1_);
 
   EXPECT_CALL(model_observer_1_, OnAXTreeDistilled(_, _)).Times(0);
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   EXPECT_CALL(model_observer_2_, OnAXTreeDistilled(_, _)).Times(0);
-  EXPECT_CALL(model_observer_2_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_2_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->AddObserver(&model_observer_2_);
 }
@@ -82,16 +76,13 @@
   model_->AddObserver(&model_observer_2_);
 
   EXPECT_CALL(model_observer_1_, OnAXTreeDistilled(_, _)).Times(0);
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   EXPECT_CALL(model_observer_2_, OnAXTreeDistilled(_, _)).Times(0);
-  EXPECT_CALL(model_observer_2_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(0);
+  EXPECT_CALL(model_observer_2_, OnReadAnythingThemeChanged(_)).Times(0);
 
   EXPECT_CALL(model_observer_3_, OnAXTreeDistilled(_, _)).Times(0);
-  EXPECT_CALL(model_observer_3_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_3_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->RemoveObserver(&model_observer_2_);
   model_->AddObserver(&model_observer_3_);
@@ -100,8 +91,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedFontIndex) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->SetSelectedFontByIndex(2);
 }
@@ -120,8 +110,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnDecreasedFontSize) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->DecreaseTextSize();
 
@@ -131,8 +120,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnIncreasedFontSize) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->IncreaseTextSize();
 
@@ -142,8 +130,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedColorsIndex) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->SetSelectedColorsByIndex(2);
 }
@@ -151,8 +138,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLineSpacingIndex) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->SetSelectedLineSpacingByIndex(2);
 }
@@ -160,8 +146,7 @@
 TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLetterSpacingIndex) {
   model_->AddObserver(&model_observer_1_);
 
-  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_, _, _, _, _, _))
-      .Times(1);
+  EXPECT_CALL(model_observer_1_, OnReadAnythingThemeChanged(_)).Times(1);
 
   model_->SetSelectedLetterSpacingByIndex(2);
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
index 18d51f3..15c20710 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
@@ -115,12 +115,6 @@
   coordinator_->AddModelObserver(this);
 }
 
-// After this view is added to the widget, we have access to the color provider
-// to apply the initial theme skcolors.
-void ReadAnythingToolbarView::AddedToWidget() {
-  ChangeColorsCallback();
-}
-
 void ReadAnythingToolbarView::DecreaseFontSizeCallback() {
   if (delegate_)
     delegate_->OnFontSizeChanged(/* increase = */ false);
@@ -157,41 +151,26 @@
 }
 
 void ReadAnythingToolbarView::OnReadAnythingThemeChanged(
-    std::string& font_name,
-    double font_scale,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    read_anything::mojom::Spacing line_spacing,
-    read_anything::mojom::Spacing letter_spacing) {
-  if (!GetColorProvider())
-    return;
-
-  const SkColor background_skcolor =
-      GetColorProvider()->GetColor(background_color_id);
-  const SkColor foreground_skcolor =
-      GetColorProvider()->GetColor(foreground_color_id);
-
-  SetBackground(views::CreateSolidBackground(background_skcolor));
+    read_anything::mojom::ReadAnythingThemePtr new_theme) {
+  SetBackground(views::CreateSolidBackground(new_theme->background_color));
   font_combobox_->SetBackground(
-      views::CreateSolidBackground(background_skcolor));
+      views::CreateSolidBackground(new_theme->background_color));
   colors_combobox_->SetBackground(
-      views::CreateSolidBackground(background_skcolor));
+      views::CreateSolidBackground(new_theme->background_color));
   lines_combobox_->SetBackground(
-      views::CreateSolidBackground(background_skcolor));
+      views::CreateSolidBackground(new_theme->background_color));
   letter_spacing_combobox_->SetBackground(
-      views::CreateSolidBackground(background_skcolor));
+      views::CreateSolidBackground(new_theme->background_color));
 
   decrease_text_size_button_->UpdateIcon(gfx::CreateVectorIcon(
-      kTextDecreaseIcon, kSmallIconSize, foreground_skcolor));
+      kTextDecreaseIcon, kSmallIconSize, new_theme->foreground_color));
 
   increase_text_size_button_->UpdateIcon(gfx::CreateVectorIcon(
-      kTextIncreaseIcon, kLargeIconSize, foreground_skcolor));
+      kTextIncreaseIcon, kLargeIconSize, new_theme->foreground_color));
 
   for (views::Separator* separator : separators_) {
-    separator->SetColorId(foreground_color_id);
+    separator->SetColorId(delegate_->GetForegroundColorId());
   }
-
-  delegate_->SetIconColorIds(foreground_color_id);
 }
 
 std::unique_ptr<views::View> ReadAnythingToolbarView::Separator() {
@@ -208,6 +187,7 @@
   separator_container->SetLayoutManager(std::move(separator_layout_manager));
 
   auto separator = std::make_unique<views::Separator>();
+  separator->SetColorId(delegate_->GetForegroundColorId());
   separators_.push_back(
       separator_container->AddChildView(std::move(separator)));
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
index da88dce..9d6ec35 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
@@ -32,7 +32,7 @@
     virtual void OnFontSizeChanged(bool increase) = 0;
     virtual void OnColorsChanged(int new_index) = 0;
     virtual ui::ComboboxModel* GetColorsModel() = 0;
-    virtual void SetIconColorIds(ui::ColorId color_id) = 0;
+    virtual ui::ColorId GetForegroundColorId() = 0;
     virtual void OnLineSpacingChanged(int new_index) = 0;
     virtual ui::ComboboxModel* GetLineSpacingModel() = 0;
     virtual void OnLetterSpacingChanged(int new_index) = 0;
@@ -49,12 +49,7 @@
 
   // ReadAnythingModel::Observer:
   void OnReadAnythingThemeChanged(
-      std::string& font_name,
-      double font_scale,
-      ui::ColorId foreground_color_id,
-      ui::ColorId background_color_id,
-      read_anything::mojom::Spacing line_spacing,
-      read_anything::mojom::Spacing letter_spacing) override;
+      read_anything::mojom::ReadAnythingThemePtr new_theme) override;
 
   // ReadAnythingCoordinator::Observer:
   void OnCoordinatorDestroyed() override;
@@ -69,7 +64,6 @@
   void ChangeLetterSpacingCallback();
 
   // views::View:
-  void AddedToWidget() override;
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   std::unique_ptr<views::View> Separator();
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc
index f4cef61..5c9eb759 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc
@@ -21,7 +21,7 @@
   MOCK_METHOD(void, OnFontSizeChanged, (bool increase), (override));
   MOCK_METHOD(void, OnColorsChanged, (int new_index), (override));
   MOCK_METHOD(ui::ComboboxModel*, GetColorsModel, (), (override));
-  MOCK_METHOD(void, SetIconColorIds, (ui::ColorId color_id), (override));
+  MOCK_METHOD(ui::ColorId, GetForegroundColorId, (), (override));
   MOCK_METHOD(void, OnLineSpacingChanged, (int new_index), (override));
   MOCK_METHOD(ui::ComboboxModel*, GetLineSpacingModel, (), (override));
   MOCK_METHOD(void, OnLetterSpacingChanged, (int new_index), (override));
@@ -86,7 +86,10 @@
     toolbar_view_->ChangeLetterSpacingCallback();
   }
 
-  void Separator() { toolbar_view_->Separator(); }
+  void OnReadAnythingThemeChanged(
+      read_anything::mojom::ReadAnythingThemePtr new_theme) {
+    toolbar_view_->OnReadAnythingThemeChanged(std::move(new_theme));
+  }
 
  protected:
   MockReadAnythingToolbarViewDelegate toolbar_delegate_;
@@ -118,6 +121,14 @@
   ChangeColorsCallback();
 }
 
+IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, ChangeSeparatorColor) {
+  // GetForegroundColorId() called for each separator (2 separators total)
+  EXPECT_CALL(toolbar_delegate_, GetForegroundColorId()).Times(2);
+
+  auto theme = read_anything::mojom::ReadAnythingTheme::New();
+  OnReadAnythingThemeChanged(std::move(theme));
+}
+
 IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, ChangeLineSpacingCallback) {
   EXPECT_CALL(toolbar_delegate_, OnLineSpacingChanged(1)).Times(1);
 
diff --git a/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc b/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc
index 1600290c..b4269dc 100644
--- a/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc
+++ b/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc
@@ -5,8 +5,10 @@
 #include "chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.h"
 
 #include "base/containers/contains.h"
+#include "base/feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/color/chrome_color_id.h"
@@ -22,8 +24,6 @@
 constexpr int kMinContentsBorderWidth = 20;
 constexpr int kMinContentsBorderHeight = 20;
 
-// TODO(https://crbug.com/1030925): Fix contents border on ChromeOS.
-#if !BUILDFLAG(IS_CHROMEOS)
 class BorderView : public views::View {
  public:
   BorderView() = default;
@@ -83,7 +83,6 @@
   // After this fix, capturing a given tab X twice will still yield one widget.
   browser_view->set_contents_border_widget(widget);
 }
-#endif  // !BUILDFLAG(IS_CHROMEOS)
 
 }  // namespace
 
@@ -139,10 +138,17 @@
 }
 
 void TabCaptureContentsBorderHelper::Update() {
-// TODO(https://crbug.com/1030925): Fix contents border on ChromeOS.
-#if !BUILDFLAG(IS_CHROMEOS)
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
+#if BUILDFLAG(IS_CHROMEOS)
+  // The blue border behavior used to be problematic on ChromeOS - see
+  // crbug.com/1320262 and crbug.com/1030925. This check serves as a means of
+  // flag-disabling this feature in case of possible future regressions.
+  if (!base::FeatureList::IsEnabled(features::kTabCaptureBlueBorderCrOS)) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
   content::WebContents* const web_contents = &GetWebContents();
 
   Browser* const browser = chrome::FindBrowserWithWebContents(web_contents);
@@ -177,7 +183,6 @@
   } else {
     contents_border_widget->Hide();
   }
-#endif  // !BUILDFLAG(IS_CHROMEOS)
 }
 
 void TabCaptureContentsBorderHelper::UpdateBlueBorderLocation() {
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
index 2a409b5d..e328af6e 100644
--- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
+++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
@@ -8,7 +8,9 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/favicon/favicon_utils.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/ui/browser.h"
@@ -40,7 +42,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.h"
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 namespace {
 
@@ -137,7 +139,7 @@
 const policy::DlpContentRestrictionSet kScreenshareRestrictionSet(
     policy::DlpContentRestriction::kScreenShare,
     policy::DlpRulesManager::Level::kBlock);
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 }  // namespace
 
@@ -146,7 +148,11 @@
       public ::testing::WithParamInterface<bool> {
  public:
   TabSharingUIViewsBrowserTest()
-      : favicons_used_for_switch_to_tab_button_(GetParam()) {}
+      : favicons_used_for_switch_to_tab_button_(GetParam()) {
+#if BUILDFLAG(IS_CHROMEOS)
+    features_.InitAndEnableFeature(features::kTabCaptureBlueBorderCrOS);
+#endif  // BUILDFLAG(IS_CHROMEOS)
+  }
 
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
@@ -196,10 +202,6 @@
     DCHECK((capturing_tab != kNullTabIndex && captured_tab != kNullTabIndex) ||
            (capturing_tab == kNullTabIndex && captured_tab == kNullTabIndex));
 
-#if BUILDFLAG(IS_CHROMEOS)
-    // TODO(https://crbug.com/1030925): Fix contents border on ChromeOS.
-    has_border = false;
-#endif
     views::Widget* contents_border = GetContentsBorder(browser);
     EXPECT_EQ(has_border, contents_border != nullptr);
     auto capture_indicator = GetCaptureIndicator();
@@ -316,7 +318,7 @@
   void ApplyDlpForAllUsers() {
     TabSharingUIViews::ApplyDlpForAllUsersForTesting();
   }
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
  private:
   void OnStartSharing(const content::DesktopMediaID& media_id) {
@@ -327,6 +329,10 @@
         std::vector<content::DesktopMediaID>{});
   }
 
+#if BUILDFLAG(IS_CHROMEOS)
+  base::test::ScopedFeatureList features_;
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
   const bool favicons_used_for_switch_to_tab_button_;
 
   std::unique_ptr<TabSharingUI> tab_sharing_ui_;
@@ -456,8 +462,6 @@
            /*captured_tab=*/kNullTabIndex, /*infobar_count=*/0);
 }
 
-// TODO(https://crbug.com/1030925): Fix contents border on ChromeOS.
-#if !BUILDFLAG(IS_CHROMEOS)
 IN_PROC_BROWSER_TEST_P(TabSharingUIViewsBrowserTest,
                        BorderWidgetShouldCloseWhenBrowserCloses) {
   Browser* new_browser = CreateBrowser(browser()->profile());
@@ -478,7 +482,6 @@
   CloseBrowserSynchronously(new_browser);
   EXPECT_FALSE(contents_border_weakptr);
 }
-#endif  // !BUILDFLAG(IS_CHROMEOS)
 
 IN_PROC_BROWSER_TEST_P(TabSharingUIViewsBrowserTest,
                        CloseTabInIncognitoBrowser) {
@@ -640,11 +643,15 @@
            /*infobar_count=*/1, /*has_border=*/true,
            /*tab_with_disabled_button=*/kNullTabIndex);
 }
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 class MultipleTabSharingUIViewsBrowserTest : public InProcessBrowserTest {
  public:
-  MultipleTabSharingUIViewsBrowserTest() {}
+#if BUILDFLAG(IS_CHROMEOS)
+  MultipleTabSharingUIViewsBrowserTest() {
+    features_.InitAndEnableFeature(features::kTabCaptureBlueBorderCrOS);
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   void CreateUIsAndStartSharing(Browser* browser,
                                 int capturing_tab,
@@ -674,6 +681,10 @@
   }
 
  private:
+#if BUILDFLAG(IS_CHROMEOS)
+  base::test::ScopedFeatureList features_;
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
   std::vector<std::unique_ptr<TabSharingUI>> tab_sharing_ui_views_;
 };
 
@@ -696,10 +707,6 @@
         capture_indicator->IsBeingMirrored(GetWebContents(browser(), i)));
 
   views::Widget* contents_border = GetContentsBorder(browser());
-#if BUILDFLAG(IS_CHROMEOS)
-  // TODO(https://crbug.com/1030925): Fix contents border on ChromeOS.
-  EXPECT_EQ(nullptr, contents_border);
-#else
   // The capturing tab, which is not itself being captured, does not have
   // the contents-border.
   ActivateTab(browser(), 0);
@@ -710,7 +717,6 @@
     ActivateTab(browser(), i);
     ASSERT_TRUE(contents_border->IsVisible());
   }
-#endif
 }
 
 IN_PROC_BROWSER_TEST_F(MultipleTabSharingUIViewsBrowserTest, StopSharing) {
diff --git a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
index cd58bc0..4947509d 100644
--- a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
@@ -544,12 +544,11 @@
       tab_view_top_row_->AddChildView(CreateOptionsMenuButton());
   tab_view_top_row_->AddChildView(CreateCloseButton());
 
+  const int button_horizontal_spacing =
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
   if (icon) {
-    icon->SetProperty(
-        views::kMarginsKey,
-        gfx::Insets::TLBR(0, 0, 0,
-                          provider->GetDistanceMetric(
-                              views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
+    icon->SetProperty(views::kMarginsKey,
+                      gfx::Insets().set_right(button_horizontal_spacing));
   }
   tabbed_pane_->SetProperty(
       views::kFlexBehaviorKey,
@@ -561,15 +560,11 @@
                                views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(2));
   options_menu->SetProperty(views::kElementIdentifierKey, kOptionsMenuButton);
-  options_menu->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::VH(0, provider->GetDistanceMetric(
-                             views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
+  options_menu->SetProperty(views::kMarginsKey,
+                            gfx::Insets::VH(0, button_horizontal_spacing));
 
   const int vertical_spacing =
       provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL);
-  const int horizontal_spacing =
-      provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
 
   // Text selection.
   auto partial_text_label = std::make_unique<views::Label>(
@@ -579,10 +574,8 @@
   partial_text_label->SizeToFit(tab_view_top_row_->GetPreferredSize().width());
   partial_text_label->SetHorizontalAlignment(
       gfx::HorizontalAlignment::ALIGN_LEFT);
-  partial_text_label->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(vertical_spacing, 0, vertical_spacing,
-                        horizontal_spacing));
+  partial_text_label->SetProperty(views::kMarginsKey,
+                                  gfx::Insets::VH(vertical_spacing, 0));
   partial_text_label_ = view->AddChildView(std::move(partial_text_label));
   SetTextAlignmentForLocaleTextDirection(model_->GetSourceLanguageCode());
 
@@ -596,9 +589,8 @@
           IDS_PARTIAL_TRANSLATE_BUBBLE_TRANSLATE_FULL_PAGE));
   full_page_button->SetID(BUTTON_ID_FULL_PAGE_TRANSLATE);
   button_row->AddChildView(std::move(full_page_button));
-  button_row->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(0, 0, vertical_spacing, horizontal_spacing));
+  button_row->SetProperty(views::kMarginsKey,
+                          gfx::Insets().set_bottom(vertical_spacing));
   view->AddChildView(std::move(button_row));
 
   return view;
@@ -651,9 +643,7 @@
                                views::MaximumFlexSizeRule::kUnbounded));
 
   title_row->AddChildView(std::move(error_message_label));
-  auto* close_button = title_row->AddChildView(CreateCloseButton());
-  close_button->SetProperty(views::kCrossAxisAlignmentKey,
-                            views::LayoutAlignment::kStart);
+  title_row->AddChildView(CreateCloseButton());
   view->AddChildView(std::move(title_row));
 
   // Button row
@@ -675,11 +665,6 @@
   try_again_button->SetID(BUTTON_ID_TRY_AGAIN);
   button_row->AddChildView(std::move(try_again_button));
   button_row->AddChildView(std::move(advanced_button));
-  button_row->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(0, 0, 0,
-                        provider->GetDistanceMetric(
-                            views::DISTANCE_RELATED_CONTROL_HORIZONTAL)));
   view->AddChildView(std::move(button_row));
 
   return view;
@@ -703,10 +688,9 @@
       close_button_container->AddChildView(CreateCloseButton());
   // The positioning of the close button should match that of the same button
   // in the Tab UI. However, the button in the Tab UI is uniquely spaced due to
-  // its layout behaviour with the views around it, and there are no constants
-  // used to determine its margins. Ideally the margins here would not be
-  // hard-coded but they are needed to match the spacing.
-  close_button->SetProperty(views::kMarginsKey, gfx::Insets::VH(6, 8));
+  // its layout behaviour with the views around it. Ideally the margins here
+  // would not be hard-coded but they are needed to match the spacing.
+  close_button->SetProperty(views::kMarginsKey, gfx::Insets().set_top(9));
   view->AddChildView(std::move(close_button_container));
 
   const int throbber_diameter = 35;
@@ -715,7 +699,7 @@
   auto throbber = std::make_unique<views::Throbber>();
   throbber->SetPreferredSize(gfx::Size(throbber_diameter, throbber_diameter));
   throbber->SetProperty(views::kMarginsKey,
-                        gfx::Insets::TLBR(0, 0, vertical_spacing, 0));
+                        gfx::Insets().set_bottom(vertical_spacing));
   throbber_ = throbber_container->AddChildView(std::move(throbber));
   view->AddChildView(std::move(throbber_container));
 
@@ -869,9 +853,7 @@
   title_row->SetLayoutManager(std::make_unique<views::FlexLayout>());
   auto* title_label = title_row->AddChildView(std::move(language_title_label));
   auto* padding_view = title_row->AddChildView(std::make_unique<views::View>());
-  title_row->AddChildView(CreateCloseButton())
-      ->SetProperty(views::kCrossAxisAlignmentKey,
-                    views::LayoutAlignment::kStart);
+  title_row->AddChildView(CreateCloseButton());
   // Set flex specifications for |title_row| views.
   title_label->SetProperty(
       views::kFlexBehaviorKey,
@@ -885,14 +867,11 @@
                                views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(2));
 
-  form_view->AddChildView(std::move(combobox))
-      ->SetProperty(views::kMarginsKey,
-                    gfx::Insets::TLBR(0, 0, 0, horizontal_spacing));
+  form_view->AddChildView(std::move(combobox));
 
   auto button_row = std::make_unique<views::BoxLayoutView>();
-  button_row->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(2 * vertical_spacing, 0, 0, horizontal_spacing));
+  button_row->SetProperty(views::kMarginsKey,
+                          gfx::Insets().set_top(2 * vertical_spacing));
   button_row->SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kEnd);
   button_row->SetBetweenChildSpacing(
       provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL));
@@ -1119,8 +1098,19 @@
 
 void PartialTranslateBubbleView::UpdateInsets(
     PartialTranslateBubbleModel::ViewState state) {
-  gfx::Insets kTabStateMargins = gfx::Insets::TLBR(7, 16, 8, 12);
-  gfx::Insets kDialogStateMargins = gfx::Insets::TLBR(5, 16, 16, 4);
+  ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
+  const int horizontal_spacing =
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
+
+  // The constants used for insets serve two purposes. |horizontal_spacing| is
+  // used as the UX standard for horizontal padding on the edges. Vertical
+  // insets keep top-most elements as closely aligned as possible across the
+  // bubble's different view states. Some additional margins are set in view
+  // construction due to small differences in how elements are laid out.
+  gfx::Insets kTabStateMargins =
+      gfx::Insets::TLBR(7, horizontal_spacing, 8, horizontal_spacing);
+  gfx::Insets kDialogStateMargins =
+      gfx::Insets::TLBR(2, horizontal_spacing, 16, horizontal_spacing);
 
   if (state == PartialTranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE ||
       state == PartialTranslateBubbleModel::VIEW_STATE_TRANSLATING ||
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 15354be6..b59056a56 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -647,12 +647,11 @@
         view->AddChildView(std::move(before_always_translate_checkbox));
   }
 
+  const int button_horizontal_spacing =
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
   if (icon) {
-    icon->SetProperty(
-        views::kMarginsKey,
-        gfx::Insets::TLBR(0, 0, 0,
-                          provider->GetDistanceMetric(
-                              views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
+    icon->SetProperty(views::kMarginsKey,
+                      gfx::Insets().set_right(button_horizontal_spacing));
   }
   tabbed_pane_->SetProperty(
       views::kFlexBehaviorKey,
@@ -664,10 +663,8 @@
                                views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(2));
   options_menu->SetProperty(views::kElementIdentifierKey, kOptionsMenuButton);
-  options_menu->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::VH(0, provider->GetDistanceMetric(
-                             views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
+  options_menu->SetProperty(views::kMarginsKey,
+                            gfx::Insets::VH(0, button_horizontal_spacing));
   if (always_translate_checkbox_) {
     horizontal_view->SetProperty(
         views::kMarginsKey,
@@ -730,9 +727,7 @@
                                views::MaximumFlexSizeRule::kUnbounded));
 
   title_row->AddChildView(std::move(error_message_label));
-  auto* close_button = title_row->AddChildView(CreateCloseButton());
-  close_button->SetProperty(views::kCrossAxisAlignmentKey,
-                            views::LayoutAlignment::kStart);
+  title_row->AddChildView(CreateCloseButton());
   view->AddChildView(std::move(title_row));
 
   // Button row.
@@ -752,11 +747,6 @@
   try_again_button->SetID(BUTTON_ID_TRY_AGAIN);
   button_row->AddChildView(std::move(try_again_button));
   button_row->AddChildView(std::move(advanced_button));
-  button_row->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(0, 0, 0,
-                        provider->GetDistanceMetric(
-                            views::DISTANCE_RELATED_CONTROL_HORIZONTAL)));
   view->AddChildView(std::move(button_row));
 
   return view;
@@ -914,9 +904,7 @@
   title_row->SetLayoutManager(std::make_unique<views::FlexLayout>());
   auto* title_label = title_row->AddChildView(std::move(language_title_label));
   auto* padding_view = title_row->AddChildView(std::make_unique<views::View>());
-  title_row->AddChildView(CreateCloseButton())
-      ->SetProperty(views::kCrossAxisAlignmentKey,
-                    views::LayoutAlignment::kStart);
+  title_row->AddChildView(CreateCloseButton());
   // Set flex specifications for |title_row| views.
   title_label->SetProperty(
       views::kFlexBehaviorKey,
@@ -930,21 +918,17 @@
                                views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(2));
 
-  form_view->AddChildView(std::move(combobox))
-      ->SetProperty(views::kMarginsKey,
-                    gfx::Insets::TLBR(0, 0, 0, horizontal_spacing));
+  form_view->AddChildView(std::move(combobox));
 
   auto button_row = std::make_unique<views::BoxLayoutView>();
   if (advanced_always_translate_checkbox) {
     advanced_always_translate_checkbox_ =
         form_view->AddChildView(std::move(advanced_always_translate_checkbox));
-    button_row->SetProperty(
-        views::kMarginsKey,
-        gfx::Insets::TLBR(vertical_spacing, 0, 0, horizontal_spacing));
+    button_row->SetProperty(views::kMarginsKey,
+                            gfx::Insets().set_top(vertical_spacing));
   } else {
-    button_row->SetProperty(
-        views::kMarginsKey,
-        gfx::Insets::TLBR(2 * vertical_spacing, 0, 0, horizontal_spacing));
+    button_row->SetProperty(views::kMarginsKey,
+                            gfx::Insets().set_top(2 * vertical_spacing));
   }
 
   button_row->SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kEnd);
@@ -1154,8 +1138,14 @@
 }
 
 void TranslateBubbleView::UpdateInsets(TranslateBubbleModel::ViewState state) {
-  gfx::Insets kTabStateMargins = gfx::Insets::TLBR(7, 16, 8, 12);
-  gfx::Insets kDialogStateMargins = gfx::Insets::TLBR(5, 16, 16, 4);
+  ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
+  const int horizontal_spacing =
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
+
+  gfx::Insets kTabStateMargins =
+      gfx::Insets::TLBR(7, horizontal_spacing, 8, horizontal_spacing);
+  gfx::Insets kDialogStateMargins =
+      gfx::Insets::TLBR(2, horizontal_spacing, 16, horizontal_spacing);
 
   if (state == TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE ||
       state == TranslateBubbleModel::VIEW_STATE_TRANSLATING ||
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
index 162d153..e476351 100644
--- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -23,9 +23,8 @@
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h"
-#include "chrome/browser/web_applications/commands/callback_command.h"
 #include "chrome/browser/web_applications/locks/app_lock.h"
-#include "chrome/browser/web_applications/web_app_command_manager.h"
+#include "chrome/browser/web_applications/web_app_command_scheduler.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
@@ -208,16 +207,15 @@
 }
 
 void WebAppBrowserController::ToggleAlwaysShowToolbarInFullscreen() {
-  // base::Unretained is safe as the command manager won't execute the command
-  // if the provider no longer exists.
-  provider_->command_manager().ScheduleCommand(
-      std::make_unique<CallbackCommand>(
-          std::make_unique<AppLockDescription, base::flat_set<AppId>>(
-              {app_id()}),
-          base::BindOnce(
-              &WebAppSyncBridge::SetAlwaysShowToolbarInFullscreen,
-              base::Unretained(&provider_->sync_bridge()), app_id(),
-              !registrar().AlwaysShowToolbarInFullscreen(app_id()))));
+  provider_->scheduler().ScheduleCallbackWithLock<AppLock>(
+      std::make_unique<AppLockDescription, base::flat_set<AppId>>({app_id()}),
+      base::BindOnce(
+          [](const AppId& app_id, AppLock& lock) {
+            lock.sync_bridge().SetAlwaysShowToolbarInFullscreen(
+                app_id,
+                !lock.registrar().AlwaysShowToolbarInFullscreen(app_id));
+          },
+          app_id()));
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/ash/DEPS b/chrome/browser/ui/webui/ash/DEPS
index 301e2fd8..ef595e5 100644
--- a/chrome/browser/ui/webui/ash/DEPS
+++ b/chrome/browser/ui/webui/ash/DEPS
@@ -1,17 +1,9 @@
-# TODO(https://crbug.com/1164001): When this file is edited, same file in
-# //chrome/browser/ui/webui/chromeos should be updated as well. We need to sync
-# both files until the migration is done.
-
 include_rules = [
-  "+ash/utility",
-  "+ash/system/human_presence",
   "+ash/system/diagnostics",
 
-  # Chrome OS depends on views, so allow code in this directory to depend on
-  # ui/views.
+  # Ash depends on views, so allow code in ui/webui/ash to depend on ui/views.
   "+chrome/browser/ui/views",
 
-  "+media/audio/sounds",
   "+services/device/public/mojom",
   "+services/network",
 ]
diff --git a/chrome/browser/ui/webui/chromeos/DEPS b/chrome/browser/ui/webui/chromeos/DEPS
index 5e00939..d08edf2 100644
--- a/chrome/browser/ui/webui/chromeos/DEPS
+++ b/chrome/browser/ui/webui/chromeos/DEPS
@@ -1,17 +1,5 @@
-# TODO(https://crbug.com/1164001): When this file is edited, same file in
-# //chrome/browser/ui/webui/ash should be updated as well. We need to sync
-# both files until the migration is done.
-
 include_rules = [
-  "+ash/utility",
-  "+ash/system/human_presence",
-  "+ash/system/diagnostics",
-
   # Chrome OS depends on views, so allow code in this directory to depend on
   # ui/views.
   "+chrome/browser/ui/views",
-
-  "+media/audio/sounds",
-  "+services/device/public/mojom",
-  "+services/network",
 ]
diff --git a/chrome/browser/ui/webui/policy/policy_ui.cc b/chrome/browser/ui/webui/policy/policy_ui.cc
index e4e2090..4ed5d14 100644
--- a/chrome/browser/ui/webui/policy/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui.cc
@@ -36,6 +36,7 @@
     {"labelAssetId", IDS_POLICY_LABEL_ASSET_ID},
     {"labelClientId", IDS_POLICY_LABEL_CLIENT_ID},
     {"labelDirectoryApiId", IDS_POLICY_LABEL_DIRECTORY_API_ID},
+    {"labelError", IDS_POLICY_LABEL_ERROR},
     {"labelGaiaId", IDS_POLICY_LABEL_GAIA_ID},
     {"labelIsAffiliated", IDS_POLICY_LABEL_IS_AFFILIATED},
     {"labelLastCloudReportSentTimestamp",
@@ -73,6 +74,7 @@
     {"showUnset", IDS_POLICY_SHOW_UNSET},
     {"signinProfile", IDS_POLICY_SIGNIN_PROFILE},
     {"status", IDS_POLICY_STATUS},
+    {"statusErrorManagedNoPolicy", IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY},
     {"statusDevice", IDS_POLICY_STATUS_DEVICE},
     {"statusMachine", IDS_POLICY_STATUS_MACHINE},
 #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
index 3da88a6e..0ff27a1a 100644
--- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
+++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
@@ -91,12 +91,17 @@
   switch (action) {
     case PrivacySandboxService::PromptAction::kNoticeAcknowledge:
     case PrivacySandboxService::PromptAction::kNoticeDismiss:
-    case PrivacySandboxService::PromptAction::kNoticeOpenSettings:
+    case PrivacySandboxService::PromptAction::kNoticeOpenSettings: {
+      CloseDialog();
+      break;
+    }
     case PrivacySandboxService::PromptAction::kConsentAccepted:
     case PrivacySandboxService::PromptAction::kConsentDeclined: {
-      did_user_make_decision_ = true;
-      DisallowJavascript();
-      std::move(close_callback_).Run();
+      // Close the dialog after consent was resolved only for trials consent
+      // (kConsent). In case of kM1Consent, a notice step will be shown after
+      // the consent decision.
+      if (prompt_type_ == PrivacySandboxService::PromptType::kConsent)
+        CloseDialog();
       break;
     }
     default:
@@ -123,11 +128,13 @@
   AllowJavascript();
 
   // Notify the service that the DOM was loaded and the dialog was shown to
-  // user.
-  if (IsConsent(prompt_type_)) {
+  // user. Only for trials prompt types, other prompt types are handled in web
+  // UI.
+  if (prompt_type_ == PrivacySandboxService::PromptType::kConsent) {
     NotifyServiceAboutPromptAction(
         PrivacySandboxService::PromptAction::kConsentShown);
-  } else {
+  }
+  if (prompt_type_ == PrivacySandboxService::PromptType::kNotice) {
     NotifyServiceAboutPromptAction(
         PrivacySandboxService::PromptAction::kNoticeShown);
   }
@@ -141,3 +148,9 @@
   DCHECK(privacy_sandbox_service_);
   privacy_sandbox_service_->PromptActionOccurred(action);
 }
+
+void PrivacySandboxDialogHandler::CloseDialog() {
+  did_user_make_decision_ = true;
+  DisallowJavascript();
+  std::move(close_callback_).Run();
+}
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.h b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.h
index 0610269..a330f70 100644
--- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.h
+++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.h
@@ -50,6 +50,7 @@
   void HandleShowDialog(const base::Value::List& args);
   void NotifyServiceAboutPromptAction(
       PrivacySandboxService::PromptAction action);
+  void CloseDialog();
 
   base::OnceClosure close_callback_;
   base::OnceCallback<void(int)> resize_callback_;
diff --git a/chrome/browser/ui/webui/settings/ash/fingerprint_handler.cc b/chrome/browser/ui/webui/settings/ash/fingerprint_handler.cc
index 8da3f0e..f73f50d 100644
--- a/chrome/browser/ui/webui/settings/ash/fingerprint_handler.cc
+++ b/chrome/browser/ui/webui/settings/ash/fingerprint_handler.cc
@@ -185,11 +185,7 @@
 
   // Auth token expiration will trigger password prompt.
   // Silently fail if auth token is incorrect.
-  quick_unlock::QuickUnlockStorage* quick_unlock_storage =
-      quick_unlock::QuickUnlockFactory::GetForProfile(profile_);
-  if (!quick_unlock_storage->GetAuthToken())
-    return;
-  if (auth_token != quick_unlock_storage->GetAuthToken()->Identifier())
+  if (!CheckAuthTokenValidity(auth_token))
     return;
 
   // Determines what the newly added fingerprint's name should be.
@@ -242,10 +238,15 @@
   const auto& list = args;
   CHECK_EQ(2U, list.size());
   std::string callback_id = list[0].GetString();
+  const std::string& auth_token = list[1].GetString();
   int index = list[1].GetInt();
   CHECK_GE(index, 0);
   CHECK_LT(index, static_cast<int>(fingerprints_paths_.size()));
 
+  // Silently fail if auth token is incorrect.
+  if (!CheckAuthTokenValidity(auth_token))
+    return;
+
   AllowJavascript();
   fp_service_->RemoveRecord(
       fingerprints_paths_[index],
@@ -286,4 +287,14 @@
   ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
 }
 
+bool FingerprintHandler::CheckAuthTokenValidity(const std::string& auth_token) {
+  quick_unlock::QuickUnlockStorage* quick_unlock_storage =
+      quick_unlock::QuickUnlockFactory::GetForProfile(profile_);
+  if (!quick_unlock_storage->GetAuthToken())
+    return false;
+  if (auth_token != quick_unlock_storage->GetAuthToken()->Identifier())
+    return false;
+  return true;
+}
+
 }  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/fingerprint_handler.h b/chrome/browser/ui/webui/settings/ash/fingerprint_handler.h
index 4e0beaf..1ed9574 100644
--- a/chrome/browser/ui/webui/settings/ash/fingerprint_handler.h
+++ b/chrome/browser/ui/webui/settings/ash/fingerprint_handler.h
@@ -67,6 +67,7 @@
   void OnRemoveRecord(const std::string& callback_id, bool success);
   void OnSetRecordLabel(const std::string& callback_id, bool success);
   void OnEndCurrentAuthSession(bool success);
+  bool CheckAuthTokenValidity(const std::string& auth_token);
 
   Profile* profile_;  // unowned
 
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
index f95bf0a7..e18e5c2 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
@@ -11,24 +11,20 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
-#include "content/public/browser/web_ui.h"
 #include "ui/accessibility/ax_tree_update.h"
 
 using read_anything::mojom::Page;
 using read_anything::mojom::PageHandler;
-using read_anything::mojom::ReadAnythingTheme;
+using read_anything::mojom::ReadAnythingThemePtr;
 
 ReadAnythingPageHandler::ReadAnythingPageHandler(
     mojo::PendingRemote<Page> page,
-    mojo::PendingReceiver<PageHandler> receiver,
-    content::WebUI* web_ui)
-    : browser_(chrome::FindLastActive()),
-      receiver_(this, std::move(receiver)),
-      page_(std::move(page)),
-      web_ui_(web_ui) {
+    mojo::PendingReceiver<PageHandler> receiver)
+    : receiver_(this, std::move(receiver)), page_(std::move(page)) {
   // Register |this| as a |ReadAnythingModel::Observer| with the coordinator
   // for the component. This will allow the IPC to update the front-end web ui.
 
+  browser_ = chrome::FindLastActive();
   if (!browser_)
     return;
 
@@ -72,21 +68,8 @@
 }
 
 void ReadAnythingPageHandler::OnReadAnythingThemeChanged(
-    std::string& font_name,
-    double font_scale,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    read_anything::mojom::Spacing line_spacing,
-    read_anything::mojom::Spacing letter_spacing) {
-  content::WebContents* web_contents = web_ui_->GetWebContents();
-  SkColor foreground_skcolor =
-      web_contents->GetColorProvider().GetColor(foreground_color_id);
-  SkColor background_skcolor =
-      web_contents->GetColorProvider().GetColor(background_color_id);
-
-  page_->OnThemeChanged(
-      ReadAnythingTheme::New(font_name, font_scale, foreground_skcolor,
-                             background_skcolor, line_spacing, letter_spacing));
+    ReadAnythingThemePtr new_theme_ptr) {
+  page_->OnThemeChanged(std::move(new_theme_ptr));
 }
 
 void ReadAnythingPageHandler::OnLinkClicked(const GURL& url,
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h
index 5175ac6..0a66766 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h
@@ -41,8 +41,7 @@
 
   ReadAnythingPageHandler(
       mojo::PendingRemote<read_anything::mojom::Page> page,
-      mojo::PendingReceiver<read_anything::mojom::PageHandler> receiver,
-      content::WebUI* web_ui);
+      mojo::PendingReceiver<read_anything::mojom::PageHandler> receiver);
   ReadAnythingPageHandler(const ReadAnythingPageHandler&) = delete;
   ReadAnythingPageHandler& operator=(const ReadAnythingPageHandler&) = delete;
   ~ReadAnythingPageHandler() override;
@@ -55,12 +54,7 @@
       const ui::AXTreeUpdate& snapshot,
       const std::vector<ui::AXNodeID>& content_node_ids) override;
   void OnReadAnythingThemeChanged(
-      std::string& font_name,
-      double font_scale,
-      ui::ColorId foreground_color_id,
-      ui::ColorId background_color_id,
-      read_anything::mojom::Spacing line_spacing,
-      read_anything::mojom::Spacing letter_spacing) override;
+      read_anything::mojom::ReadAnythingThemePtr new_theme) override;
 
   // ReadAnythingCoordinator::Observer:
   void OnCoordinatorDestroyed() override;
@@ -69,12 +63,10 @@
   raw_ptr<ReadAnythingCoordinator> coordinator_;
   raw_ptr<ReadAnythingPageHandler::Delegate> delegate_;
 
-  const raw_ptr<Browser> browser_;
+  raw_ptr<Browser> browser_;
 
-  const mojo::Receiver<read_anything::mojom::PageHandler> receiver_;
-  const mojo::Remote<read_anything::mojom::Page> page_;
-
-  const raw_ptr<content::WebUI> web_ui_;
+  mojo::Receiver<read_anything::mojom::PageHandler> receiver_;
+  mojo::Remote<read_anything::mojom::Page> page_;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_PAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_ui.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_ui.cc
index cb115d1..108585b 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_ui.cc
@@ -54,7 +54,7 @@
     mojo::PendingReceiver<read_anything::mojom::PageHandler> receiver) {
   DCHECK(page);
   read_anything_page_handler_ = std::make_unique<ReadAnythingPageHandler>(
-      std::move(page), std::move(receiver), web_ui());
+      std::move(page), std::move(receiver));
   if (embedder())
     embedder()->ShowUI();
 }
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
index 37f59d9..55c99f0 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
@@ -176,7 +176,7 @@
     mojo::PendingReceiver<read_anything::mojom::PageHandler> receiver) {
   DCHECK(page);
   read_anything_page_handler_ = std::make_unique<ReadAnythingPageHandler>(
-      std::move(page), std::move(receiver), web_ui());
+      std::move(page), std::move(receiver));
 }
 
 void ReadingListUI::BindInterface(
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc
index d5196a2..0e87f4c 100644
--- a/chrome/browser/ui/webui/webui_util.cc
+++ b/chrome/browser/ui/webui/webui_util.cc
@@ -69,7 +69,8 @@
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::TrustedTypes,
       "trusted-types parse-html-subset sanitize-inner-html static-types "
-      "webui-test-script "
+      // Add TrustedTypes policies used during tests.
+      "webui-test-script webui-test-html "
       // Add TrustedTypes policies necessary for using Polymer.
       "polymer-html-literal polymer-template-event-attribute-policy;");
 }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn
index e50cb44..2062358 100644
--- a/chrome/browser/vr/BUILD.gn
+++ b/chrome/browser/vr/BUILD.gn
@@ -319,7 +319,6 @@
     "macros.h",
     "model/assets.cc",
     "model/assets.h",
-    "model/camera_model.cc",
     "model/camera_model.h",
     "model/capturing_state_model.h",
     "model/controller_model.cc",
diff --git a/chrome/browser/vr/elements/linear_layout_unittest.cc b/chrome/browser/vr/elements/linear_layout_unittest.cc
index 69e75d8..1115fa5a 100644
--- a/chrome/browser/vr/elements/linear_layout_unittest.cc
+++ b/chrome/browser/vr/elements/linear_layout_unittest.cc
@@ -189,7 +189,7 @@
 
   auto scene = std::make_unique<UiScene>();
   scene->AddUiElement(kRoot, std::move(parent_layout));
-  scene->OnBeginFrame(gfx::MicrosecondsToTicks(1), StartHeadPose());
+  scene->OnBeginFrame(gfx::MicrosecondsToTicks(1), kStartHeadPose);
 
   // Ensure that layouts expand to include the cumulative size of children.
   EXPECT_FLOAT_EQ(p_parent_layout->size().width(), 999.f);
@@ -219,25 +219,25 @@
 
   auto scene = std::make_unique<UiScene>();
   scene->AddUiElement(kRoot, std::move(layout));
-  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), StartHeadPose());
+  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), kStartHeadPose);
   EXPECT_FLOAT_EQ(p_layout->size().width(), 3.f);
 
   // Element grows to fit.
   p_layout->set_layout_length(3.5f);
   p_resizable_child->set_resizable_by_layout(true);
-  scene->OnBeginFrame(gfx::MicrosecondsToTicks(1), StartHeadPose());
+  scene->OnBeginFrame(gfx::MicrosecondsToTicks(1), kStartHeadPose);
   EXPECT_FLOAT_EQ(p_layout->size().width(), 3.5f);
   EXPECT_FLOAT_EQ(p_resizable_child->size().width(), 1.5f);
 
   // Element shrinks to fit.
   p_layout->set_layout_length(2.5f);
-  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), StartHeadPose());
+  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), kStartHeadPose);
   EXPECT_FLOAT_EQ(p_layout->size().width(), 2.5f);
   EXPECT_FLOAT_EQ(p_resizable_child->size().width(), 0.5f);
 
   // Element shrinks to 0 if there's no size for it.
   p_layout->set_layout_length(1.5f);
-  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), StartHeadPose());
+  scene->OnBeginFrame(gfx::MicrosecondsToTicks(0), kStartHeadPose);
   EXPECT_FLOAT_EQ(p_layout->size().width(), 2.0f);
   EXPECT_FLOAT_EQ(p_resizable_child->size().width(), 0.f);
 }
diff --git a/chrome/browser/vr/elements/rect_unittest.cc b/chrome/browser/vr/elements/rect_unittest.cc
index a4b56860..f896ae8a 100644
--- a/chrome/browser/vr/elements/rect_unittest.cc
+++ b/chrome/browser/vr/elements/rect_unittest.cc
@@ -45,11 +45,11 @@
   rect->SetTransitionedProperties({BACKGROUND_COLOR, FOREGROUND_COLOR});
   rect->SetColor(SK_ColorBLACK);
 
-  scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose);
   EXPECT_EQ(SK_ColorRED, rect->edge_color());
   EXPECT_EQ(SK_ColorBLUE, rect->center_color());
 
-  scene.OnBeginFrame(gfx::MsToTicks(5000), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(5000), kStartHeadPose);
   EXPECT_EQ(SK_ColorBLACK, rect->edge_color());
   EXPECT_EQ(SK_ColorBLACK, rect->center_color());
 }
diff --git a/chrome/browser/vr/elements/scaled_depth_adjuster_unittest.cc b/chrome/browser/vr/elements/scaled_depth_adjuster_unittest.cc
index c8b767f..b65d88fd 100644
--- a/chrome/browser/vr/elements/scaled_depth_adjuster_unittest.cc
+++ b/chrome/browser/vr/elements/scaled_depth_adjuster_unittest.cc
@@ -31,7 +31,7 @@
   auto adjuster = std::make_unique<ScaledDepthAdjuster>(2.5);
   adjuster->AddChild(std::move(element));
   scene.AddUiElement(kRoot, std::move(adjuster));
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   CheckScaleAndDepth(p_element, 2.5);
 }
 
@@ -64,7 +64,7 @@
   grandparent->AddChild(std::move(parent_adjuster));
   grandparent_adjuster->AddChild(std::move(grandparent));
   scene.AddUiElement(kRoot, std::move(grandparent_adjuster));
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
 
   CheckScaleAndDepth(p_child, 2.6f);
   CheckScaleAndDepth(p_parent, 2.4f);
diff --git a/chrome/browser/vr/elements/shadow_unittest.cc b/chrome/browser/vr/elements/shadow_unittest.cc
index cb0c0c4..a57bf5c 100644
--- a/chrome/browser/vr/elements/shadow_unittest.cc
+++ b/chrome/browser/vr/elements/shadow_unittest.cc
@@ -25,14 +25,14 @@
   shadow->AddChild(std::move(rect));
   scene.AddUiElement(kRoot, std::move(shadow));
 
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   float old_left_padding = shadow_ptr->left_padding();
   float old_top_padding = shadow_ptr->top_padding();
   EXPECT_LE(0.0f, old_left_padding);
   EXPECT_LE(0.0f, old_top_padding);
 
   rect_ptr->SetTranslate(0, 0, 0.15);
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   float new_left_padding = shadow_ptr->left_padding();
   float new_top_padding = shadow_ptr->top_padding();
   EXPECT_LE(old_left_padding, new_left_padding);
diff --git a/chrome/browser/vr/elements/spinner_unittest.cc b/chrome/browser/vr/elements/spinner_unittest.cc
index 3d2818b..54b6fcf4 100644
--- a/chrome/browser/vr/elements/spinner_unittest.cc
+++ b/chrome/browser/vr/elements/spinner_unittest.cc
@@ -51,7 +51,7 @@
   UiTexture* texture = spinner_element->GetTexture();
   scene.AddUiElement(kRoot, std::move(spinner_element));
   base::TimeTicks start_time = gfx::MsToTicks(1);
-  scene.OnBeginFrame(start_time, StartHeadPose());
+  scene.OnBeginFrame(start_time, kStartHeadPose);
 
   struct TestCase {
     float start_angle;
@@ -70,7 +70,7 @@
   };
 
   for (const auto& test_case : test_cases) {
-    scene.OnBeginFrame(gfx::MsToTicks(1) + test_case.delta, StartHeadPose());
+    scene.OnBeginFrame(gfx::MsToTicks(1) + test_case.delta, kStartHeadPose);
     CheckArc(texture, test_case.start_angle, test_case.sweep_angle);
   }
 }
diff --git a/chrome/browser/vr/elements/text_input_unittest.cc b/chrome/browser/vr/elements/text_input_unittest.cc
index d249aad..70fc344 100644
--- a/chrome/browser/vr/elements/text_input_unittest.cc
+++ b/chrome/browser/vr/elements/text_input_unittest.cc
@@ -188,13 +188,13 @@
   scene.root_element().AddChild(std::move(instance));
 
   // Text field is empty, so we should be showing hint text.
-  scene.OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene.OnBeginFrame(base::TimeTicks(), kStartHeadPose);
   EXPECT_GT(element->get_hint_element()->GetTargetOpacity(), 0);
 
   // When text enters the field, the hint should disappear.
   EditedText info(u"text");
   element->UpdateInput(info);
-  scene.OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene.OnBeginFrame(base::TimeTicks(), kStartHeadPose);
   EXPECT_EQ(element->get_hint_element()->GetTargetOpacity(), 0);
 }
 
@@ -214,7 +214,7 @@
   float initial = element->get_cursor_element()->GetTargetOpacity();
   EXPECT_EQ(initial, 0.f);
   for (int ms = 0; ms <= 2000; ms += 100) {
-    scene.OnBeginFrame(gfx::MsToTicks(ms), StartHeadPose());
+    scene.OnBeginFrame(gfx::MsToTicks(ms), kStartHeadPose);
     EXPECT_EQ(initial, element->get_cursor_element()->GetTargetOpacity());
   }
 
@@ -223,7 +223,7 @@
   initial = element->get_cursor_element()->GetTargetOpacity();
   bool toggled = false;
   for (int ms = 0; ms <= 2000; ms += 100) {
-    scene.OnBeginFrame(gfx::MsToTicks(ms), StartHeadPose());
+    scene.OnBeginFrame(gfx::MsToTicks(ms), kStartHeadPose);
     if (initial != element->get_cursor_element()->GetTargetOpacity())
       toggled = true;
   }
@@ -236,7 +236,7 @@
   element->UpdateInput(info);
   EXPECT_EQ(0.f, element->get_cursor_element()->GetTargetOpacity());
   for (int ms = 0; ms <= 2000; ms += 100) {
-    scene.OnBeginFrame(gfx::MsToTicks(ms), StartHeadPose());
+    scene.OnBeginFrame(gfx::MsToTicks(ms), kStartHeadPose);
     EXPECT_EQ(0.f, element->get_cursor_element()->GetTargetOpacity());
   }
 }
diff --git a/chrome/browser/vr/elements/throbber_unittest.cc b/chrome/browser/vr/elements/throbber_unittest.cc
index 864c9585..02b119b 100644
--- a/chrome/browser/vr/elements/throbber_unittest.cc
+++ b/chrome/browser/vr/elements/throbber_unittest.cc
@@ -35,11 +35,11 @@
   scene.AddUiElement(kRoot, std::move(element));
 
   throbber->SetCircleGrowAnimationEnabled(true);
-  scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose);
   EXPECT_TRUE(throbber->IsAnimatingProperty(CIRCLE_GROW));
 
   // Half way through animation.
-  scene.OnBeginFrame(gfx::MsToTicks(501), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(501), kStartHeadPose);
   EXPECT_FLOAT_EQ(throbber->opacity(), kInitialOpacity / 2);
   EXPECT_FLOAT_EQ(
       throbber->GetTargetTransform().at(UiElement::kScaleIndex).scale.x,
diff --git a/chrome/browser/vr/elements/transient_element_unittest.cc b/chrome/browser/vr/elements/transient_element_unittest.cc
index d5428f1..ce1eeb9 100644
--- a/chrome/browser/vr/elements/transient_element_unittest.cc
+++ b/chrome/browser/vr/elements/transient_element_unittest.cc
@@ -19,7 +19,7 @@
 bool DoBeginFrame(UiElement* element, int time_milliseconds) {
   element->set_last_frame_time(gfx::MsToTicks(time_milliseconds));
   const bool force_animations_to_completion = false;
-  return element->DoBeginFrame(StartHeadPose(), force_animations_to_completion);
+  return element->DoBeginFrame(kStartHeadPose, force_animations_to_completion);
 }
 
 }  // namespace
@@ -118,31 +118,31 @@
   parent->AddChild(std::move(element));
 
   // Child hidden because parent is hidden.
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose));
   EXPECT_FALSE(child->IsVisible());
   EXPECT_FALSE(parent->IsVisible());
 
   // Setting visiblity on parent should make the child visible.
   parent->SetVisible(true);
   scene.set_dirty();
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(10), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(10), kStartHeadPose));
   EXPECT_TRUE(child->IsVisible());
   EXPECT_TRUE(parent->IsVisible());
 
   // Make sure the elements go away.
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2010), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2010), kStartHeadPose));
   EXPECT_FALSE(child->IsVisible());
   EXPECT_FALSE(parent->IsVisible());
 
   // Test again, but this time manually set the visibility to false.
   parent->SetVisible(true);
   scene.set_dirty();
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2020), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2020), kStartHeadPose));
   EXPECT_TRUE(child->IsVisible());
   EXPECT_TRUE(parent->IsVisible());
   parent->SetVisible(false);
   scene.set_dirty();
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2030), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(2030), kStartHeadPose));
   EXPECT_FALSE(child->IsVisible());
   EXPECT_FALSE(parent->IsVisible());
 }
diff --git a/chrome/browser/vr/elements/ui_element_unittest.cc b/chrome/browser/vr/elements/ui_element_unittest.cc
index 9ac6162..613d8cd 100644
--- a/chrome/browser/vr/elements/ui_element_unittest.cc
+++ b/chrome/browser/vr/elements/ui_element_unittest.cc
@@ -257,10 +257,10 @@
   UiElement* rect_ptr = rect.get();
   scene.AddUiElement(kRoot, std::move(rect));
   base::TimeTicks start_time = gfx::MicrosecondsToTicks(1);
-  EXPECT_TRUE(scene.OnBeginFrame(start_time, StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(start_time, kStartHeadPose));
   EXPECT_SIZEF_EQ(gfx::SizeF(10, 100), rect_ptr->size());
   EXPECT_TRUE(scene.OnBeginFrame(start_time + gfx::MicrosecondsToDelta(10000),
-                                 StartHeadPose()));
+                                 kStartHeadPose));
   EXPECT_SIZEF_EQ(gfx::SizeF(20, 200), rect_ptr->size());
 }
 
@@ -280,11 +280,11 @@
       gfx::MicrosecondsToDelta(10000)));
 
   base::TimeTicks start_time = gfx::MicrosecondsToTicks(1);
-  EXPECT_TRUE(scene.OnBeginFrame(start_time, StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(start_time, kStartHeadPose));
   EXPECT_POINT3F_EQ(gfx::Point3F(10, 100, 1000),
                     rect_ptr->LocalTransform().MapPoint(gfx::Point3F()));
   EXPECT_TRUE(scene.OnBeginFrame(start_time + gfx::MicrosecondsToDelta(10000),
-                                 StartHeadPose()));
+                                 kStartHeadPose));
   EXPECT_POINT3F_EQ(gfx::Point3F(20, 200, 2000),
                     rect_ptr->LocalTransform().MapPoint(gfx::Point3F()));
 }
@@ -463,11 +463,11 @@
   parent->AddChild(std::move(child));
   scene.AddUiElement(kRoot, std::move(parent));
 
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
 
   value = true;
 
-  scene.OnBeginFrame(gfx::MsToTicks(16), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(16), kStartHeadPose);
 
   // We should have started animating both, and they should both be at opacity
   // zero given that this is the first frame. This does not guarantee that
@@ -478,7 +478,7 @@
   EXPECT_TRUE(child_ptr->IsAnimatingProperty(OPACITY));
   EXPECT_EQ(child_ptr->opacity(), parent_ptr->opacity());
 
-  scene.OnBeginFrame(gfx::MsToTicks(32), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(32), kStartHeadPose);
   EXPECT_EQ(child_ptr->opacity(), parent_ptr->opacity());
   EXPECT_LT(0.0f, child_ptr->opacity());
 }
diff --git a/chrome/browser/vr/elements/vector_icon_unittest.cc b/chrome/browser/vr/elements/vector_icon_unittest.cc
index 2672c37..6ce49a8 100644
--- a/chrome/browser/vr/elements/vector_icon_unittest.cc
+++ b/chrome/browser/vr/elements/vector_icon_unittest.cc
@@ -44,7 +44,7 @@
   UiTexture* texture = icon->GetTexture();
   scene.AddUiElement(kRoot, std::move(icon));
   base::TimeTicks start_time = gfx::MsToTicks(1);
-  scene.OnBeginFrame(start_time, StartHeadPose());
+  scene.OnBeginFrame(start_time, kStartHeadPose);
 
   InSequence scope;
   cc::MockCanvas canvas;
diff --git a/chrome/browser/vr/model/camera_model.cc b/chrome/browser/vr/model/camera_model.cc
deleted file mode 100644
index d74517e..0000000
--- a/chrome/browser/vr/model/camera_model.cc
+++ /dev/null
@@ -1,14 +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/vr/model/camera_model.h"
-
-namespace vr {
-
-CameraModel::CameraModel() = default;
-CameraModel::~CameraModel() = default;
-CameraModel::CameraModel(const CameraModel&) = default;
-CameraModel& CameraModel::operator=(const CameraModel&) = default;
-
-}  // namespace vr
diff --git a/chrome/browser/vr/model/camera_model.h b/chrome/browser/vr/model/camera_model.h
index 0f1c6d8..ccbeaf9 100644
--- a/chrome/browser/vr/model/camera_model.h
+++ b/chrome/browser/vr/model/camera_model.h
@@ -18,11 +18,6 @@
 };
 
 struct VR_BASE_EXPORT CameraModel {
-  CameraModel();
-  ~CameraModel();
-  CameraModel(const CameraModel&);
-  CameraModel& operator=(const CameraModel&);
-
   EyeType eye_type;
   gfx::Rect viewport;
   gfx::Transform view_matrix;
diff --git a/chrome/browser/vr/renderers/textured_quad_renderer.cc b/chrome/browser/vr/renderers/textured_quad_renderer.cc
index daabe42..b82ac647 100644
--- a/chrome/browser/vr/renderers/textured_quad_renderer.cc
+++ b/chrome/browser/vr/renderers/textured_quad_renderer.cc
@@ -162,12 +162,6 @@
 
 }  // namespace
 
-TexturedQuadRenderer::QuadData::QuadData() = default;
-TexturedQuadRenderer::QuadData::~QuadData() = default;
-TexturedQuadRenderer::QuadData::QuadData(const QuadData&) = default;
-TexturedQuadRenderer::QuadData& TexturedQuadRenderer::QuadData::operator=(
-    const QuadData&) = default;
-
 TexturedQuadRenderer::TexturedQuadRenderer()
     : TexturedQuadRenderer(kVertexShader, kFragmentShader) {}
 
diff --git a/chrome/browser/vr/renderers/textured_quad_renderer.h b/chrome/browser/vr/renderers/textured_quad_renderer.h
index 28fef7d..8bafc1f 100644
--- a/chrome/browser/vr/renderers/textured_quad_renderer.h
+++ b/chrome/browser/vr/renderers/textured_quad_renderer.h
@@ -48,11 +48,6 @@
 
  private:
   struct QuadData {
-    QuadData();
-    ~QuadData();
-    QuadData(const QuadData&);
-    QuadData& operator=(const QuadData&);
-
     int texture_data_handle;
     int overlay_texture_data_handle;
     gfx::Transform model_view_proj_matrix;
diff --git a/chrome/browser/vr/test/constants.cc b/chrome/browser/vr/test/constants.cc
index 57147c9..ae601c0 100644
--- a/chrome/browser/vr/test/constants.cc
+++ b/chrome/browser/vr/test/constants.cc
@@ -12,8 +12,4 @@
                                   -1.002f, -0.2002f, 0.0f, 0.0f, -1.0f, 0.0f);
 }
 
-gfx::Transform StartHeadPose() {
-  return gfx::Transform();
-}
-
 }  // namespace vr
diff --git a/chrome/browser/vr/test/constants.h b/chrome/browser/vr/test/constants.h
index 8b85f30..8878361 100644
--- a/chrome/browser/vr/test/constants.h
+++ b/chrome/browser/vr/test/constants.h
@@ -13,7 +13,7 @@
 
 // Proj matrix as used on a Pixel phone with the Daydream headset.
 gfx::Transform GetPixelDaydreamProjMatrix();
-gfx::Transform StartHeadPose();
+static constexpr gfx::Transform kStartHeadPose;
 static constexpr gfx::Vector3dF kStartControllerPosition(0.3, -0.3, -0.3);
 static constexpr gfx::Vector3dF kForwardVector(0.0f, 0.0f, -1.0f);
 static constexpr gfx::Vector3dF kBackwardVector(0.0f, 0.0f, 1.0f);
diff --git a/chrome/browser/vr/test/ui_test.cc b/chrome/browser/vr/test/ui_test.cc
index 3f1c461..a3b8856 100644
--- a/chrome/browser/vr/test/ui_test.cc
+++ b/chrome/browser/vr/test/ui_test.cc
@@ -258,7 +258,7 @@
 bool UiTest::OnBeginFrame() const {
   bool changed = false;
   model_->current_time = current_time_;
-  changed |= scene_->OnBeginFrame(current_time_, StartHeadPose());
+  changed |= scene_->OnBeginFrame(current_time_, kStartHeadPose);
   if (scene_->HasDirtyTextures()) {
     scene_->UpdateTextures();
     changed = true;
diff --git a/chrome/browser/vr/ui_input_manager_unittest.cc b/chrome/browser/vr/ui_input_manager_unittest.cc
index 572434c..75797d5 100644
--- a/chrome/browser/vr/ui_input_manager_unittest.cc
+++ b/chrome/browser/vr/ui_input_manager_unittest.cc
@@ -104,7 +104,7 @@
     element->SetTranslate(0, 0, z_position);
     element->set_hit_testable(true);
     scene_->AddUiElement(kRoot, std::move(element));
-    scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+    scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
     return p_element;
   }
 
@@ -115,7 +115,7 @@
     element->SetSize(1, 0.1);
     element->set_hit_testable(true);
     scene_->AddUiElement(kRoot, std::move(element));
-    scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+    scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
     return p_element;
   }
 
@@ -216,7 +216,7 @@
   child->set_hit_testable(true);
   child->set_focusable(true);
   p_element->AddChild(std::move(child));
-  scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
 
   // Focus element.
   testing::Sequence s;
@@ -242,7 +242,7 @@
   child->set_hit_testable(true);
   child->set_focusable(false);
   p_element->AddChild(std::move(child));
-  scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
 
   // Focus element.
   testing::Sequence s;
@@ -262,7 +262,7 @@
   element->SetTranslate(0, 0, -1.f);
   element->set_hit_testable(true);
   scene_->AddUiElement(kRoot, std::move(element));
-  scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
 
   ControllerModel controller_model;
   controller_model.laser_direction = kBackwardVector;
@@ -447,7 +447,7 @@
 
   // Re-add the element to the scene, and press on it to lock it for input.
   scene_->AddUiElement(kRoot, std::move(deleted_element));
-  scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
   EXPECT_CALL(*p_element, OnHoverEnter(_, _));
   EXPECT_CALL(*p_element, OnButtonDown(_, _));
   HandleInput(kForwardVector, kDown);
@@ -471,7 +471,7 @@
   element->SetSize(1000.0f, 1000.0f);
   element->set_hit_testable(true);
   scene_->AddUiElement(kRoot, std::move(element));
-  scene_->OnBeginFrame(base::TimeTicks(), StartHeadPose());
+  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
 
   gfx::Point3F center = p_element->GetCenter();
   gfx::Point3F laser_origin(0.5, -0.5, 0.0);
diff --git a/chrome/browser/vr/ui_scene_unittest.cc b/chrome/browser/vr/ui_scene_unittest.cc
index 9c59b08..0e7317b 100644
--- a/chrome/browser/vr/ui_scene_unittest.cc
+++ b/chrome/browser/vr/ui_scene_unittest.cc
@@ -105,14 +105,14 @@
   parent->AddChild(std::move(element));
 
   // Set initial computed opacity.
-  scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose);
 
   parent->SetVisible(false);
 
-  scene.OnBeginFrame(gfx::MsToTicks(2), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(2), kStartHeadPose);
 
   // On the second walk, we should skip the child.
-  scene.OnBeginFrame(gfx::MsToTicks(3), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(3), kStartHeadPose);
 
   EXPECT_FALSE(child->IsVisible());
 }
@@ -142,7 +142,7 @@
   UiElement* child = element.get();
   parent->AddChild(std::move(element));
 
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   gfx::Point3F origin = child->world_space_transform().MapPoint(gfx::Point3F());
   gfx::Point3F point =
       child->world_space_transform().MapPoint(gfx::Point3F(1, 0, 0));
@@ -163,7 +163,7 @@
   element->SetOpacity(0.5);
   parent->AddChild(std::move(element));
 
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   EXPECT_EQ(0.5f, parent->computed_opacity());
   EXPECT_EQ(0.25f, child->computed_opacity());
 }
@@ -190,7 +190,7 @@
 
   EXPECT_FALSE(scene.GetWebVrOverlayElementsToDraw().empty());
   child->SetVisible(false);
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   EXPECT_TRUE(scene.GetWebVrOverlayElementsToDraw().empty());
 }
 
@@ -202,11 +202,11 @@
       gfx::MsToDelta(1000)));
   UiElement* element_ptr = element.get();
   scene.AddUiElement(kRoot, std::move(element));
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose));
 
   element_ptr->SetVisible(false);
   element_ptr->UpdateComputedOpacity();
-  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), StartHeadPose()));
+  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), kStartHeadPose));
 }
 
 TEST(UiScene, InvisibleElementsDoNotCauseBindingDirtiness) {
@@ -219,12 +219,12 @@
                               element.get(), view->SetSize(1, value)));
   UiElement* element_ptr = element.get();
   scene.AddUiElement(kRoot, std::move(element));
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose));
 
   model.foo = 2;
   element_ptr->SetVisible(false);
   element_ptr->UpdateComputedOpacity();
-  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), StartHeadPose()));
+  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), kStartHeadPose));
 }
 
 TEST(UiScene, InvisibleElementsDoNotCauseOnBeginFrameDirtiness) {
@@ -232,11 +232,11 @@
   auto element = std::make_unique<AlwaysDirty>();
   UiElement* element_ptr = element.get();
   scene.AddUiElement(kRoot, std::move(element));
-  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), StartHeadPose()));
+  EXPECT_TRUE(scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose));
 
   element_ptr->SetVisible(false);
   element_ptr->UpdateComputedOpacity();
-  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), StartHeadPose()));
+  EXPECT_FALSE(scene.OnBeginFrame(gfx::MsToTicks(2), kStartHeadPose));
 }
 
 typedef struct {
@@ -271,7 +271,7 @@
   element->set_y_centering(GetParam().y_centering);
   parent->AddChild(std::move(element));
 
-  scene.OnBeginFrame(gfx::MsToTicks(0), StartHeadPose());
+  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
   EXPECT_NEAR(GetParam().expected_x, child->GetCenter().x(), TOLERANCE);
   EXPECT_NEAR(GetParam().expected_y, child->GetCenter().y(), TOLERANCE);
 }
diff --git a/chrome/browser/web_applications/commands/callback_command.cc b/chrome/browser/web_applications/commands/callback_command.cc
index 715d82f3..4c6b6a1 100644
--- a/chrome/browser/web_applications/commands/callback_command.cc
+++ b/chrome/browser/web_applications/commands/callback_command.cc
@@ -7,32 +7,53 @@
 #include <memory>
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/web_applications/locks/app_lock.h"
+#include "chrome/browser/web_applications/locks/full_system_lock.h"
 #include "chrome/browser/web_applications/locks/lock.h"
+#include "chrome/browser/web_applications/locks/noop_lock.h"
+#include "chrome/browser/web_applications/locks/shared_web_contents_lock.h"
+#include "chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h"
 
 namespace web_app {
 
-CallbackCommand::CallbackCommand(
-    std::unique_ptr<LockDescription> lock_description,
-    base::OnceClosure callback)
+template <class LockType, class DescriptionType>
+CallbackCommand<LockType, DescriptionType>::CallbackCommand(
+    std::unique_ptr<DescriptionType> lock_description,
+    base::OnceCallback<void(LockType& lock)> callback)
     : lock_description_(std::move(lock_description)),
       callback_(std::move(callback)) {
   DCHECK(lock_description_);
 }
 
-CallbackCommand::~CallbackCommand() = default;
+template <class LockType, class DescriptionType>
+CallbackCommand<LockType, DescriptionType>::~CallbackCommand() = default;
 
-void CallbackCommand::Start() {
-  return SignalCompletionAndSelfDestruct(CommandResult::kSuccess,
-                                         base::BindOnce(std::move(callback_)));
+template <class LockType, class DescriptionType>
+void CallbackCommand<LockType, DescriptionType>::StartWithLock(
+    std::unique_ptr<LockType> lock) {
+  lock_ = std::move(lock);
+  std::move(callback_).Run(*lock_.get());
+  return this->SignalCompletionAndSelfDestruct(CommandResult::kSuccess,
+                                               base::DoNothing());
 }
 
-LockDescription& CallbackCommand::lock_description() const {
+template <class LockType, class DescriptionType>
+LockDescription& CallbackCommand<LockType, DescriptionType>::lock_description()
+    const {
   return *lock_description_;
 }
 
-base::Value CallbackCommand::ToDebugValue() const {
-  return base::Value(base::StringPrintf("CallbackCommand %d", id()));
+template <class LockType, class DescriptionType>
+base::Value CallbackCommand<LockType, DescriptionType>::ToDebugValue() const {
+  return base::Value(base::StringPrintf("CallbackCommand %d", this->id()));
 }
+
+template class CallbackCommand<NoopLock>;
+template class CallbackCommand<SharedWebContentsLock>;
+template class CallbackCommand<AppLock>;
+template class CallbackCommand<SharedWebContentsWithAppLock>;
+template class CallbackCommand<FullSystemLock>;
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/commands/callback_command.h b/chrome/browser/web_applications/commands/callback_command.h
index 68a170c..6223b29 100644
--- a/chrome/browser/web_applications/commands/callback_command.h
+++ b/chrome/browser/web_applications/commands/callback_command.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMMANDS_CALLBACK_COMMAND_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMMANDS_CALLBACK_COMMAND_H_
 
+#include <memory>
 #include "base/callback.h"
 #include "chrome/browser/web_applications/commands/web_app_command.h"
 
@@ -15,13 +16,16 @@
 // CallbackCommand simply runs the callback being passed. This is handy for
 // small operations to web app system to avoid defining a new command class but
 // still providing isolation for the work done in the callback.
-class CallbackCommand : public WebAppCommand {
+template <typename LockType,
+          typename DescriptionType = typename LockType::LockDescription>
+class CallbackCommand : public WebAppCommandTemplate<LockType> {
  public:
-  CallbackCommand(std::unique_ptr<LockDescription> lock_description,
-                  base::OnceClosure callback);
+  CallbackCommand(std::unique_ptr<DescriptionType> lock_description,
+                  base::OnceCallback<void(LockType& lock)> callback);
+
   ~CallbackCommand() override;
 
-  void Start() override;
+  void StartWithLock(std::unique_ptr<LockType> lock) override;
 
   LockDescription& lock_description() const override;
 
@@ -31,8 +35,10 @@
   void OnShutdown() override {}
 
  private:
-  std::unique_ptr<LockDescription> lock_description_;
-  base::OnceClosure callback_;
+  std::unique_ptr<DescriptionType> lock_description_;
+  std::unique_ptr<LockType> lock_;
+
+  base::OnceCallback<void(LockType& lock)> callback_;
 };
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/commands/externally_managed_install_command_unittest.cc b/chrome/browser/web_applications/commands/externally_managed_install_command_unittest.cc
index deb54702..f5d8aae 100644
--- a/chrome/browser/web_applications/commands/externally_managed_install_command_unittest.cc
+++ b/chrome/browser/web_applications/commands/externally_managed_install_command_unittest.cc
@@ -281,15 +281,16 @@
       GenerateAppId(/*manifest_id=*/absl::nullopt, kWebAppUrl)};
 
   bool callback_command_run = false;
-  auto callback_command = std::make_unique<CallbackCommand>(
+  auto callback_command = std::make_unique<CallbackCommand<AppLock>>(
       std::make_unique<AppLockDescription>(app_ids),
-      base::BindLambdaForTesting([&]() { callback_command_run = true; }));
+      base::BindLambdaForTesting(
+          [&](AppLock&) { callback_command_run = true; }));
 
   bool callback_command_2_run = false;
   base::RunLoop callback_runloop;
-  auto callback_command_2 = std::make_unique<CallbackCommand>(
+  auto callback_command_2 = std::make_unique<CallbackCommand<AppLock>>(
       std::make_unique<AppLockDescription>(app_ids),
-      base::BindLambdaForTesting([&]() {
+      base::BindLambdaForTesting([&](AppLock&) {
         callback_command_2_run = true;
         callback_runloop.Quit();
       }));
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.cc
index 913e5e7..b2fea557 100644
--- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.cc
@@ -24,7 +24,10 @@
 #include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_command_scheduler.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
+#include "components/policy/core/common/policy_pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
 #include "components/webapps/browser/installable/installable_manager.h"
 #include "content/public/common/content_features.h"
@@ -125,28 +128,40 @@
 }
 
 base::expected<absl::optional<IsolationData>, std::string>
-GetIsolationDataFromCommandLine(const base::CommandLine& command_line) {
-  if (!base::FeatureList::IsEnabled(features::kIsolatedWebApps)) {
-    return absl::nullopt;
-  }
-
+GetIsolationDataFromCommandLine(const base::CommandLine& command_line,
+                                const PrefService* prefs) {
   base::expected<absl::optional<IsolationData>, std::string> proxy_url =
       GetProxyUrlFromCommandLine(command_line);
   base::expected<absl::optional<IsolationData>, std::string> bundle_path =
       GetBundlePathFromCommandLine(command_line);
 
-  // Return an error if both flags are set.
-  bool was_proxy_url_set = !proxy_url.has_value() || proxy_url->has_value();
-  bool was_bundle_path_set =
+  bool is_proxy_url_set = !proxy_url.has_value() || proxy_url->has_value();
+  bool is_bundle_path_set =
       !bundle_path.has_value() || bundle_path->has_value();
-  if (was_proxy_url_set && was_bundle_path_set) {
+  if (!is_proxy_url_set && !is_bundle_path_set) {
+    return absl::nullopt;
+  }
+
+  if (!base::FeatureList::IsEnabled(features::kIsolatedWebApps)) {
+    return base::unexpected("Isolated Web Apps are not enabled");
+  }
+
+  if (is_proxy_url_set && is_bundle_path_set) {
     return base::unexpected(
         base::StrCat({"--", switches::kInstallIsolatedWebAppFromUrl, " and --",
                       switches::kInstallIsolatedWebAppFromFile,
                       " cannot both be provided."}));
   }
 
-  return was_proxy_url_set ? proxy_url : bundle_path;
+  bool is_dev_mode_policy_enabled =
+      prefs && prefs->GetBoolean(
+                   policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed);
+  if (!base::FeatureList::IsEnabled(features::kIsolatedWebAppDevMode) ||
+      !is_dev_mode_policy_enabled) {
+    return base::unexpected("Isolated Web App Developer Mode is not enabled");
+  }
+
+  return is_proxy_url_set ? proxy_url : bundle_path;
 }
 
 void MaybeInstallAppFromCommandLine(const base::CommandLine& command_line,
@@ -161,7 +176,7 @@
   }
 
   base::expected<absl::optional<IsolationData>, std::string> isolation_data =
-      GetIsolationDataFromCommandLine(command_line);
+      GetIsolationDataFromCommandLine(command_line, profile.GetPrefs());
   if (!isolation_data.has_value()) {
     LOG(ERROR) << isolation_data.error();
     return;
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.h b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.h
index 6b09eb3..633d7d155 100644
--- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.h
+++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line.h
@@ -14,6 +14,7 @@
 class CommandLine;
 }
 
+class PrefService;
 class Profile;
 
 namespace web_app {
@@ -22,7 +23,8 @@
     const IsolationData& isolation_data);
 
 base::expected<absl::optional<IsolationData>, std::string>
-GetIsolationDataFromCommandLine(const base::CommandLine& command_line);
+GetIsolationDataFromCommandLine(const base::CommandLine& command_line,
+                                const PrefService* prefs);
 
 void MaybeInstallAppFromCommandLine(const base::CommandLine& command_line,
                                     Profile& profile);
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_browsertest.cc
index 6d50dd5..3f7f902 100644
--- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_browsertest.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
@@ -47,7 +48,8 @@
     : public InProcessBrowserTest {
  protected:
   void SetUp() override {
-    scoped_feature_list_.InitAndEnableFeature(features::kIsolatedWebApps);
+    scoped_feature_list_.InitWithFeatures(
+        {features::kIsolatedWebApps, features::kIsolatedWebAppDevMode}, {});
     InProcessBrowserTest::SetUp();
   }
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_unittest.cc
index 3e90182..5284b80 100644
--- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_from_command_line_unittest.cc
@@ -14,7 +14,12 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "base/values.h"
 #include "chrome/browser/web_applications/isolation_data.h"
+#include "chrome/common/chrome_features.h"
+#include "components/policy/core/common/policy_pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
 #include "content/public/common/content_features.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -135,10 +140,20 @@
 }
 
 class InstallIsolatedWebAppFromCommandLineFlagTest : public ::testing::Test {
- protected:
+ public:
+  InstallIsolatedWebAppFromCommandLineFlagTest() {
+    scoped_feature_list_.InitWithFeatures(
+        {features::kIsolatedWebApps, features::kIsolatedWebAppDevMode}, {});
+    pref_service_.registry()->RegisterBooleanPref(
+        policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed, true);
+  }
+
+  TestingPrefServiceSimple* pref_service() { return &pref_service_; }
+
+ private:
   base::test::SingleThreadTaskEnvironment task_environment_;
-  base::test::ScopedFeatureList scoped_feature_list_{
-      features::kIsolatedWebApps};
+  base::test::ScopedFeatureList scoped_feature_list_;
+  TestingPrefServiceSimple pref_service_;
 };
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
@@ -147,45 +162,78 @@
   scoped_feature_list.InitAndDisableFeature(features::kIsolatedWebApps);
 
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("http://example.com:12345", absl::nullopt)),
-              HasNoValue());
+                  CreateCommandLine("http://example.com:12345", absl::nullopt),
+                  pref_service()),
+              HasErrorWithSubstr("Isolated Web Apps are not enabled"));
+}
+
+TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
+       NoInstallationWhenDevModeFeatureDisabled) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(features::kIsolatedWebAppDevMode);
+
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine("http://example.com:12345", absl::nullopt),
+          pref_service()),
+      HasErrorWithSubstr("Isolated Web App Developer Mode is not enabled"));
+}
+
+TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
+       NoInstallationWhenDevModePolicyDisabled) {
+  pref_service()->SetManagedPref(
+      policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed,
+      base::Value(false));
+
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine("http://example.com:12345", absl::nullopt),
+          pref_service()),
+      HasErrorWithSubstr("Isolated Web App Developer Mode is not enabled"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        NoInstallationWhenProxyFlagAbsentAndBundleFlagAbsent) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine(absl::nullopt, absl::nullopt)),
-              HasNoValue());
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine(absl::nullopt, absl::nullopt), pref_service()),
+      HasNoValue());
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        NoInstallationWhenProxyFlagAbsentAndBundleFlagEmpty) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  absl::nullopt, base::FilePath::FromUTF8Unsafe(""))),
-              HasNoValue());
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine(absl::nullopt, base::FilePath::FromUTF8Unsafe("")),
+          pref_service()),
+      HasNoValue());
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagAbsentAndBundleFlagInvalid) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  absl::nullopt,
-                  base::FilePath::FromUTF8Unsafe("does_not_exist.wbn)"))),
-              HasErrorWithSubstr("Invalid path provided"));
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine(absl::nullopt, base::FilePath::FromUTF8Unsafe(
+                                               "does_not_exist.wbn)")),
+          pref_service()),
+      HasErrorWithSubstr("Invalid path provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagAbsentAndBundleFlagIsDirectory) {
   ScopedWorkingDirectoryWithFile cwd;
-  EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine(absl::nullopt, cwd.directory())),
-              HasErrorWithSubstr("Invalid path provided"));
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine(absl::nullopt, cwd.directory()), pref_service()),
+      HasErrorWithSubstr("Invalid path provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        InstallsAppWhenProxyFlagAbsentAndBundleFlagValid) {
   ScopedWorkingDirectoryWithFile cwd;
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine(absl::nullopt, cwd.existing_file_name())),
+                  CreateCommandLine(absl::nullopt, cwd.existing_file_name()),
+                  pref_service()),
               IsDevModeBundle(cwd.existing_file_path()));
 }
 
@@ -193,111 +241,129 @@
        InstallsAppWhenProxyFlagAbsentAndBundleFlagValidAndAbsolute) {
   ScopedWorkingDirectoryWithFile cwd;
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine(absl::nullopt, cwd.existing_file_path())),
+                  CreateCommandLine(absl::nullopt, cwd.existing_file_path()),
+                  pref_service()),
               IsDevModeBundle(cwd.existing_file_path()));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        NoInstallationWhenProxyFlagEmptyAndBundleFlagAbsent) {
-  EXPECT_THAT(
-      GetIsolationDataFromCommandLine(CreateCommandLine("", absl::nullopt)),
-      HasNoValue());
+  EXPECT_THAT(GetIsolationDataFromCommandLine(
+                  CreateCommandLine("", absl::nullopt), pref_service()),
+              HasNoValue());
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        NoInstallationWhenProxyFlagEmptyAndBundleFlagEmpty) {
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("", base::FilePath::FromUTF8Unsafe(""))),
+                  CreateCommandLine("", base::FilePath::FromUTF8Unsafe("")),
+                  pref_service()),
               HasNoValue());
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagEmptyAndBundleFlagInvalid) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  "", base::FilePath::FromUTF8Unsafe("does_not_exist.wbn"))),
+  EXPECT_THAT(GetIsolationDataFromCommandLine(
+                  CreateCommandLine(
+                      "", base::FilePath::FromUTF8Unsafe("does_not_exist.wbn")),
+                  pref_service()),
               HasErrorWithSubstr("Invalid path provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        InstallsAppWhenProxyFlagEmptyAndBundleFlagValid) {
   ScopedWorkingDirectoryWithFile cwd;
-  EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("", cwd.existing_file_name())),
-              IsDevModeBundle(cwd.existing_file_path()));
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine("", cwd.existing_file_name()), pref_service()),
+      IsDevModeBundle(cwd.existing_file_path()));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagInvalidAndBundleFlagAbsent) {
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("invalid", absl::nullopt)),
+                  CreateCommandLine("invalid", absl::nullopt), pref_service()),
               HasErrorWithSubstr("Invalid URL"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagInvalidAndBundleFlagEmpty) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  "invalid", base::FilePath::FromUTF8Unsafe(""))),
-              HasErrorWithSubstr("Invalid URL"));
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine("invalid", base::FilePath::FromUTF8Unsafe("")),
+          pref_service()),
+      HasErrorWithSubstr("Invalid URL"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagInvalidAndBundleFlagInvalid) {
-  EXPECT_THAT(
-      GetIsolationDataFromCommandLine(CreateCommandLine(
-          "invalid", base::FilePath::FromUTF8Unsafe("does_not_exist.wbn"))),
-      HasErrorWithSubstr("cannot both be provided"));
+  EXPECT_THAT(GetIsolationDataFromCommandLine(
+                  CreateCommandLine("invalid", base::FilePath::FromUTF8Unsafe(
+                                                   "does_not_exist.wbn")),
+                  pref_service()),
+              HasErrorWithSubstr("cannot both be provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagInvalidAndBundleFlagValid) {
   ScopedWorkingDirectoryWithFile cwd;
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("invalid", cwd.existing_file_name())),
+                  CreateCommandLine("invalid", cwd.existing_file_name()),
+                  pref_service()),
               HasErrorWithSubstr("cannot both be provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        InstallsAppWhenProxyFlagValidAndBundleFlagAbsent) {
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("http://example.com", absl::nullopt)),
+                  CreateCommandLine("http://example.com", absl::nullopt),
+                  pref_service()),
               IsDevModeProxy("http://example.com"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        InstallsAppWhenProxyFlagWithPortValidAndBundleFlagAbsent) {
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("http://example.com:12345", absl::nullopt)),
+                  CreateCommandLine("http://example.com:12345", absl::nullopt),
+                  pref_service()),
               IsDevModeProxy("http://example.com:12345"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagHasPathAndBundleFlagInValid) {
   EXPECT_THAT(GetIsolationDataFromCommandLine(
-                  CreateCommandLine("http://example.com/path", absl::nullopt)),
+                  CreateCommandLine("http://example.com/path", absl::nullopt),
+                  pref_service()),
               HasErrorWithSubstr("Non-origin URL provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        InstallsAppWhenProxyFlagValidAndBundleFlagEmpty) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  "http://example.com", base::FilePath::FromUTF8Unsafe(""))),
+  EXPECT_THAT(GetIsolationDataFromCommandLine(
+                  CreateCommandLine("http://example.com",
+                                    base::FilePath::FromUTF8Unsafe("")),
+                  pref_service()),
               IsDevModeProxy("http://example.com"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagValidAndBundleFlagInvalid) {
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  "http://example.com",
-                  base::FilePath::FromUTF8Unsafe("does_not_exist.wbn"))),
+  EXPECT_THAT(GetIsolationDataFromCommandLine(
+                  CreateCommandLine(
+                      "http://example.com",
+                      base::FilePath::FromUTF8Unsafe("does_not_exist.wbn")),
+                  pref_service()),
               HasErrorWithSubstr("cannot both be provided"));
 }
 
 TEST_F(InstallIsolatedWebAppFromCommandLineFlagTest,
        ErrorWhenProxyFlagValidAndBundleFlagValid) {
   ScopedWorkingDirectoryWithFile cwd;
-  EXPECT_THAT(GetIsolationDataFromCommandLine(CreateCommandLine(
-                  "http://example.com", cwd.existing_file_name())),
-              HasErrorWithSubstr("cannot both be provided"));
+  EXPECT_THAT(
+      GetIsolationDataFromCommandLine(
+          CreateCommandLine("http://example.com", cwd.existing_file_name()),
+          pref_service()),
+      HasErrorWithSubstr("cannot both be provided"));
 }
 
 class InstallIsolatedWebAppFromCommandLineIsolationInfoTest
diff --git a/chrome/browser/web_applications/locks/app_lock.h b/chrome/browser/web_applications/locks/app_lock.h
index 13c3ef2c..ffe1717f 100644
--- a/chrome/browser/web_applications/locks/app_lock.h
+++ b/chrome/browser/web_applications/locks/app_lock.h
@@ -35,6 +35,8 @@
 
 class AppLock {
  public:
+  using LockDescription = AppLockDescription;
+
   AppLock(WebAppRegistrar& registrar,
           WebAppSyncBridge& sync_bridge,
           WebAppInstallFinalizer& install_finalizer,
diff --git a/chrome/browser/web_applications/locks/full_system_lock.h b/chrome/browser/web_applications/locks/full_system_lock.h
index 30eca5b..bf94a90 100644
--- a/chrome/browser/web_applications/locks/full_system_lock.h
+++ b/chrome/browser/web_applications/locks/full_system_lock.h
@@ -34,6 +34,8 @@
 
 class FullSystemLock : public AppLock {
  public:
+  using LockDescription = FullSystemLockDescription;
+
   FullSystemLock(WebAppRegistrar& registrar,
                  WebAppSyncBridge& sync_bridge,
                  WebAppInstallFinalizer& install_finalizer,
diff --git a/chrome/browser/web_applications/locks/noop_lock.h b/chrome/browser/web_applications/locks/noop_lock.h
index 57b94cb..da787add 100644
--- a/chrome/browser/web_applications/locks/noop_lock.h
+++ b/chrome/browser/web_applications/locks/noop_lock.h
@@ -24,6 +24,8 @@
 
 class NoopLock {
  public:
+  using LockDescription = NoopLockDescription;
+
   NoopLock() = default;
   ~NoopLock() = default;
 };
diff --git a/chrome/browser/web_applications/locks/shared_web_contents_lock.h b/chrome/browser/web_applications/locks/shared_web_contents_lock.h
index a5d6c40c..1a795e2 100644
--- a/chrome/browser/web_applications/locks/shared_web_contents_lock.h
+++ b/chrome/browser/web_applications/locks/shared_web_contents_lock.h
@@ -30,6 +30,8 @@
 
 class SharedWebContentsLock {
  public:
+  using LockDescription = SharedWebContentsLockDescription;
+
   explicit SharedWebContentsLock(content::WebContents& shared_web_contents);
   ~SharedWebContentsLock();
 
diff --git a/chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h b/chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h
index 5d90f8ab..2d16c1c 100644
--- a/chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h
+++ b/chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h
@@ -44,6 +44,8 @@
 class SharedWebContentsWithAppLock : public SharedWebContentsLock,
                                      public AppLock {
  public:
+  using LockDescription = SharedWebContentsWithAppLockDescription;
+
   SharedWebContentsWithAppLock(content::WebContents& shared_web_contents,
                                WebAppRegistrar& registrar,
                                WebAppSyncBridge& sync_bridge,
diff --git a/chrome/browser/web_applications/web_app_command_manager_unittest.cc b/chrome/browser/web_applications/web_app_command_manager_unittest.cc
index 3b786a0..5794b8e 100644
--- a/chrome/browser/web_applications/web_app_command_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_command_manager_unittest.cc
@@ -476,12 +476,11 @@
         loop.Quit();
       }));
   for (auto* app_id : {kTestAppId, kTestAppId2}) {
-    base::OnceClosure callback = base::BindOnce(
-        [](AppId app_id, base::RepeatingCallback<void(std::string)> barrier) {
-          barrier.Run(app_id);
-        },
+    base::OnceCallback<void(AppLock&)> callback = base::BindOnce(
+        [](AppId app_id, base::RepeatingCallback<void(std::string)> barrier,
+           AppLock&) { barrier.Run(app_id); },
         app_id, barrier);
-    manager().ScheduleCommand(std::make_unique<CallbackCommand>(
+    manager().ScheduleCommand(std::make_unique<CallbackCommand<AppLock>>(
         std::make_unique<AppLockDescription, base::flat_set<AppId>>({app_id}),
         std::move(callback)));
   }
@@ -553,10 +552,10 @@
 
 TEST_F(WebAppCommandManagerTest, ToDebugValue) {
   base::RunLoop loop;
-  manager().ScheduleCommand(std::make_unique<CallbackCommand>(
+  manager().ScheduleCommand(std::make_unique<CallbackCommand<AppLock>>(
       std::make_unique<AppLockDescription, base::flat_set<AppId>>({kTestAppId}),
-      base::BindLambdaForTesting([&]() { loop.Quit(); })));
-  manager().ScheduleCommand(std::make_unique<CallbackCommand>(
+      base::BindLambdaForTesting([&](AppLock&) { loop.Quit(); })));
+  manager().ScheduleCommand(std::make_unique<CallbackCommand<AppLock>>(
       std::make_unique<AppLockDescription, base::flat_set<AppId>>(
           {kTestAppId2}),
       base::DoNothing()));
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.cc b/chrome/browser/web_applications/web_app_command_scheduler.cc
index fa9080c..337e9ef 100644
--- a/chrome/browser/web_applications/web_app_command_scheduler.cc
+++ b/chrome/browser/web_applications/web_app_command_scheduler.cc
@@ -6,6 +6,7 @@
 
 #include "base/functional/bind.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/commands/callback_command.h"
 #include "chrome/browser/web_applications/commands/fetch_installability_for_chrome_management.h"
 #include "chrome/browser/web_applications/commands/fetch_manifest_and_install_command.h"
 #include "chrome/browser/web_applications/commands/manifest_update_data_fetch_command.h"
@@ -14,6 +15,11 @@
 #include "chrome/browser/web_applications/commands/update_file_handler_command.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/isolation_data.h"
+#include "chrome/browser/web_applications/locks/app_lock.h"
+#include "chrome/browser/web_applications/locks/full_system_lock.h"
+#include "chrome/browser/web_applications/locks/noop_lock.h"
+#include "chrome/browser/web_applications/locks/shared_web_contents_lock.h"
+#include "chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h"
 #include "chrome/browser/web_applications/manifest_update_manager.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_command_scheduler.h"
@@ -247,6 +253,51 @@
       RunOnOsLoginCommand::CreateForSyncLoginMode(app_id, std::move(callback)));
 }
 
+template <class LockType, class DescriptionType>
+void WebAppCommandScheduler::ScheduleCallbackWithLock(
+    std::unique_ptr<DescriptionType> lock_description,
+    base::OnceCallback<void(LockType& lock)> callback) {
+  if (is_in_shutdown_)
+    return;
+
+  if (!provider_->is_registry_ready()) {
+    provider_->on_registry_ready().Post(
+        FROM_HERE,
+        base::BindOnce(
+            &WebAppCommandScheduler::ScheduleCallbackWithLock<LockType>,
+            weak_ptr_factory_.GetWeakPtr(), std::move(lock_description),
+            std::move(callback)));
+    return;
+  }
+
+  provider_->command_manager().ScheduleCommand(
+      std::make_unique<CallbackCommand<LockType>>(std::move(lock_description),
+                                                  std::move(callback)));
+}
+
+template void WebAppCommandScheduler::ScheduleCallbackWithLock<NoopLock>(
+    std::unique_ptr<NoopLock::LockDescription> lock_description,
+    base::OnceCallback<void(NoopLock& lock)> callback);
+
+template void
+WebAppCommandScheduler::ScheduleCallbackWithLock<SharedWebContentsLock>(
+    std::unique_ptr<SharedWebContentsLock::LockDescription> lock_description,
+    base::OnceCallback<void(SharedWebContentsLock& lock)> callback);
+
+template void WebAppCommandScheduler::ScheduleCallbackWithLock<AppLock>(
+    std::unique_ptr<AppLock::LockDescription> lock_description,
+    base::OnceCallback<void(AppLock& lock)> callback);
+
+template void
+WebAppCommandScheduler::ScheduleCallbackWithLock<SharedWebContentsWithAppLock>(
+    std::unique_ptr<SharedWebContentsWithAppLock::LockDescription>
+        lock_description,
+    base::OnceCallback<void(SharedWebContentsWithAppLock& lock)> callback);
+
+template void WebAppCommandScheduler::ScheduleCallbackWithLock<FullSystemLock>(
+    std::unique_ptr<FullSystemLock::LockDescription> lock_description,
+    base::OnceCallback<void(FullSystemLock& lock)> callback);
+
 void WebAppCommandScheduler::Shutdown() {
   is_in_shutdown_ = true;
 }
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.h b/chrome/browser/web_applications/web_app_command_scheduler.h
index 6474e91d..66f9689 100644
--- a/chrome/browser/web_applications/web_app_command_scheduler.h
+++ b/chrome/browser/web_applications/web_app_command_scheduler.h
@@ -107,6 +107,14 @@
   // OS.
   void SyncRunOnOsLoginMode(const AppId& app_id, base::OnceClosure callback);
 
+  // Schedules provided callback after `lock` is granted. The callback can
+  // access web app resources through the `lock`.
+  template <typename LockType,
+            typename DescriptionType = typename LockType::LockDescription>
+  void ScheduleCallbackWithLock(
+      std::unique_ptr<DescriptionType> lock_description,
+      base::OnceCallback<void(LockType& lock)> callback);
+
   // TODO(https://crbug.com/1298130): expose all commands for web app
   // operations.
 
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index b37aef5..e85233f 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1668578082-b0eee736161271db0f75641695c07f9dcdf42317.profdata
+chrome-linux-main-1668621564-322878ac0abb2e153a23bf69b2797296c1463dcc.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 3a2c81382..e7f29a4 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1668578082-c2361f5132c4d28de2c0da43aa0350aa9892f9a5.profdata
+chrome-mac-arm-main-1668621564-5654323d688c653147295c4b69d67cc52664a1ee.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index fb9c763d..9a6cc10 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1668578082-3fca691b150d93719c04306c28ec808cc1820840.profdata
+chrome-mac-main-1668642856-82c7bf1edee3d29b4b2b2bfb72eb10edfa0a67d2.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 7d2958f..d219b82 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1668588915-78c9a318566b6154d0cca34c7b1985a95b534579.profdata
+chrome-win32-main-1668621564-943e4f2fde178f3fd8c4c0c60abe98f828a61732.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 723881a..03ce471 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1668588915-793b67747d63c8c1a1cf8850175e637871ff83c8.profdata
+chrome-win64-main-1668621564-4d23e9fedf7d7da342fc24475537f6d790792f1a.profdata
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json
index ccfa3d3..e98e49bf 100644
--- a/chrome/common/extensions/api/accessibility_private.json
+++ b/chrome/common/extensions/api/accessibility_private.json
@@ -568,6 +568,12 @@
             "name": "keyEvent",
             "$ref": "SyntheticKeyboardEvent",
             "description": "The event to send."
+          },
+          {
+            "name": "useRewriters",
+            "type": "boolean",
+            "description": "If true, uses rewriters for the key event; only allowed if used from Dictation. Otherwise indicates that rewriters should be skipped.",
+            "optional": true
           }
         ]
       },
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl
index c8518fff..aa904a46 100644
--- a/chrome/common/extensions/api/autotest_private.idl
+++ b/chrome/common/extensions/api/autotest_private.idl
@@ -652,6 +652,19 @@
 
   callback GetShelfUIInfoForStateCallback = void (ShelfUIInfo info);
 
+  // Frame counting record for one frame sink/compositor.
+  dictionary FrameCountingPerSinkData {
+    // Type of the frame sink. This corresponds to CompositorFrameSinkType.
+    DOMString sinkType;
+    // Whether the frame sink is the root.
+    boolean isRoot;
+
+    // Number of presented frames grouped by seconds, i.e. fps.
+    long[] presentedFrames;
+  };
+
+  callback StopFrameCountingCallback = void (FrameCountingPerSinkData[] data);
+
   // Result of calling setWindowBounds, which returns the actual bounds and
   // display the window was set to. This may be different than the requested
   // bounds and display, for example if the window is showing an ARC app and
@@ -1509,6 +1522,16 @@
     // Remove the specified component extension.
     [supportsPromises] static void removeComponentExtension(
         DOMString extensionId, VoidCallback callback);
+
+    // Starts frame counting in viz. `bucketSizeInSeconds` decides the bucket
+    // size of the frame count records. If it is X seconds, each record is
+    // the number of presented frames in X seconds.
+    [supportsPromises] static void startFrameCounting(long bucketSizeInSeconds,
+        VoidCallback callback);
+
+    // Ends frame counting in viz and return the collected data.
+    [supportsPromises] static void stopFrameCounting(
+        StopFrameCountingCallback  callback);
   };
 
   interface Events {
diff --git a/chrome/credential_provider/gaiacp/event_logs_upload_manager.cc b/chrome/credential_provider/gaiacp/event_logs_upload_manager.cc
index fe36a769..4a4e919 100644
--- a/chrome/credential_provider/gaiacp/event_logs_upload_manager.cc
+++ b/chrome/credential_provider/gaiacp/event_logs_upload_manager.cc
@@ -458,8 +458,7 @@
     }
   }
 
-  if (log_entry_value_list &&
-      log_entry_value_list->GetListDeprecated().size() > 0) {
+  if (log_entry_value_list && !log_entry_value_list->GetList().empty()) {
     upload_status_ = MakeUploadLogChunkRequest(access_token, chunk_id,
                                                std::move(log_entry_value_list));
     if (FAILED(upload_status_)) {
@@ -488,8 +487,7 @@
     return hr;
   }
 
-  size_t num_events_to_upload =
-      log_entries_value_list->GetListDeprecated().size();
+  size_t num_events_to_upload = log_entries_value_list->GetList().size();
 
   base::Value request_dict(base::Value::Type::DICTIONARY);
   request_dict.SetStringKey(kRequestSerialNumberParameterName,
diff --git a/chrome/credential_provider/gaiacp/experiments_manager.cc b/chrome/credential_provider/gaiacp/experiments_manager.cc
index ec6c889f..d7947a3 100644
--- a/chrome/credential_provider/gaiacp/experiments_manager.cc
+++ b/chrome/credential_provider/gaiacp/experiments_manager.cc
@@ -87,7 +87,7 @@
   }
 
   if (experiments_value->is_list()) {
-    for (const auto& item : experiments_value->GetListDeprecated()) {
+    for (const auto& item : experiments_value->GetList()) {
       auto* f = item.FindStringKey(kResponseFeatureKeyName);
       auto* v = item.FindStringKey(kResponseValueKeyName);
       if (!f || !v) {
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
index ad57eac..52801c7 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
@@ -3479,7 +3479,7 @@
 
   std::vector<std::string> actual_mac_address_list;
   for (const base::Value& value :
-       request_dict.FindKey("wlan_mac_addr")->GetListDeprecated()) {
+       request_dict.FindKey("wlan_mac_addr")->GetList()) {
     ASSERT_TRUE(value.is_string());
     actual_mac_address_list.push_back(value.GetString());
   }
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc
index 09fa894..85fb7c00 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -1017,7 +1017,7 @@
 
   auto* value = json_obj->FindListPath(base::JoinString(path, "."));
   if (value && value->is_list()) {
-    for (const base::Value& entry : value->GetListDeprecated()) {
+    for (const base::Value& entry : value->GetList()) {
       if (entry.FindKey(list_key) && entry.FindKey(list_key)->is_string()) {
         output->push_back(entry.FindKey(list_key)->GetString());
       } else {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 627ee001..5a86bc5 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -77,6 +77,7 @@
       "//chrome/browser/feedback/android:java",
       "//chrome/browser/profiles/android:java",
       "//components/autofill/android:autofill_java",
+      "//components/metrics:metrics_java",
       "//components/payments/content/android:java",
       "//components/payments/mojom:mojom_java",
       "//content/public/android:content_java",
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js
index 00c309a..607f12a3 100644
--- a/chrome/test/data/extensions/api_test/autotest_private/test.js
+++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -1105,6 +1105,29 @@
     });
   },
 
+  function collectFrameCountingData() {
+    promisify(
+        chrome.autotestPrivate.startFrameCounting, /*bucketSizeInSeconds=*/1)
+        .then(function() {
+          // Minimize/restore to trigger screen updates.
+          return promisify(minimizeBrowserWindow);
+        })
+        .then(function() {
+          return promisify(unminimizeBrowserWindow);
+        })
+        .then(function() {
+          return promisify(
+              chrome.autotestPrivate.stopFrameCounting);
+        })
+        .then(function(data) {
+          chrome.test.assertTrue(data.length >= 0);
+          chrome.test.succeed();
+        })
+        .catch(function(err) {
+          chrome.test.fail(err);
+        });
+  },
+
   // KEEP |lockScreen()| TESTS AT THE BOTTOM OF THE defaultTests AS IT WILL
   // CHANGE THE SESSION STATE TO LOCKED STATE.
   function lockScreen() {
diff --git a/chrome/test/data/pdf/annotations_feature_enabled_test.ts b/chrome/test/data/pdf/annotations_feature_enabled_test.ts
index 15ac559..2363cff 100644
--- a/chrome/test/data/pdf/annotations_feature_enabled_test.ts
+++ b/chrome/test/data/pdf/annotations_feature_enabled_test.ts
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import {AnnotationTool, SaveRequestType, ViewerInkHostElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {waitFor} from './test_util.js';
@@ -450,6 +451,7 @@
   async function testSaveAfterAnnotationMode() {
     const saveData = await viewer.getCurrentControllerForTesting()!.save(
         SaveRequestType.EDITED);
+    assert(saveData);
     chrome.test.assertTrue(saveData.editModeForTesting!);
     chrome.test.succeed();
   },
diff --git a/chrome/test/data/webui/extensions/code_section_test.ts b/chrome/test/data/webui/extensions/code_section_test.ts
index 635830d..3f0cf950 100644
--- a/chrome/test/data/webui/extensions/code_section_test.ts
+++ b/chrome/test/data/webui/extensions/code_section_test.ts
@@ -6,7 +6,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsCodeSectionElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible} from 'chrome://webui-test/test_util.js';
 
@@ -34,7 +33,7 @@
     document.body.appendChild(codeSection);
   });
 
-  test(assert(extension_code_section_tests.TestNames.Layout), function() {
+  test(extension_code_section_tests.TestNames.Layout, function() {
     const code: chrome.developerPrivate.RequestFileSourceResponse = {
       beforeHighlight: 'this part before the highlight\nAnd this too\n',
       highlight: 'highlight this part\n',
@@ -70,7 +69,7 @@
                 '#line-numbers span')!.textContent!.trim());
   });
 
-  test(assert(extension_code_section_tests.TestNames.LongSource), function() {
+  test(extension_code_section_tests.TestNames.LongSource, function() {
     let lineNums;
 
     function setCodeContent(beforeLineCount: number, afterLineCount: number):
diff --git a/chrome/test/data/webui/extensions/detail_view_test.ts b/chrome/test/data/webui/extensions/detail_view_test.ts
index 51a391cb..239db459 100644
--- a/chrome/test/data/webui/extensions/detail_view_test.ts
+++ b/chrome/test/data/webui/extensions/detail_view_test.ts
@@ -5,10 +5,8 @@
 /** @fileoverview Suite of tests for extensions-detail-view. */
 
 import {CrCheckboxElement, ExtensionsDetailViewElement, ExtensionsToggleRowElement, navigation, Page} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible, isVisible} from 'chrome://webui-test/test_util.js';
 
@@ -61,7 +59,7 @@
     document.body.appendChild(item);
   });
 
-  test(assert(extension_detail_view_tests.TestNames.Layout), function() {
+  test(extension_detail_view_tests.TestNames.Layout, function() {
     flush();
 
     const testIsVisible: (selector: string) => boolean =
@@ -242,7 +240,7 @@
     assertTrue(testIsVisible('extensions-host-permissions-toggle-list'));
   });
 
-  test(assert(extension_detail_view_tests.TestNames.LayoutSource), function() {
+  test(extension_detail_view_tests.TestNames.LayoutSource, function() {
     item.set('data.location', 'FROM_STORE');
     flush();
     assertEquals('Chrome Web Store', item.$.source.textContent!.trim());
@@ -275,8 +273,7 @@
   });
 
   test(
-      assert(
-          extension_detail_view_tests.TestNames.SupervisedUserDisableReasons),
+      extension_detail_view_tests.TestNames.SupervisedUserDisableReasons,
       function() {
         flush();
         const toggle = item.$.enableToggle;
@@ -311,8 +308,7 @@
       });
 
   test(
-      assert(extension_detail_view_tests.TestNames.ClickableElements),
-      function() {
+      extension_detail_view_tests.TestNames.ClickableElements, function() {
         const optionsUrl =
             'chrome-extension://' + extensionData.id + '/options.html';
         item.set('data.optionsPage', {openInTab: true, url: optionsUrl});
@@ -377,7 +373,7 @@
             'reloadItem', [extensionData.id], Promise.resolve());
       });
 
-  test(assert(extension_detail_view_tests.TestNames.Indicator), function() {
+  test(extension_detail_view_tests.TestNames.Indicator, function() {
     const indicator = item.shadowRoot!.querySelector('cr-tooltip-icon')!;
     assertTrue(indicator.hidden);
     item.set('data.controlledInfo', {text: 'policy'});
@@ -385,7 +381,7 @@
     assertFalse(indicator.hidden);
   });
 
-  test(assert(extension_detail_view_tests.TestNames.Warnings), function() {
+  test(extension_detail_view_tests.TestNames.Warnings, function() {
     function testWarningVisible(id: string, expectVisible: boolean): void {
       const f: (arg: boolean) => void =
           expectVisible ? assertTrue : assertFalse;
@@ -491,8 +487,8 @@
   });
 
   test(
-      assert(extension_detail_view_tests.TestNames
-                 .NoSiteAccessWithEnhancedSiteControls),
+      extension_detail_view_tests.TestNames
+          .NoSiteAccessWithEnhancedSiteControls,
       function() {
         const testIsVisible = isChildVisible.bind(null, item);
 
@@ -529,7 +525,7 @@
       });
 
   test(
-      assert(extension_detail_view_tests.TestNames.InspectableViewSortOrder),
+      extension_detail_view_tests.TestNames.InspectableViewSortOrder,
       function() {
         function getUrl(path: string) {
           return `chrome-extension://${extensionData.id}/${path}`;
@@ -564,7 +560,7 @@
       });
 
   test(
-      assert(extension_detail_view_tests.TestNames.ShowAccessRequestsInToolbar),
+      extension_detail_view_tests.TestNames.ShowAccessRequestsInToolbar,
       function() {
         const testIsVisible = isChildVisible.bind(null, item);
 
diff --git a/chrome/test/data/webui/extensions/error_page_test.ts b/chrome/test/data/webui/extensions/error_page_test.ts
index be3dd93..65993f8 100644
--- a/chrome/test/data/webui/extensions/error_page_test.ts
+++ b/chrome/test/data/webui/extensions/error_page_test.ts
@@ -6,10 +6,8 @@
 import 'chrome://extensions/extensions.js';
 
 import {ErrorPageDelegate, ExtensionsErrorPageElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible} from 'chrome://webui-test/test_util.js';
 
@@ -95,7 +93,7 @@
     document.body.appendChild(errorPage);
   });
 
-  test(assert(extension_error_page_tests.TestNames.Layout), function() {
+  test(extension_error_page_tests.TestNames.Layout, function() {
     flush();
 
     const testIsVisible = isChildVisible.bind(null, errorPage);
@@ -137,7 +135,7 @@
   });
 
   test(
-      assert(extension_error_page_tests.TestNames.CodeSection), function(done) {
+      extension_error_page_tests.TestNames.CodeSection, function(done) {
         flush();
 
         assertTrue(!!mockDelegate.requestFileSourceArgs);
@@ -165,7 +163,7 @@
         });
       });
 
-  test(assert(extension_error_page_tests.TestNames.ErrorSelection), function() {
+  test(extension_error_page_tests.TestNames.ErrorSelection, function() {
     const nextRuntimeError = Object.assign(
         {
           source: 'chrome-extension://' + extensionId + '/other_source.html',
diff --git a/chrome/test/data/webui/extensions/item_list_test.ts b/chrome/test/data/webui/extensions/item_list_test.ts
index 8ae68f6..3cbf0f8 100644
--- a/chrome/test/data/webui/extensions/item_list_test.ts
+++ b/chrome/test/data/webui/extensions/item_list_test.ts
@@ -6,10 +6,10 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsItemListElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+
 import {createExtensionInfo, testVisible} from './test_util.js';
 
 const extension_item_list_tests = {
@@ -50,7 +50,7 @@
     document.body.appendChild(itemList);
   });
 
-  test(assert(extension_item_list_tests.TestNames.Filtering), function() {
+  test(extension_item_list_tests.TestNames.Filtering, function() {
     function itemLengthEquals(num: number) {
       flush();
       assertEquals(
@@ -102,7 +102,7 @@
         itemList.shadowRoot!.querySelector('extensions-item')!.data.name);
   });
 
-  test(assert(extension_item_list_tests.TestNames.NoItemsMsg), function() {
+  test(extension_item_list_tests.TestNames.NoItemsMsg, function() {
     flush();
     boundTestVisible('#no-items', false);
     boundTestVisible('#no-search-results', false);
@@ -114,20 +114,18 @@
     boundTestVisible('#no-search-results', false);
   });
 
-  test(
-      assert(extension_item_list_tests.TestNames.NoSearchResultsMsg),
-      function() {
-        flush();
-        boundTestVisible('#no-items', false);
-        boundTestVisible('#no-search-results', false);
+  test(extension_item_list_tests.TestNames.NoSearchResultsMsg, function() {
+    flush();
+    boundTestVisible('#no-items', false);
+    boundTestVisible('#no-search-results', false);
 
-        itemList.filter = 'non-existent name';
-        flush();
-        boundTestVisible('#no-items', false);
-        boundTestVisible('#no-search-results', true);
-      });
+    itemList.filter = 'non-existent name';
+    flush();
+    boundTestVisible('#no-items', false);
+    boundTestVisible('#no-search-results', true);
+  });
 
-  test(assert(extension_item_list_tests.TestNames.LoadTimeData), function() {
+  test(extension_item_list_tests.TestNames.LoadTimeData, function() {
     // Check that loadTimeData contains these values.
     loadTimeData.getBoolean('isManaged');
     loadTimeData.getString('browserManagedByOrg');
diff --git a/chrome/test/data/webui/extensions/item_test.ts b/chrome/test/data/webui/extensions/item_test.ts
index 0aa05ad..51a738e 100644
--- a/chrome/test/data/webui/extensions/item_test.ts
+++ b/chrome/test/data/webui/extensions/item_test.ts
@@ -5,7 +5,6 @@
 /** @fileoverview Suite of tests for extension-item. */
 
 import {ExtensionsItemElement, IronIconElement, navigation, Page} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible} from 'chrome://webui-test/test_util.js';
@@ -107,21 +106,19 @@
     document.body.appendChild(toastManager);
   });
 
-  test(
-      assert(extension_item_tests.TestNames.ElementVisibilityNormalState),
-      function() {
-        testNormalElementsAreVisible(item);
-        testDeveloperElementsAreHidden(item);
+  test(extension_item_tests.TestNames.ElementVisibilityNormalState, function() {
+    testNormalElementsAreVisible(item);
+    testDeveloperElementsAreHidden(item);
 
-        assertTrue(item.$.enableToggle.checked);
-        item.set('data.state', 'DISABLED');
-        assertFalse(item.$.enableToggle.checked);
-        item.set('data.state', 'BLACKLISTED');
-        assertFalse(item.$.enableToggle.checked);
-      });
+    assertTrue(item.$.enableToggle.checked);
+    item.set('data.state', 'DISABLED');
+    assertFalse(item.$.enableToggle.checked);
+    item.set('data.state', 'BLACKLISTED');
+    assertFalse(item.$.enableToggle.checked);
+  });
 
   test(
-      assert(extension_item_tests.TestNames.ElementVisibilityDeveloperState),
+      extension_item_tests.TestNames.ElementVisibilityDeveloperState,
       function() {
         item.set('inDevMode', true);
 
@@ -154,7 +151,7 @@
       });
 
   /** Tests that the delegate methods are correctly called. */
-  test(assert(extension_item_tests.TestNames.ClickableItems), function() {
+  test(extension_item_tests.TestNames.ClickableItems, function() {
     item.set('inDevMode', true);
 
     mockDelegate.testClickingCalls(
@@ -208,7 +205,7 @@
 
   /** Tests that the reload button properly fires the load-error event. */
   test(
-      assert(extension_item_tests.TestNames.FailedReloadFiresLoadError),
+      extension_item_tests.TestNames.FailedReloadFiresLoadError,
       async function() {
         item.set('inDevMode', true);
         item.set('data.location', chrome.developerPrivate.Location.UNPACKED);
@@ -252,7 +249,7 @@
         return verifyEventPromise(true);
       });
 
-  test(assert(extension_item_tests.TestNames.Warnings), function() {
+  test(extension_item_tests.TestNames.Warnings, function() {
     const kCorrupt = 1 << 0;
     const kSuspicious = 1 << 1;
     const kBlacklisted = 1 << 2;
@@ -313,7 +310,7 @@
     assertWarnings(kSuspicious);
   });
 
-  test(assert(extension_item_tests.TestNames.SourceIndicator), function() {
+  test(extension_item_tests.TestNames.SourceIndicator, function() {
     assertFalse(isChildVisible(item, '#source-indicator'));
     item.set('data.location', 'UNPACKED');
     flush();
@@ -348,7 +345,7 @@
     assertFalse(isChildVisible(item, '#source-indicator'));
   });
 
-  test(assert(extension_item_tests.TestNames.EnableToggle), function() {
+  test(extension_item_tests.TestNames.EnableToggle, function() {
     assertFalse(item.$.enableToggle.disabled);
 
     // Test case where user does not have permission.
@@ -394,14 +391,14 @@
     flush();
   });
 
-  test(assert(extension_item_tests.TestNames.RemoveButton), function() {
+  test(extension_item_tests.TestNames.RemoveButton, function() {
     assertFalse(item.$.removeButton.hidden);
     item.set('data.mustRemainInstalled', true);
     flush();
     assertTrue(item.$.removeButton.hidden);
   });
 
-  test(assert(extension_item_tests.TestNames.HtmlInName), function() {
+  test(extension_item_tests.TestNames.HtmlInName, function() {
     const name = '<HTML> in the name!';
     item.set('data.name', name);
     flush();
@@ -411,7 +408,7 @@
         `Related to ${name}`, item.$.a11yAssociation.textContent!.trim());
   });
 
-  test(assert(extension_item_tests.TestNames.RepairButton), function() {
+  test(extension_item_tests.TestNames.RepairButton, function() {
     // For most extensions, the "repair" button should be displayed if the
     // extension is detected as corrupted.
     testVisible(item, '#repair-button', false);
@@ -431,8 +428,7 @@
   });
 
   test(
-      assert(extension_item_tests.TestNames.InspectableViewSortOrder),
-      function() {
+      extension_item_tests.TestNames.InspectableViewSortOrder, function() {
         function getUrl(path: string) {
           return `chrome-extension://${extensionData.id}/${path}`;
         }
diff --git a/chrome/test/data/webui/extensions/keyboard_shortcuts_test.ts b/chrome/test/data/webui/extensions/keyboard_shortcuts_test.ts
index 66041a50..647c950 100644
--- a/chrome/test/data/webui/extensions/keyboard_shortcuts_test.ts
+++ b/chrome/test/data/webui/extensions/keyboard_shortcuts_test.ts
@@ -5,9 +5,7 @@
 /** @fileoverview Suite of tests for extension-keyboard-shortcuts. */
 
 import {ExtensionsKeyboardShortcutsElement, isValidKeyCode, Key, keystrokeToString} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible} from 'chrome://webui-test/test_util.js';
 
@@ -80,7 +78,7 @@
     flush();
   });
 
-  test(assert(extension_shortcut_tests.TestNames.Layout), function() {
+  test(extension_shortcut_tests.TestNames.Layout, function() {
     function isVisibleOnCard(e: HTMLElement, s: string): boolean {
       // We check the light DOM in the card because it's a regular old div,
       // rather than a fancy-schmancy custom element.
diff --git a/chrome/test/data/webui/extensions/kiosk_mode_manager_unit_test.ts b/chrome/test/data/webui/extensions/kiosk_mode_manager_unit_test.ts
index 71d98e1..cad23e2 100644
--- a/chrome/test/data/webui/extensions/kiosk_mode_manager_unit_test.ts
+++ b/chrome/test/data/webui/extensions/kiosk_mode_manager_unit_test.ts
@@ -9,10 +9,9 @@
  */
 
 import {ExtensionsManagerElement, KioskBrowserProxyImpl, Service} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
 import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+
 import {TestKioskBrowserProxy} from './test_kiosk_browser_proxy.js';
 import {TestService} from './test_service.js';
 
@@ -53,8 +52,7 @@
   });
 
   test(
-      assert(extension_manager_unit_tests.TestNames.KioskMode),
-      async function() {
+      extension_manager_unit_tests.TestNames.KioskMode, async function() {
         assertFalse(
             !!manager.shadowRoot!.querySelector('extensions-kiosk-dialog'));
 
diff --git a/chrome/test/data/webui/extensions/kiosk_mode_test.ts b/chrome/test/data/webui/extensions/kiosk_mode_test.ts
index 9d953cd..db24a7b 100644
--- a/chrome/test/data/webui/extensions/kiosk_mode_test.ts
+++ b/chrome/test/data/webui/extensions/kiosk_mode_test.ts
@@ -5,7 +5,6 @@
 /** @fileoverview Suite of tests for extension-kiosk-dialog. */
 
 import {CrCheckboxElement, ExtensionsKioskDialogElement, KioskApp, KioskAppSettings, KioskBrowserProxyImpl, KioskSettings} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -86,7 +85,7 @@
     return initPage();
   });
 
-  test(assert(extension_kiosk_mode_tests.TestNames.Layout), async function() {
+  test(extension_kiosk_mode_tests.TestNames.Layout, async function() {
     const apps = basicApps.slice(0);
     apps[1]!.autoLaunch = true;
     apps[1]!.isLoading = true;
@@ -116,8 +115,7 @@
   });
 
   test(
-      assert(extension_kiosk_mode_tests.TestNames.AutoLaunch),
-      async function() {
+      extension_kiosk_mode_tests.TestNames.AutoLaunch, async function() {
         const apps = basicApps.slice(0);
         apps[1]!.autoLaunch = true;
         setAppSettings({apps: apps, hasAutoLaunchApp: true});
@@ -141,7 +139,7 @@
         assertEquals(appId, basicApps[1]!.id);
       });
 
-  test(assert(extension_kiosk_mode_tests.TestNames.Bailout), async function() {
+  test(extension_kiosk_mode_tests.TestNames.Bailout, async function() {
     const apps = basicApps.slice(0);
     apps[1]!.autoLaunch = true;
     setAppSettings({apps: apps, hasAutoLaunchApp: true});
@@ -193,22 +191,21 @@
     assertFalse(disabled);
   });
 
-  test(
-      assert(extension_kiosk_mode_tests.TestNames.AddButton), async function() {
-        const addButton = dialog.$.addButton;
-        assertTrue(!!addButton);
-        assertTrue(addButton.disabled);
+  test(extension_kiosk_mode_tests.TestNames.AddButton, async function() {
+    const addButton = dialog.$.addButton;
+    assertTrue(!!addButton);
+    assertTrue(addButton.disabled);
 
-        const addInput = dialog.$.addInput;
-        addInput.value = 'blah';
-        assertFalse(addButton.disabled);
+    const addInput = dialog.$.addInput;
+    addInput.value = 'blah';
+    assertFalse(addButton.disabled);
 
-        addButton.click();
-        const appId = await browserProxy.whenCalled('addKioskApp');
-        assertEquals(appId, 'blah');
-      });
+    addButton.click();
+    const appId = await browserProxy.whenCalled('addKioskApp');
+    assertEquals(appId, 'blah');
+  });
 
-  test(assert(extension_kiosk_mode_tests.TestNames.Updated), function() {
+  test(extension_kiosk_mode_tests.TestNames.Updated, function() {
     const items =
         dialog.shadowRoot!.querySelectorAll<HTMLElement>('.list-item');
     assertTrue(items[0]!.textContent!.includes(basicApps[0]!.name));
@@ -227,7 +224,7 @@
     assertTrue(items[0]!.textContent!.includes(newName));
   });
 
-  test(assert(extension_kiosk_mode_tests.TestNames.AddError), function() {
+  test(extension_kiosk_mode_tests.TestNames.AddError, function() {
     const addInput = dialog.$.addInput;
 
     assertFalse(!!addInput.invalid);
diff --git a/chrome/test/data/webui/extensions/load_error_test.ts b/chrome/test/data/webui/extensions/load_error_test.ts
index 5cf9a76..574d30b 100644
--- a/chrome/test/data/webui/extensions/load_error_test.ts
+++ b/chrome/test/data/webui/extensions/load_error_test.ts
@@ -7,8 +7,8 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsLoadErrorElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+
 import {TestService} from './test_service.js';
 import {isElementVisible} from './test_util.js';
 
@@ -44,43 +44,36 @@
     document.body.appendChild(loadError);
   });
 
-  test(
-      assert(extension_load_error_tests.TestNames.RetryError),
-      async function() {
-        const dialogElement =
-            loadError.shadowRoot!.querySelector('cr-dialog')!.getNative();
-        assertFalse(isElementVisible(dialogElement));
-        loadError.show();
-        assertTrue(isElementVisible(dialogElement));
+  test(extension_load_error_tests.TestNames.RetryError, async function() {
+    const dialogElement =
+        loadError.shadowRoot!.querySelector('cr-dialog')!.getNative();
+    assertFalse(isElementVisible(dialogElement));
+    loadError.show();
+    assertTrue(isElementVisible(dialogElement));
 
-        mockDelegate.setRetryLoadUnpackedError(stubLoadError);
-        loadError.shadowRoot!.querySelector<HTMLElement>(
-                                 '.action-button')!.click();
-        const arg = await mockDelegate.whenCalled('retryLoadUnpacked');
-        assertEquals(fakeGuid, arg);
-        assertTrue(isElementVisible(dialogElement));
-        loadError.shadowRoot!.querySelector<HTMLElement>(
-                                 '.cancel-button')!.click();
-        assertFalse(isElementVisible(dialogElement));
-      });
+    mockDelegate.setRetryLoadUnpackedError(stubLoadError);
+    loadError.shadowRoot!.querySelector<HTMLElement>('.action-button')!.click();
+    const arg = await mockDelegate.whenCalled('retryLoadUnpacked');
+    assertEquals(fakeGuid, arg);
+    assertTrue(isElementVisible(dialogElement));
+    loadError.shadowRoot!.querySelector<HTMLElement>('.cancel-button')!.click();
+    assertFalse(isElementVisible(dialogElement));
+  });
 
-  test(
-      assert(extension_load_error_tests.TestNames.RetrySuccess),
-      async function() {
-        const dialogElement =
-            loadError.shadowRoot!.querySelector('cr-dialog')!.getNative();
-        assertFalse(isElementVisible(dialogElement));
-        loadError.show();
-        assertTrue(isElementVisible(dialogElement));
+  test(extension_load_error_tests.TestNames.RetrySuccess, async function() {
+    const dialogElement =
+        loadError.shadowRoot!.querySelector('cr-dialog')!.getNative();
+    assertFalse(isElementVisible(dialogElement));
+    loadError.show();
+    assertTrue(isElementVisible(dialogElement));
 
-        loadError.shadowRoot!.querySelector<HTMLElement>(
-                                 '.action-button')!.click();
-        const arg = await mockDelegate.whenCalled('retryLoadUnpacked');
-        assertEquals(fakeGuid, arg);
-        assertFalse(isElementVisible(dialogElement));
-      });
+    loadError.shadowRoot!.querySelector<HTMLElement>('.action-button')!.click();
+    const arg = await mockDelegate.whenCalled('retryLoadUnpacked');
+    assertEquals(fakeGuid, arg);
+    assertFalse(isElementVisible(dialogElement));
+  });
 
-  test(assert(extension_load_error_tests.TestNames.CodeSection), function() {
+  test(extension_load_error_tests.TestNames.CodeSection, function() {
     assertTrue(loadError.$.code.shadowRoot!
                    .querySelector<HTMLElement>('#scroll-container')!.hidden);
     const loadErrorWithSource = {
diff --git a/chrome/test/data/webui/extensions/manager_test.ts b/chrome/test/data/webui/extensions/manager_test.ts
index dfa3d0a..ab037167 100644
--- a/chrome/test/data/webui/extensions/manager_test.ts
+++ b/chrome/test/data/webui/extensions/manager_test.ts
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 import {ChromeEvent} from '/tools/typescript/definitions/chrome_event.js';
-import {navigation, Page, Service} from 'chrome://extensions/extensions.js';
-import {ExtensionsManagerElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
+import {ExtensionsManagerElement, navigation, Page, Service} from 'chrome://extensions/extensions.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
@@ -61,7 +59,7 @@
   }
 
   test(
-      assert(extension_manager_tests.TestNames.ItemListVisibility), function() {
+      extension_manager_tests.TestNames.ItemListVisibility, function() {
         function getExtensionByName(name: string):
             chrome.developerPrivate.ExtensionInfo|null {
           return getExtensions().find(el => el.name === name) || null;
@@ -97,7 +95,7 @@
         assertTrue(listHasItemWithName('My extension 1'));
       });
 
-  test(assert(extension_manager_tests.TestNames.SplitItems), function() {
+  test(extension_manager_tests.TestNames.SplitItems, function() {
     function hasExtensionWithName(name: string): boolean {
       return getExtensions().some(el => el.name === name);
     }
@@ -113,7 +111,7 @@
     assertTrue(hasAppWithName('Packaged App Test'));
   });
 
-  test(assert(extension_manager_tests.TestNames.ChangePages), function() {
+  test(extension_manager_tests.TestNames.ChangePages, function() {
     manager.shadowRoot!.querySelector('extensions-toolbar')!.shadowRoot!
         .querySelector('cr-toolbar')!.shadowRoot!
         .querySelector<HTMLElement>('#menuButton')!.click();
@@ -155,7 +153,7 @@
     assertViewActive('extensions-item-list');
   });
 
-  test(assert(extension_manager_tests.TestNames.PageTitleUpdate), function() {
+  test(extension_manager_tests.TestNames.PageTitleUpdate, function() {
     assertEquals('Extensions', document.title);
 
     // Open details view with a valid ID.
@@ -171,7 +169,7 @@
   });
 
   test(
-      assert(extension_manager_tests.TestNames.NavigateToSitePermissionsFail),
+      extension_manager_tests.TestNames.NavigateToSitePermissionsFail,
       function() {
         assertFalse(manager.enableEnhancedSiteControls);
 
@@ -192,8 +190,7 @@
       });
 
   test(
-      assert(
-          extension_manager_tests.TestNames.NavigateToSitePermissionsSuccess),
+      extension_manager_tests.TestNames.NavigateToSitePermissionsSuccess,
       function() {
         // Set the enableEnhancedSiteControls flag to true.
         manager.enableEnhancedSiteControls = true;
diff --git a/chrome/test/data/webui/extensions/manager_test_with_id_query_param.ts b/chrome/test/data/webui/extensions/manager_test_with_id_query_param.ts
index f501281..807b69b 100644
--- a/chrome/test/data/webui/extensions/manager_test_with_id_query_param.ts
+++ b/chrome/test/data/webui/extensions/manager_test_with_id_query_param.ts
@@ -5,7 +5,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsManagerElement, navigation, Page} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
@@ -44,8 +43,7 @@
   });
 
   test(
-      assert(extension_manager_tests.TestNames.UrlNavigationToDetails),
-      function() {
+      extension_manager_tests.TestNames.UrlNavigationToDetails, function() {
         assertViewActive('extensions-detail-view');
         const detailsView =
             manager.shadowRoot!.querySelector('extensions-detail-view');
@@ -69,7 +67,7 @@
       });
 
   test(
-      assert(extension_manager_tests.TestNames.UrlNavigationToActivityLogFail),
+      extension_manager_tests.TestNames.UrlNavigationToActivityLogFail,
       function() {
         assertFalse(manager.showActivityLog);
 
diff --git a/chrome/test/data/webui/extensions/manager_unit_test.ts b/chrome/test/data/webui/extensions/manager_unit_test.ts
index 2d548b5..709d58b 100644
--- a/chrome/test/data/webui/extensions/manager_unit_test.ts
+++ b/chrome/test/data/webui/extensions/manager_unit_test.ts
@@ -9,7 +9,6 @@
  */
 
 import {ExtensionsManagerElement, navigation, Page, Service} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
@@ -77,7 +76,7 @@
   }
 
   // Test that newly added items are inserted in the correct order.
-  test(assert(extension_manager_unit_tests.TestNames.ItemOrder), function() {
+  test(extension_manager_unit_tests.TestNames.ItemOrder, function() {
     assertEquals(0, getExtensions().length);
 
     const alphaFromStore = createExtensionInfo({
@@ -142,7 +141,7 @@
     assertEquals(alphaFromStore.id, getExtension(5).id);
   });
 
-  test(assert(extension_manager_unit_tests.TestNames.SetItemData), function() {
+  test(extension_manager_unit_tests.TestNames.SetItemData, function() {
     const description = 'description';
 
     const extension = createExtensionInfo({description: description});
@@ -163,8 +162,7 @@
   });
 
   test(
-      assert(extension_manager_unit_tests.TestNames.UpdateItemData),
-      function() {
+      extension_manager_unit_tests.TestNames.UpdateItemData, function() {
         const oldDescription = 'old description';
         const newDescription = 'new description';
 
@@ -204,29 +202,23 @@
         assertEquals(newDescription, content.textContent!.trim());
       });
 
-  test(
-      assert(extension_manager_unit_tests.TestNames.ProfileSettings),
-      function() {
-        assertFalse(manager.inDevMode);
+  test(extension_manager_unit_tests.TestNames.ProfileSettings, function() {
+    assertFalse(manager.inDevMode);
 
-        service.profileStateChangedTarget.callListeners(
-            {inDeveloperMode: true});
-        assertTrue(manager.inDevMode);
+    service.profileStateChangedTarget.callListeners({inDeveloperMode: true});
+    assertTrue(manager.inDevMode);
 
-        service.profileStateChangedTarget.callListeners(
-            {inDeveloperMode: false});
-        assertFalse(manager.inDevMode);
+    service.profileStateChangedTarget.callListeners({inDeveloperMode: false});
+    assertFalse(manager.inDevMode);
 
-        service.profileStateChangedTarget.callListeners(
-            {canLoadUnpacked: true});
-        assertTrue(manager.canLoadUnpacked);
+    service.profileStateChangedTarget.callListeners({canLoadUnpacked: true});
+    assertTrue(manager.canLoadUnpacked);
 
-        service.profileStateChangedTarget.callListeners(
-            {canLoadUnpacked: false});
-        assertFalse(manager.canLoadUnpacked);
-      });
+    service.profileStateChangedTarget.callListeners({canLoadUnpacked: false});
+    assertFalse(manager.canLoadUnpacked);
+  });
 
-  test(assert(extension_manager_unit_tests.TestNames.Uninstall), function() {
+  test(extension_manager_unit_tests.TestNames.Uninstall, function() {
     assertEquals(0, getExtensions().length);
 
     const extension = createExtensionInfo({
@@ -252,7 +244,7 @@
   }
 
   test(
-      assert(extension_manager_unit_tests.TestNames.UninstallFromDetails),
+      extension_manager_unit_tests.TestNames.UninstallFromDetails,
       function(done) {
         const extension = createExtensionInfo({
           location: chrome.developerPrivate.Location.FROM_STORE,
@@ -279,8 +271,7 @@
       });
 
   test(
-      assert(extension_manager_unit_tests.TestNames.ToggleIncognitoMode),
-      function() {
+      extension_manager_unit_tests.TestNames.ToggleIncognitoMode, function() {
         assertEquals(0, getExtensions().length);
         const extension = createExtensionInfo({
           location: chrome.developerPrivate.Location.FROM_STORE,
@@ -315,8 +306,7 @@
       });
 
   test(
-      assert(extension_manager_unit_tests.TestNames.EnableAndDisable),
-      function() {
+      extension_manager_unit_tests.TestNames.EnableAndDisable, function() {
         const ExtensionState = chrome.developerPrivate.ExtensionState;
         assertEquals(0, getExtensions().length);
         const extension = createExtensionInfo({
diff --git a/chrome/test/data/webui/extensions/manager_unit_test_with_activity_log_flag.ts b/chrome/test/data/webui/extensions/manager_unit_test_with_activity_log_flag.ts
index 7d1f1305..1d6cec8 100644
--- a/chrome/test/data/webui/extensions/manager_unit_test_with_activity_log_flag.ts
+++ b/chrome/test/data/webui/extensions/manager_unit_test_with_activity_log_flag.ts
@@ -11,7 +11,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsManagerElement, navigation, Page, Service} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 import {TestService} from './test_service.js';
@@ -61,8 +60,7 @@
   }
 
   test(
-      assert(extension_manager_unit_tests.TestNames.UpdateFromActivityLog),
-      function() {
+      extension_manager_unit_tests.TestNames.UpdateFromActivityLog, function() {
         service.testActivities = testActivities;
 
         const extension = createExtensionInfo();
diff --git a/chrome/test/data/webui/extensions/navigation_helper_test.ts b/chrome/test/data/webui/extensions/navigation_helper_test.ts
index 44f581a1..93ecbe6 100644
--- a/chrome/test/data/webui/extensions/navigation_helper_test.ts
+++ b/chrome/test/data/webui/extensions/navigation_helper_test.ts
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 import {Dialog, NavigationHelper, Page, PageState} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {assertDeepEquals, assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {MockMethod} from 'chrome://webui-test/mock_controller.js';
 
@@ -40,7 +39,7 @@
     navigationHelper = new NavigationHelper();
   });
 
-  test(assert(extension_navigation_helper_tests.TestNames.Basic), function() {
+  test(extension_navigation_helper_tests.TestNames.Basic, function() {
     const id = 'a'.repeat(32);
     const mock = new MockMethod();
 
@@ -78,8 +77,7 @@
   });
 
   test(
-      assert(extension_navigation_helper_tests.TestNames.Conversions),
-      function() {
+      extension_navigation_helper_tests.TestNames.Conversions, function() {
         const id = 'a'.repeat(32);
         const stateUrlPairs: {[k: string]: {url: string, state: PageState}} = {
           extensions: {
@@ -134,7 +132,7 @@
       });
 
   test(
-      assert(extension_navigation_helper_tests.TestNames.PushAndReplaceState),
+      extension_navigation_helper_tests.TestNames.PushAndReplaceState,
       function() {
         const id1 = 'a'.repeat(32);
         const id2 = 'b'.repeat(32);
@@ -186,8 +184,7 @@
       });
 
   test(
-      assert(extension_navigation_helper_tests.TestNames.SupportedRoutes),
-      function() {
+      extension_navigation_helper_tests.TestNames.SupportedRoutes, function() {
         function removeEndSlash(url: string): string {
           const CANONICAL_PATH_REGEX = /([\/-\w]+)\/$/;
           return url.replace(CANONICAL_PATH_REGEX, '$1');
diff --git a/chrome/test/data/webui/extensions/options_dialog_test.ts b/chrome/test/data/webui/extensions/options_dialog_test.ts
index e223d62..30dc344b 100644
--- a/chrome/test/data/webui/extensions/options_dialog_test.ts
+++ b/chrome/test/data/webui/extensions/options_dialog_test.ts
@@ -6,7 +6,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsOptionsDialogElement, OptionsDialogMaxHeight, OptionsDialogMinWidth, Service} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {assertEquals, assertFalse, assertGE, assertLE, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
@@ -41,7 +40,7 @@
     return rect.width * rect.height > 0;
   }
 
-  test(assert(extension_options_dialog_tests.TestNames.Layout), function() {
+  test(extension_options_dialog_tests.TestNames.Layout, function() {
     // Try showing the dialog.
     assertFalse(isDialogVisible());
     optionsDialog.show(data);
diff --git a/chrome/test/data/webui/extensions/pack_dialog_test.ts b/chrome/test/data/webui/extensions/pack_dialog_test.ts
index 9a55cbb..27cea07 100644
--- a/chrome/test/data/webui/extensions/pack_dialog_test.ts
+++ b/chrome/test/data/webui/extensions/pack_dialog_test.ts
@@ -7,7 +7,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsPackDialogAlertElement, ExtensionsPackDialogElement, PackDialogDelegate} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -73,7 +72,7 @@
     document.body.appendChild(packDialog);
   });
 
-  test(assert(extension_pack_dialog_tests.TestNames.Interaction), function() {
+  test(extension_pack_dialog_tests.TestNames.Interaction, function() {
     const dialogElement = packDialog.$.dialog.getNative();
 
     assertTrue(isElementVisible(dialogElement));
@@ -110,7 +109,7 @@
     });
   });
 
-  test(assert(extension_pack_dialog_tests.TestNames.PackSuccess), function() {
+  test(extension_pack_dialog_tests.TestNames.PackSuccess, function() {
     const dialogElement = packDialog.$.dialog.getNative();
     let packDialogAlert: ExtensionsPackDialogAlertElement;
     let alertElement: HTMLDialogElement;
@@ -159,7 +158,7 @@
         });
   });
 
-  test(assert(extension_pack_dialog_tests.TestNames.PackError), function() {
+  test(extension_pack_dialog_tests.TestNames.PackError, function() {
     const dialogElement = packDialog.$.dialog.getNative();
     let packDialogAlert: ExtensionsPackDialogAlertElement;
     let alertElement: HTMLDialogElement;
@@ -202,7 +201,7 @@
     });
   });
 
-  test(assert(extension_pack_dialog_tests.TestNames.PackWarning), function() {
+  test(extension_pack_dialog_tests.TestNames.PackWarning, function() {
     const dialogElement = packDialog.$.dialog.getNative();
     let packDialogAlert: ExtensionsPackDialogAlertElement;
     let alertElement: HTMLDialogElement;
diff --git a/chrome/test/data/webui/extensions/shortcut_input_test.ts b/chrome/test/data/webui/extensions/shortcut_input_test.ts
index b5a93d70..fd666c04 100644
--- a/chrome/test/data/webui/extensions/shortcut_input_test.ts
+++ b/chrome/test/data/webui/extensions/shortcut_input_test.ts
@@ -11,7 +11,6 @@
 import 'chrome://extensions/extensions.js';
 
 import {ExtensionsShortcutInputElement} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {keyDownOn, keyUpOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -42,76 +41,75 @@
     flush();
   });
 
-  test(
-      assert(extension_shortcut_input_tests.TestNames.Basic), async function() {
-        const field = input.$.input;
-        assertEquals('', field.value);
+  test(extension_shortcut_input_tests.TestNames.Basic, async function() {
+    const field = input.$.input;
+    assertEquals('', field.value);
 
-        // Click the edit button. Capture should start.
-        input.$.edit.click();
-        let arg = await testService.whenCalled('setShortcutHandlingSuspended');
+    // Click the edit button. Capture should start.
+    input.$.edit.click();
+    let arg = await testService.whenCalled('setShortcutHandlingSuspended');
 
-        assertTrue(arg);
-        testService.reset();
-        assertEquals('', field.value);
+    assertTrue(arg);
+    testService.reset();
+    assertEquals('', field.value);
 
-        // Press character.
-        keyDownOn(field, 65, []);
-        assertEquals('', field.value);
-        assertTrue(field.errorMessage!.startsWith('Include'));
-        // Add shift to character.
-        keyDownOn(field, 65, ['shift']);
-        assertEquals('', field.value);
-        assertTrue(field.errorMessage!.startsWith('Include'));
-        // Press ctrl.
-        keyDownOn(field, 17, ['ctrl']);
-        assertEquals('', field.value);
-        assertEquals('Type a letter', field.errorMessage);
-        // Add shift.
-        keyDownOn(field, 16, ['ctrl', 'shift']);
-        assertEquals('', field.value);
-        assertEquals('Type a letter', field.errorMessage);
-        // Remove shift.
-        keyUpOn(field, 16, ['ctrl']);
-        assertEquals('', field.value);
-        assertEquals('Type a letter', field.errorMessage);
-        // Add alt (ctrl + alt is invalid).
-        keyDownOn(field, 18, ['ctrl', 'alt']);
-        assertEquals('', field.value);
-        // Remove alt.
-        keyUpOn(field, 18, ['ctrl']);
-        assertEquals('', field.value);
-        assertEquals('Type a letter', field.errorMessage);
+    // Press character.
+    keyDownOn(field, 65, []);
+    assertEquals('', field.value);
+    assertTrue(field.errorMessage!.startsWith('Include'));
+    // Add shift to character.
+    keyDownOn(field, 65, ['shift']);
+    assertEquals('', field.value);
+    assertTrue(field.errorMessage!.startsWith('Include'));
+    // Press ctrl.
+    keyDownOn(field, 17, ['ctrl']);
+    assertEquals('', field.value);
+    assertEquals('Type a letter', field.errorMessage);
+    // Add shift.
+    keyDownOn(field, 16, ['ctrl', 'shift']);
+    assertEquals('', field.value);
+    assertEquals('Type a letter', field.errorMessage);
+    // Remove shift.
+    keyUpOn(field, 16, ['ctrl']);
+    assertEquals('', field.value);
+    assertEquals('Type a letter', field.errorMessage);
+    // Add alt (ctrl + alt is invalid).
+    keyDownOn(field, 18, ['ctrl', 'alt']);
+    assertEquals('', field.value);
+    // Remove alt.
+    keyUpOn(field, 18, ['ctrl']);
+    assertEquals('', field.value);
+    assertEquals('Type a letter', field.errorMessage);
 
-        // Add 'A'. Once a valid shortcut is typed (like Ctrl + A), it is
-        // committed.
-        keyDownOn(field, 65, ['ctrl']);
-        arg = await testService.whenCalled('updateExtensionCommandKeybinding');
+    // Add 'A'. Once a valid shortcut is typed (like Ctrl + A), it is
+    // committed.
+    keyDownOn(field, 65, ['ctrl']);
+    arg = await testService.whenCalled('updateExtensionCommandKeybinding');
 
-        testService.reset();
-        assertDeepEquals(['itemid', 'Command', 'Ctrl+A'], arg);
-        assertEquals('Ctrl + A', field.value);
-        assertEquals('Ctrl+A', input.shortcut);
+    testService.reset();
+    assertDeepEquals(['itemid', 'Command', 'Ctrl+A'], arg);
+    assertEquals('Ctrl + A', field.value);
+    assertEquals('Ctrl+A', input.shortcut);
 
-        // Test clearing the shortcut.
-        input.$.edit.click();
-        assertEquals(input.$.input, input.shadowRoot!.activeElement);
-        arg = await testService.whenCalled('updateExtensionCommandKeybinding');
+    // Test clearing the shortcut.
+    input.$.edit.click();
+    assertEquals(input.$.input, input.shadowRoot!.activeElement);
+    arg = await testService.whenCalled('updateExtensionCommandKeybinding');
 
-        field.blur();
-        testService.reset();
-        assertDeepEquals(['itemid', 'Command', ''], arg);
-        assertEquals('', input.shortcut);
+    field.blur();
+    testService.reset();
+    assertDeepEquals(['itemid', 'Command', ''], arg);
+    assertEquals('', input.shortcut);
 
-        input.$.edit.click();
-        arg = await testService.whenCalled('setShortcutHandlingSuspended');
-        testService.reset();
-        assertTrue(arg);
+    input.$.edit.click();
+    arg = await testService.whenCalled('setShortcutHandlingSuspended');
+    testService.reset();
+    assertTrue(arg);
 
-        // Test ending capture using the escape key.
-        input.$.edit.click();
-        keyDownOn(field, 27);  // Escape key.
-        arg = await testService.whenCalled('setShortcutHandlingSuspended');
-        assertFalse(arg);
-      });
+    // Test ending capture using the escape key.
+    input.$.edit.click();
+    keyDownOn(field, 27);  // Escape key.
+    arg = await testService.whenCalled('setShortcutHandlingSuspended');
+    assertFalse(arg);
+  });
 });
diff --git a/chrome/test/data/webui/extensions/sidebar_test.ts b/chrome/test/data/webui/extensions/sidebar_test.ts
index f2802a0..db466160 100644
--- a/chrome/test/data/webui/extensions/sidebar_test.ts
+++ b/chrome/test/data/webui/extensions/sidebar_test.ts
@@ -4,7 +4,6 @@
 
 /** @fileoverview Suite of tests for extension-sidebar. */
 import {ExtensionsSidebarElement, navigation, Page} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertDeepEquals, assertEquals, assertFalse} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
@@ -31,7 +30,7 @@
     document.body.appendChild(sidebar);
   });
 
-  test(assert(extension_sidebar_tests.TestNames.SetSelected), function() {
+  test(extension_sidebar_tests.TestNames.SetSelected, function() {
     const selector = '.section-item.iron-selected';
     assertFalse(!!sidebar.shadowRoot!.querySelector(selector));
 
@@ -64,8 +63,7 @@
   });
 
   test(
-      assert(extension_sidebar_tests.TestNames.LayoutAndClickHandlers),
-      function(done) {
+      extension_sidebar_tests.TestNames.LayoutAndClickHandlers, function(done) {
         const boundTestVisible = testVisible.bind(null, sidebar);
         boundTestVisible('#sectionsExtensions', true);
 
diff --git a/chrome/test/data/webui/extensions/toolbar_test.ts b/chrome/test/data/webui/extensions/toolbar_test.ts
index 0a015fd..87891a6 100644
--- a/chrome/test/data/webui/extensions/toolbar_test.ts
+++ b/chrome/test/data/webui/extensions/toolbar_test.ts
@@ -3,12 +3,11 @@
 // found in the LICENSE file.
 
 import {ExtensionsToolbarElement, getToastManager} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
-
 // <if expr="chromeos_ash">
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
+
 // </if>
 
 import {TestService} from './test_service.js';
@@ -56,7 +55,7 @@
     document.body.appendChild(toastManager);
   });
 
-  test(assert(extension_toolbar_tests.TestNames.Layout), function() {
+  test(extension_toolbar_tests.TestNames.Layout, function() {
     const boundTestVisible = testVisible.bind(null, toolbar);
     boundTestVisible('#devMode', true);
     assertEquals(toolbar.$.devMode.disabled, false);
@@ -81,7 +80,7 @@
     boundTestVisible('#updateNow', true);
   });
 
-  test(assert(extension_toolbar_tests.TestNames.DevModeToggle), function() {
+  test(extension_toolbar_tests.TestNames.DevModeToggle, function() {
     const toggle = toolbar.$.devMode;
     assertFalse(toggle.disabled);
 
@@ -100,52 +99,48 @@
     assertTrue(toggle.disabled);
   });
 
-  test(
-      assert(extension_toolbar_tests.TestNames.ClickHandlers),
-      async function() {
-        toolbar.set('inDevMode', true);
-        flush();
-        const toastManager = getToastManager();
-        toolbar.$.devMode.click();
-        let arg = await mockDelegate.whenCalled('setProfileInDevMode');
-        assertFalse(arg);
+  test(extension_toolbar_tests.TestNames.ClickHandlers, async function() {
+    toolbar.set('inDevMode', true);
+    flush();
+    const toastManager = getToastManager();
+    toolbar.$.devMode.click();
+    let arg = await mockDelegate.whenCalled('setProfileInDevMode');
+    assertFalse(arg);
 
-        mockDelegate.reset();
-        toolbar.$.devMode.click();
-        arg = await mockDelegate.whenCalled('setProfileInDevMode');
-        assertTrue(arg);
+    mockDelegate.reset();
+    toolbar.$.devMode.click();
+    arg = await mockDelegate.whenCalled('setProfileInDevMode');
+    assertTrue(arg);
 
-        mockDelegate.setLoadUnpackedSuccess(true);
-        toolbar.$.loadUnpacked.click();
-        await mockDelegate.whenCalled('loadUnpacked');
-        assertTrue(toastManager.isToastOpen);
+    mockDelegate.setLoadUnpackedSuccess(true);
+    toolbar.$.loadUnpacked.click();
+    await mockDelegate.whenCalled('loadUnpacked');
+    assertTrue(toastManager.isToastOpen);
 
-        // Hide toast since it is open for 3000ms in previous Promise.
-        toastManager.hide();
-        mockDelegate.setLoadUnpackedSuccess(false);
-        toolbar.$.loadUnpacked.click();
-        await mockDelegate.whenCalled('loadUnpacked');
-        assertFalse(toastManager.isToastOpen);
-        assertFalse(toastManager.isToastOpen);
+    // Hide toast since it is open for 3000ms in previous Promise.
+    toastManager.hide();
+    mockDelegate.setLoadUnpackedSuccess(false);
+    toolbar.$.loadUnpacked.click();
+    await mockDelegate.whenCalled('loadUnpacked');
+    assertFalse(toastManager.isToastOpen);
+    assertFalse(toastManager.isToastOpen);
 
-        toolbar.$.updateNow.click();
-        // Simulate user rapidly clicking update button multiple times.
-        toolbar.$.updateNow.click();
-        assertTrue(toastManager.isToastOpen);
-        await mockDelegate.whenCalled('updateAllExtensions');
-        assertEquals(1, mockDelegate.getCallCount('updateAllExtensions'));
-        assertFalse(
-            !!toolbar.shadowRoot!.querySelector('extensions-pack-dialog'));
-        toolbar.$.packExtensions.click();
-        flush();
-        const dialog =
-            toolbar.shadowRoot!.querySelector('extensions-pack-dialog');
-        assertTrue(!!dialog);
-      });
+    toolbar.$.updateNow.click();
+    // Simulate user rapidly clicking update button multiple times.
+    toolbar.$.updateNow.click();
+    assertTrue(toastManager.isToastOpen);
+    await mockDelegate.whenCalled('updateAllExtensions');
+    assertEquals(1, mockDelegate.getCallCount('updateAllExtensions'));
+    assertFalse(!!toolbar.shadowRoot!.querySelector('extensions-pack-dialog'));
+    toolbar.$.packExtensions.click();
+    flush();
+    const dialog = toolbar.shadowRoot!.querySelector('extensions-pack-dialog');
+    assertTrue(!!dialog);
+  });
 
   /** Tests that the update button properly fires the load-error event. */
   test(
-      assert(extension_toolbar_tests.TestNames.FailedUpdateFiresLoadError),
+      extension_toolbar_tests.TestNames.FailedUpdateFiresLoadError,
       async function() {
         const item = document.createElement('extensions-item');
         item.data = createExtensionInfo();
@@ -187,7 +182,7 @@
       });
 
   // <if expr="chromeos_ash">
-  test(assert(extension_toolbar_tests.TestNames.KioskMode), function() {
+  test(extension_toolbar_tests.TestNames.KioskMode, function() {
     const button = toolbar.$.kioskExtensions;
     assertTrue(button.hidden);
     toolbar.kioskEnabled = true;
diff --git a/chrome/test/data/webui/inline_login/arc_account_picker_page_test.ts b/chrome/test/data/webui/inline_login/arc_account_picker_page_test.ts
index 936a18dd..1d21c01 100644
--- a/chrome/test/data/webui/inline_login/arc_account_picker_page_test.ts
+++ b/chrome/test/data/webui/inline_login/arc_account_picker_page_test.ts
@@ -9,7 +9,6 @@
 import {AccountAdditionOptions} from 'chrome://chrome-signin/arc_account_picker/arc_util.js';
 import {InlineLoginAppElement, View} from 'chrome://chrome-signin/inline_login_app.js';
 import {InlineLoginBrowserProxyImpl} from 'chrome://chrome-signin/inline_login_browser_proxy.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertDeepEquals, assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -71,8 +70,7 @@
   }
 
   test(
-      assert(arc_account_picker_page_test.TestNames.ArcPickerActive),
-      async () => {
+      arc_account_picker_page_test.TestNames.ArcPickerActive, async () => {
         await testSetup(
             {isAvailableInArc: true, showArcAvailabilityPicker: true},
             getFakeAccountsNotAvailableInArcList(),
@@ -92,7 +90,7 @@
       });
 
   test(
-      assert(arc_account_picker_page_test.TestNames.ArcPickerHiddenForReauth),
+      arc_account_picker_page_test.TestNames.ArcPickerHiddenForReauth,
       async () => {
         await testSetup(
             {isAvailableInArc: true, showArcAvailabilityPicker: true},
@@ -106,7 +104,7 @@
       });
 
   test(
-      assert(arc_account_picker_page_test.TestNames.ArcPickerHiddenNoAccounts),
+      arc_account_picker_page_test.TestNames.ArcPickerHiddenNoAccounts,
       async () => {
         await testSetup(
             {isAvailableInArc: true, showArcAvailabilityPicker: true},
@@ -120,7 +118,7 @@
                 ' not available in ARC');
       });
 
-  test(assert(arc_account_picker_page_test.TestNames.AddAccount), async () => {
+  test(arc_account_picker_page_test.TestNames.AddAccount, async () => {
     await testSetup(
         {isAvailableInArc: true, showArcAvailabilityPicker: true},
         getFakeAccountsNotAvailableInArcList(),
@@ -141,8 +139,7 @@
   });
 
   test(
-      assert(arc_account_picker_page_test.TestNames.MakeAvailableInArc),
-      async () => {
+      arc_account_picker_page_test.TestNames.MakeAvailableInArc, async () => {
         await testSetup(
             {isAvailableInArc: true, showArcAvailabilityPicker: true},
             getFakeAccountsNotAvailableInArcList(),
diff --git a/chrome/test/data/webui/inline_login/inline_login_signin_blocked_by_policy_page_test.ts b/chrome/test/data/webui/inline_login/inline_login_signin_blocked_by_policy_page_test.ts
index 60ebe423..110b7c1 100644
--- a/chrome/test/data/webui/inline_login/inline_login_signin_blocked_by_policy_page_test.ts
+++ b/chrome/test/data/webui/inline_login/inline_login_signin_blocked_by_policy_page_test.ts
@@ -14,7 +14,6 @@
 import {InlineLoginAppElement, View} from 'chrome://chrome-signin/inline_login_app.js';
 import {InlineLoginBrowserProxyImpl} from 'chrome://chrome-signin/inline_login_browser_proxy.js';
 import {SigninBlockedByPolicyPageElement} from 'chrome://chrome-signin/signin_blocked_by_policy_page.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -61,8 +60,8 @@
   }
 
   test(
-      assert(inline_login_signin_blocked_by_policy_page_test.TestNames
-                 .BlockedSigninPage),
+      inline_login_signin_blocked_by_policy_page_test.TestNames
+          .BlockedSigninPage,
       () => {
         testSetup(/*dialogArgs=*/ null);
         // Fire web UI listener to switch the ui view to
@@ -92,8 +91,8 @@
       });
 
   test(
-      assert(inline_login_signin_blocked_by_policy_page_test.TestNames
-                 .FireWebUIListenerCallback),
+      inline_login_signin_blocked_by_policy_page_test.TestNames
+          .FireWebUIListenerCallback,
       () => {
         testSetup(/*dialogArgs=*/ null);
         // Fire web UI listener to switch the ui view to
@@ -135,8 +134,7 @@
       });
 
   test(
-      assert(
-          inline_login_signin_blocked_by_policy_page_test.TestNames.OkButton),
+      inline_login_signin_blocked_by_policy_page_test.TestNames.OkButton,
       async () => {
         testSetup(/*dialogArgs=*/ null);
         // Fire web UI listener to switch the ui view to
diff --git a/chrome/test/data/webui/inline_login/inline_login_test.ts b/chrome/test/data/webui/inline_login/inline_login_test.ts
index 69d922dd..14277f6 100644
--- a/chrome/test/data/webui/inline_login/inline_login_test.ts
+++ b/chrome/test/data/webui/inline_login/inline_login_test.ts
@@ -6,10 +6,9 @@
 
 import {InlineLoginAppElement, View} from 'chrome://chrome-signin/inline_login_app.js';
 import {InlineLoginBrowserProxyImpl} from 'chrome://chrome-signin/inline_login_browser_proxy.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
-import {isChromeOS} from 'chrome://resources/js/platform.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {isChromeOS} from 'chrome://resources/js/platform.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {isChildVisible} from 'chrome://webui-test/test_util.js';
@@ -61,7 +60,7 @@
     flush();
   });
 
-  test(assert(inline_login_test.TestNames.Initialize), () => {
+  test(inline_login_test.TestNames.Initialize, () => {
     webUIListenerCallback('load-auth-extension', fakeAuthExtensionData);
     // 'Add account' screen should be shown.
     assertTrue(isVisible(`#${View.ADD_ACCOUNT}`));
@@ -78,7 +77,7 @@
     assertEquals(1, testBrowserProxy.getCallCount('initialize'));
   });
 
-  test(assert(inline_login_test.TestNames.WebUICallbacks), () => {
+  test(inline_login_test.TestNames.WebUICallbacks, () => {
     webUIListenerCallback('load-auth-extension', fakeAuthExtensionData);
     assertEquals(1, testAuthenticator.loadCalls);
     assertEquals(fakeAuthExtensionData, testAuthenticator.data);
@@ -95,7 +94,7 @@
     });
   });
 
-  test(assert(inline_login_test.TestNames.AuthExtHostCallbacks), async () => {
+  test(inline_login_test.TestNames.AuthExtHostCallbacks, async () => {
     const fakeUrl = 'www.google.com/fake';
 
     assertTrue(inlineLoginComponent.$.spinner.active);
@@ -140,7 +139,7 @@
   });
 
   // <if expr="not chromeos_ash">
-  test(assert(inline_login_test.TestNames.BackButton), () => {
+  test(inline_login_test.TestNames.BackButton, () => {
     const backButton =
         inlineLoginComponent.shadowRoot!.querySelector('.back-button');
     // Back button should only exist on ChromeOS.
@@ -150,7 +149,7 @@
 
 
   // <if expr="chromeos_ash">
-  test(assert(inline_login_test.TestNames.BackButton), () => {
+  test(inline_login_test.TestNames.BackButton, () => {
     const backButton =
         inlineLoginComponent.shadowRoot!.querySelector<HTMLElement>(
             '.back-button');
@@ -174,7 +173,7 @@
     assertEquals(1, backInWebviewCalls);
   });
 
-  test(assert(inline_login_test.TestNames.OkButton), () => {
+  test(inline_login_test.TestNames.OkButton, () => {
     // 'OK' button should be hidden.
     assertTrue(inlineLoginComponent.shadowRoot!
                    .querySelector<HTMLElement>('.next-button')!.hidden);
diff --git a/chrome/test/data/webui/inline_login/inline_login_welcome_page_test.ts b/chrome/test/data/webui/inline_login/inline_login_welcome_page_test.ts
index bb9544e..251be66b 100644
--- a/chrome/test/data/webui/inline_login/inline_login_welcome_page_test.ts
+++ b/chrome/test/data/webui/inline_login/inline_login_welcome_page_test.ts
@@ -7,7 +7,6 @@
 import {AccountAdditionOptions} from 'chrome://chrome-signin/arc_account_picker/arc_util.js';
 import {InlineLoginAppElement, View} from 'chrome://chrome-signin/inline_login_app.js';
 import {InlineLoginBrowserProxyImpl} from 'chrome://chrome-signin/inline_login_browser_proxy.js';
-import {assert} from 'chrome://resources/js/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -59,7 +58,7 @@
   });
 
   test(
-      assert(inline_login_welcome_page_test.TestNames.Reauthentication), () => {
+      inline_login_welcome_page_test.TestNames.Reauthentication, () => {
         testSetup(/*dialogArgs=*/ null);
         webUIListenerCallback(
             'load-auth-extension', fakeAuthExtensionDataWithEmail);
@@ -69,7 +68,7 @@
             'Welcome screen should be active');
       });
 
-  test(assert(inline_login_welcome_page_test.TestNames.OkButton), () => {
+  test(inline_login_welcome_page_test.TestNames.OkButton, () => {
     testSetup(/*dialogArgs=*/ null);
     webUIListenerCallback('load-auth-extension', fakeAuthExtensionData);
     const okButton =
@@ -96,7 +95,7 @@
     });
   });
 
-  test(assert(inline_login_welcome_page_test.TestNames.Checkbox), () => {
+  test(inline_login_welcome_page_test.TestNames.Checkbox, () => {
     testSetup(/*dialogArgs=*/ null);
 
     webUIListenerCallback('load-auth-extension', fakeAuthExtensionData);
@@ -119,7 +118,7 @@
     });
   });
 
-  test(assert(inline_login_welcome_page_test.TestNames.GoBack), () => {
+  test(inline_login_welcome_page_test.TestNames.GoBack, () => {
     testSetup(/*dialogArgs=*/ null);
     webUIListenerCallback('load-auth-extension', fakeAuthExtensionData);
     const backButton =
@@ -151,7 +150,7 @@
   });
 
   test(
-      assert(inline_login_welcome_page_test.TestNames.IsAvailableInArc), () => {
+      inline_login_welcome_page_test.TestNames.IsAvailableInArc, () => {
         const dialogArgs = {
           isAvailableInArc: true,
           showArcAvailabilityPicker: false,
@@ -175,7 +174,7 @@
         });
       });
 
-  test(assert(inline_login_welcome_page_test.TestNames.ToggleHidden), () => {
+  test(inline_login_welcome_page_test.TestNames.ToggleHidden, () => {
     const dialogArgs = {
       isAvailableInArc: true,
       showArcAvailabilityPicker: true,
@@ -190,7 +189,7 @@
     assertTrue(toggle.hidden, 'ARC toggle should be hidden');
   });
 
-  test(assert(inline_login_welcome_page_test.TestNames.LinkClick), async () => {
+  test(inline_login_welcome_page_test.TestNames.LinkClick, async () => {
     const dialogArgs = {
       isAvailableInArc: true,
       showArcAvailabilityPicker: false,
diff --git a/chrome/test/data/webui/password_manager/BUILD.gn b/chrome/test/data/webui/password_manager/BUILD.gn
index 4e0afc0..fe370e4 100644
--- a/chrome/test/data/webui/password_manager/BUILD.gn
+++ b/chrome/test/data/webui/password_manager/BUILD.gn
@@ -27,6 +27,7 @@
     "password_manager_routing_test.ts",
     "password_manager_side_bar_test.ts",
     "passwords_section_test.ts",
+    "password_details_section_test.ts",
     "settings_section_test.ts",
     "test_password_manager_proxy.ts",
     "test_prefs_browser_proxy.ts",
diff --git a/chrome/test/data/webui/password_manager/password_details_section_test.ts b/chrome/test/data/webui/password_manager/password_details_section_test.ts
new file mode 100644
index 0000000..0204be57
--- /dev/null
+++ b/chrome/test/data/webui/password_manager/password_details_section_test.ts
@@ -0,0 +1,89 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://password-manager/password_manager.js';
+
+import {Page, PasswordDetailsSectionElement, PasswordManagerImpl, Router} from 'chrome://password-manager/password_manager.js';
+import {assertEquals, 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';
+import {createCredentialGroup} from './test_util.js';
+
+suite('PasswordDetailsSectionTest', function() {
+  let passwordManager: TestPasswordManagerProxy;
+
+  setup(function() {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    passwordManager = new TestPasswordManagerProxy();
+    PasswordManagerImpl.setInstance(passwordManager);
+    Router.getInstance().navigateTo(Page.PASSWORDS);
+    return flushTasks();
+  });
+
+  test('Navigation from passwords section', async function() {
+    const section: PasswordDetailsSectionElement =
+        document.createElement('password-details-section');
+    document.body.appendChild(section);
+    await flushTasks();
+
+    // Simulate navigation from passwords list.
+    const group = createCredentialGroup({name: 'test.com'});
+    Router.getInstance().navigateTo(Page.PASSWORD_DETAILS, group);
+
+    const title = section.shadowRoot!.querySelector('#title');
+    assertTrue(!!title);
+    assertEquals(group.name, title.textContent!.trim());
+  });
+
+  test('Navigating directly', async function() {
+    // Simulate direct navigation.
+    Router.getInstance().navigateTo(Page.PASSWORD_DETAILS, 'test.com');
+    passwordManager.data.groups = [
+      createCredentialGroup({name: 'test.com'}),
+      createCredentialGroup({name: 'test1.com'}),
+      createCredentialGroup({name: 'test2.com'}),
+    ];
+
+    const section: PasswordDetailsSectionElement =
+        document.createElement('password-details-section');
+    document.body.appendChild(section);
+    await passwordManager.whenCalled('getCredentialGroups');
+    await flushTasks();
+
+    const title = section.$.title;
+    assertTrue(!!title);
+    assertEquals('test.com', title.textContent!.trim());
+  });
+
+  test('Navigating directly fails when group is not found', async function() {
+    // Simulate direct navigation.
+    Router.getInstance().navigateTo(Page.PASSWORD_DETAILS, 'test.com');
+    assertEquals(Page.PASSWORD_DETAILS, Router.getInstance().currentRoute.page);
+
+    const section: PasswordDetailsSectionElement =
+        document.createElement('password-details-section');
+    document.body.appendChild(section);
+    await passwordManager.whenCalled('getCredentialGroups');
+    await flushTasks();
+
+    assertEquals(Page.PASSWORDS, Router.getInstance().currentRoute.page);
+  });
+
+  test('Clicking back navigates to passwords section', async function() {
+    const group = createCredentialGroup({name: 'test.com'});
+    Router.getInstance().navigateTo(Page.PASSWORD_DETAILS, group);
+
+    const section: PasswordDetailsSectionElement =
+        document.createElement('password-details-section');
+    document.body.appendChild(section);
+    await flushTasks();
+
+    const backButton = section.$.backButton;
+
+    assertEquals(Page.PASSWORD_DETAILS, Router.getInstance().currentRoute.page);
+    backButton.click();
+    assertEquals(Page.PASSWORDS, Router.getInstance().currentRoute.page);
+  });
+});
diff --git a/chrome/test/data/webui/password_manager/password_manager_browsertest.js b/chrome/test/data/webui/password_manager/password_manager_browsertest.js
index bdc0519..218d5e2 100644
--- a/chrome/test/data/webui/password_manager/password_manager_browsertest.js
+++ b/chrome/test/data/webui/password_manager/password_manager_browsertest.js
@@ -34,6 +34,7 @@
  ['SideBar', 'password_manager_side_bar_test.js'],
  ['Settings', 'settings_section_test.js'],
  ['Routing', 'password_manager_routing_test.js'],
+ ['PasswordDetails', 'password_details_section_test.js'],
  ['Checkup', 'checkup_section_test.js'],
  ['PasswordsSection', 'passwords_section_test.js'],
 ].forEach(test => registerTest(...test));
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 7e2dcdb..006705ec 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
@@ -3,9 +3,13 @@
 // found in the LICENSE file.
 
 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_combined_dialog_app.js';
 
+import {PrivacySandboxCombinedDialogAppElement, PrivacySandboxCombinedDialogStep} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_combined_dialog_app.js';
 import {PrivacySandboxDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_app.js';
 import {PrivacySandboxDialogBrowserProxy, PrivacySandboxPromptAction} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_browser_proxy.js';
+import {PrivacySandboxNoticeDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_dialog_app.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
@@ -37,9 +41,10 @@
   let page: PrivacySandboxDialogAppElement;
   let browserProxy: TestPrivacySandboxDialogBrowserProxy;
 
-  function testClickButton(buttonSelector: string) {
+  function testClickButton(
+      buttonSelector: string, element: HTMLElement = page) {
     const actionButton =
-        page.shadowRoot!.querySelector(buttonSelector) as CrButtonElement;
+        element.shadowRoot!.querySelector(buttonSelector) as CrButtonElement;
     actionButton.click();
   }
 
@@ -197,3 +202,229 @@
     assertEquals(action, PrivacySandboxPromptAction.NOTICE_DISMISS);
   });
 });
+
+suite('PrivacySandboxDialogCombined', function() {
+  let page: PrivacySandboxCombinedDialogAppElement;
+  let browserProxy: TestPrivacySandboxDialogBrowserProxy;
+
+  function testClickButton(
+      buttonSelector: string, element: HTMLElement|null = page) {
+    const actionButton =
+        element!.shadowRoot!.querySelector(buttonSelector) as CrButtonElement;
+    actionButton.click();
+  }
+
+  async function verifyActionOccured(targetAction: PrivacySandboxPromptAction) {
+    const [action] = await browserProxy.whenCalled('promptActionOccurred');
+    assertEquals(action, targetAction);
+    browserProxy.reset();
+  }
+
+  function getActiveStep(): HTMLElement|null {
+    return page.shadowRoot!.querySelector('.active');
+  }
+
+  setup(async function() {
+    browserProxy = new TestPrivacySandboxDialogBrowserProxy();
+    PrivacySandboxDialogBrowserProxy.setInstance(browserProxy);
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    page = document.createElement('privacy-sandbox-combined-dialog-app');
+    page.disableAnimationsForTesting();
+    document.body.appendChild(page);
+
+    await browserProxy.whenCalled('resizeDialog');
+    await browserProxy.whenCalled('showDialog');
+  });
+
+  test('acceptConsentAndAckNotice', async function() {
+    // Verify that dialog starts with consent step.
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_SHOWN);
+    const consentStep: HTMLElement|null = getActiveStep();
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.CONSENT);
+
+    // Accept the consent step.
+    testClickButton('#confirmButton', consentStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_ACCEPTED);
+
+    // Resolving consent step triggers saving step.
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.SAVING);
+
+    // After saving step has ended (with a delay), the notice is shown.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(noticeStep!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Acknowledge the notice.
+    testClickButton('#ackButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
+  });
+
+  test('acceptConsentAndOpenSettings', async function() {
+    // Verify that dialog starts with consent step.
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_SHOWN);
+    const consentStep: HTMLElement|null = getActiveStep();
+    assertEquals(consentStep!.id, PrivacySandboxCombinedDialogStep.CONSENT);
+
+    // Accept the consent step.
+    testClickButton('#confirmButton', consentStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_ACCEPTED);
+
+    // Resolving consent step triggers saving step.
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.SAVING);
+
+    // After saving step has ended (with a delay), the notice is shown.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Click 'Open settings' button.
+    testClickButton('#settingsButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_OPEN_SETTINGS);
+  });
+
+  test('declineConsentAndAckNotice', async function() {
+    // Verify that dialog starts with consent step.
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_SHOWN);
+    const consentStep: HTMLElement|null = getActiveStep();
+    assertEquals(consentStep!.id, PrivacySandboxCombinedDialogStep.CONSENT);
+
+    // Decline the consent step.
+    testClickButton('#declineButton', consentStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_DECLINED);
+
+    // Resolving consent step triggers saving step.
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.SAVING);
+
+    // After saving step has ended (with a delay), the notice is shown.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(noticeStep!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Acknowledge the notice.
+    testClickButton('#ackButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
+  });
+
+  test('declineConsentAndOpenSettings', async function() {
+    // Verify that dialog starts with consent step.
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_SHOWN);
+    const consentStep: HTMLElement|null = getActiveStep();
+    assertEquals(consentStep!.id, PrivacySandboxCombinedDialogStep.CONSENT);
+
+    // Decline the consent step.
+    testClickButton('#declineButton', consentStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.CONSENT_DECLINED);
+
+    // Resolving consent step triggers saving step.
+    assertEquals(getActiveStep()!.id, PrivacySandboxCombinedDialogStep.SAVING);
+
+    // After saving step has ended (with a delay), the notice is shown.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(noticeStep!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Click 'Open settings' button.
+    testClickButton('#settingsButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_OPEN_SETTINGS);
+  });
+});
+
+suite('PrivacySandboxDialogNoticeEEA', function() {
+  let page: PrivacySandboxCombinedDialogAppElement;
+  let browserProxy: TestPrivacySandboxDialogBrowserProxy;
+
+  function testClickButton(
+      buttonSelector: string, element: HTMLElement|null = page) {
+    const actionButton =
+        element!.shadowRoot!.querySelector(buttonSelector) as CrButtonElement;
+    actionButton.click();
+  }
+
+  async function verifyActionOccured(targetAction: PrivacySandboxPromptAction) {
+    const [action] = await browserProxy.whenCalled('promptActionOccurred');
+    assertEquals(action, targetAction);
+    browserProxy.reset();
+  }
+
+  function getActiveStep(): HTMLElement|null {
+    return page.shadowRoot!.querySelector('.active');
+  }
+
+  setup(async function() {
+    browserProxy = new TestPrivacySandboxDialogBrowserProxy();
+    PrivacySandboxDialogBrowserProxy.setInstance(browserProxy);
+
+    window.history.replaceState({}, '', '?step=notice');
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    page = document.createElement('privacy-sandbox-combined-dialog-app');
+    page.disableAnimationsForTesting();
+    document.body.appendChild(page);
+
+    await browserProxy.whenCalled('resizeDialog');
+    await browserProxy.whenCalled('showDialog');
+  });
+
+  test('ackClicked', async function() {
+    // Verify that dialog starts with notice step.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(noticeStep!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Acknowledge the notice.
+    testClickButton('#ackButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
+  });
+
+  test('settingsClicked', async function() {
+    // Verify that dialog starts with notice step.
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    const noticeStep: HTMLElement|null = getActiveStep();
+    assertEquals(noticeStep!.id, PrivacySandboxCombinedDialogStep.NOTICE);
+
+    // Acknowledge the notice.
+    testClickButton('#settingsButton', noticeStep);
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_OPEN_SETTINGS);
+  });
+});
+
+suite('PrivacySandboxDialogNoticeROW', function() {
+  let page: PrivacySandboxNoticeDialogAppElement;
+  let browserProxy: TestPrivacySandboxDialogBrowserProxy;
+
+  function testClickButton(buttonSelector: string) {
+    const actionButton =
+        page.shadowRoot!.querySelector(buttonSelector) as CrButtonElement;
+    actionButton.click();
+  }
+
+  async function verifyActionOccured(targetAction: PrivacySandboxPromptAction) {
+    const [action] = await browserProxy.whenCalled('promptActionOccurred');
+    assertEquals(action, targetAction);
+    browserProxy.reset();
+  }
+
+  setup(async function() {
+    browserProxy = new TestPrivacySandboxDialogBrowserProxy();
+    PrivacySandboxDialogBrowserProxy.setInstance(browserProxy);
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    page = document.createElement('privacy-sandbox-notice-dialog-app');
+    document.body.appendChild(page);
+
+    await browserProxy.whenCalled('resizeDialog');
+    await browserProxy.whenCalled('showDialog');
+  });
+
+  test('ackClicked', async function() {
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    testClickButton('#ackButton');
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
+  });
+
+  test('settingsClicked', async function() {
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_SHOWN);
+    testClickButton('#settingsButton');
+    await verifyActionOccured(PrivacySandboxPromptAction.NOTICE_OPEN_SETTINGS);
+  });
+});
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index b02a47b..f3510a3 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -143,6 +143,7 @@
   "test_search_engines_browser_proxy.ts",
   "test_site_settings_prefs_browser_proxy.ts",
   "test_util.ts",
+  "trusted_html.ts",
   "zoom_levels_tests.ts",
 ]
 
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index 4142490..b9f14f2 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -44,6 +44,7 @@
 test_files = [
   "add_users_tests.js",
   "apn_subpage_tests.js",
+  "apn_detail_dialog_tests.js",
   "app_notifications_subpage_tests.js",
   "apps_page_test.js",
   "audio_and_captions_page_tests.js",
diff --git a/chrome/test/data/webui/settings/chromeos/OWNERS b/chrome/test/data/webui/settings/chromeos/OWNERS
index da5a446..cc68fe0 100644
--- a/chrome/test/data/webui/settings/chromeos/OWNERS
+++ b/chrome/test/data/webui/settings/chromeos/OWNERS
@@ -1,4 +1,6 @@
-file://chrome/browser/resources/settings/chromeos/OWNERS
+# This directory inherits its parents which allows any committer to approve
+# changes. Please review and approve changes related to your own team's code.
+# If you are not sure, or the changes would affect a different team from your
+# own, please select a Settings owner from file below.
 
-per-file *internet*=azeemarshad@chromium.org
-per-file *internet*=jonmann@chromium.org
+file://chrome/browser/resources/settings/chromeos/OWNERS
diff --git a/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_tests.js
new file mode 100644
index 0000000..e95e2b5
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_tests.js
@@ -0,0 +1,54 @@
+// 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.
+
+import 'chrome://os-settings/strings.m.js';
+import 'chrome://resources/ash/common/network/apn_detail_dialog.js';
+
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+
+import {assertEquals, assertTrue} from '../../../chai_assert.js';
+
+suite('ApnDetailDialog', function() {
+  /** @type {ApnDetalDialog} */
+  let apnDetailDialog = null;
+
+  setup(function() {
+    testing.Test.disableAnimationsAndTransitions();
+    PolymerTest.clearBody();
+    apnDetailDialog = document.createElement('apn-detail-dialog');
+    document.body.appendChild(apnDetailDialog);
+
+    return flushTasks();
+  });
+
+  teardown(function() {
+    return flushTasks().then(() => {
+      apnDetailDialog.remove();
+      apnDetailDialog = null;
+    });
+  });
+
+  test('Element contains dialog', function() {
+    const dialog = apnDetailDialog.shadowRoot.querySelector('cr-dialog');
+    assertTrue(!!dialog);
+    assertTrue(dialog.open);
+    // Confirm that the dialog has the add apn title.
+    assertEquals(
+        apnDetailDialog.i18n('apnDetailAddApnDialogTitle'),
+        apnDetailDialog.shadowRoot.querySelector('#apnDetailDialogTitle')
+            .innerText);
+  });
+
+  test('Clicking the cancel button fires the close event', async function() {
+    const closeEventPromise = eventToPromise('close', window);
+    const cancelBtn =
+        apnDetailDialog.shadowRoot.querySelector('#apnDetailCancelBtn');
+    assertTrue(!!cancelBtn);
+
+    cancelBtn.click();
+    await closeEventPromise;
+    assertFalse(!!apnDetailDialog.open);
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page_tests.js b/chrome/test/data/webui/settings/chromeos/internet_page_tests.js
index 8fbf7a1..021684c 100644
--- a/chrome/test/data/webui/settings/chromeos/internet_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/internet_page_tests.js
@@ -762,6 +762,32 @@
         'Apn subpage row should be focused');
   });
 
+  test(
+      'Create apn button opens dialogs and clicking cancel button removes it',
+      async function() {
+        loadTimeData.overrideValues({isApnRevampEnabled: true});
+        await init();
+        Router.getInstance().navigateTo(routes.APN);
+        await flushAsync();
+        const getApnDetailDialog = () =>
+            internetPage.shadowRoot.querySelector('apn-detail-dialog');
+
+        assertFalse(!!getApnDetailDialog());
+        const createCustomApnButton =
+            internetPage.shadowRoot.querySelector('#createCustomApnButton');
+        assertTrue(!!createCustomApnButton);
+        createCustomApnButton.click();
+        await flushAsync();
+
+        assertTrue(!!getApnDetailDialog());
+        const onCloseEventPromise = eventToPromise('close', window);
+        const cancelBtn = getApnDetailDialog().shadowRoot.querySelector(
+            '#apnDetailCancelBtn');
+        cancelBtn.click();
+        await onCloseEventPromise;
+
+        assertFalse(!!getApnDetailDialog());
+      });
   // TODO(stevenjb): Figure out a way to reliably test navigation. Currently
   // such tests are flaky.
 });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
index 48bda619..12a590c 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -325,6 +325,7 @@
 [['AccessibilityPage', 'os_a11y_page_tests.js'],
  ['AboutPage', 'os_about_page_tests.js'],
  ['AccountsPage', 'add_users_tests.js'],
+ ['ApnDetailDialog', 'apn_detail_dialog_tests.js'],
  ['AppsPage', 'apps_page_test.js'],
  ['AppNotificationsSubpage', 'app_notifications_subpage_tests.js'],
  ['AppManagementAppDetailsItem', 'app_management/app_details_item_test.js'],
diff --git a/chrome/test/data/webui/settings/idle_load_tests.ts b/chrome/test/data/webui/settings/idle_load_tests.ts
index 6c9aef2b..36bcf4d3 100644
--- a/chrome/test/data/webui/settings/idle_load_tests.ts
+++ b/chrome/test/data/webui/settings/idle_load_tests.ts
@@ -4,6 +4,8 @@
 
 // #clang-format off
 import 'chrome://settings/settings.js';
+
+import {getTrustedHTML} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 // #clang-format on
 
@@ -16,7 +18,7 @@
 
 suite('Settings idle load tests', function() {
   setup(function() {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedHTML`
       <settings-idle-load>
         <template>
           <div></div>
diff --git a/chrome/test/data/webui/settings/privacy_page_test.ts b/chrome/test/data/webui/settings/privacy_page_test.ts
index 781eea4..7609ae07 100644
--- a/chrome/test/data/webui/settings/privacy_page_test.ts
+++ b/chrome/test/data/webui/settings/privacy_page_test.ts
@@ -518,7 +518,7 @@
     Router.getInstance().navigateTo(routes.SITE_SETTINGS_NOTIFICATIONS);
     siteSettingsBrowserProxy = new TestSiteSettingsPrefsBrowserProxy();
     SiteSettingsPrefsBrowserProxyImpl.setInstance(siteSettingsBrowserProxy);
-    document.body.innerHTML = '';
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
   });
 
   teardown(function() {
diff --git a/chrome/test/data/webui/settings/search_settings_test.ts b/chrome/test/data/webui/settings/search_settings_test.ts
index 61ebd7d5..33e0397 100644
--- a/chrome/test/data/webui/settings/search_settings_test.ts
+++ b/chrome/test/data/webui/settings/search_settings_test.ts
@@ -4,9 +4,11 @@
 
 // clang-format off
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {BaseMixin, getSearchManager, SearchManager} from 'chrome://settings/settings.js';
+import {BaseMixin, getSearchManager, SearchManager, getTrustedHTML as getTrustedStaticHtml} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
+import {getTrustedHtml} from './trusted_html.js';
+
 // clang-format on
 
 suite('SearchSettingsTest', function() {
@@ -24,9 +26,10 @@
   test('normal highlighting', function() {
     const optionText = 'FooSettingsFoo';
 
-    document.body.innerHTML = `<settings-section hidden-by-search>
+    document.body.innerHTML =
+        getTrustedHtml(`<settings-section hidden-by-search>
            <div id="mydiv">${optionText}</div>
-         </settings-section>`;
+         </settings-section>`);
 
     const section = document.querySelector('settings-section')!;
     const div = document.querySelector('#mydiv')!;
@@ -66,7 +69,8 @@
    * bubble.
    */
   test('<select> highlighting', function() {
-    document.body.innerHTML = `<settings-section hidden-by-search>
+    document.body.innerHTML =
+        getTrustedStaticHtml`<settings-section hidden-by-search>
            <select>
              <option>Foo</option>
              <option>Settings</option>
@@ -99,7 +103,8 @@
 
   test('ignored elements are ignored', function() {
     const text = 'hello';
-    document.body.innerHTML = `<settings-section hidden-by-search>
+    document.body.innerHTML =
+        getTrustedHtml(`<settings-section hidden-by-search>
            <cr-action-menu>${text}</cr-action-menu>
            <cr-dialog>${text}</cr-dialog>
            <cr-icon-button>${text}</cr-icon-button>
@@ -113,7 +118,7 @@
            <content>${text}</content>
            <style>${text}</style>
            <template>${text}</template>
-         </settings-section>`;
+         </settings-section>`);
 
     const section = document.querySelector('settings-section')!;
     assertTrue(section.hiddenBySearch);
@@ -166,7 +171,8 @@
 
     const text = 'hello';
 
-    document.body.innerHTML = `<dummy-test-element></dummy-test-element>`;
+    document.body.innerHTML =
+        getTrustedStaticHtml`<dummy-test-element></dummy-test-element>`;
 
     const element =
         document.body.querySelector<DummyTestElement>('dummy-test-element')!;
@@ -197,7 +203,8 @@
   // Test that multiple requests for the same text correctly highlight their
   // corresponding part of the tree without affecting other parts of the tree.
   test('multiple simultaneous requests for the same text', function() {
-    document.body.innerHTML = `<settings-section hidden-by-search>
+    document.body.innerHTML =
+        getTrustedStaticHtml`<settings-section hidden-by-search>
            <div><span>Hello there</span></div>
          </settings-section>
          <settings-section hidden-by-search>
@@ -224,9 +231,10 @@
   test('highlight removed when text is changed', function() {
     const originalText = 'FooSettingsFoo';
 
-    document.body.innerHTML = `<settings-section hidden-by-search>
+    document.body.innerHTML =
+        getTrustedHtml(`<settings-section hidden-by-search>
           <div id="mydiv">${originalText}</div>
-        </settings-section>`;
+        </settings-section>`);
 
     const section = document.querySelector('settings-section')!;
     const div = document.querySelector('#mydiv')!;
@@ -253,7 +261,7 @@
   });
 
   test('match text outside of a settings section', async function() {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedStaticHtml`
         <div id="mydiv">Match</div>
         <settings-section></settings-section>`;
 
@@ -272,7 +280,7 @@
   });
 
   test('associated control causes search highlight bubble', async () => {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedStaticHtml`
         <settings-section>
           <button></button>
           <settings-subpage>
@@ -288,7 +296,7 @@
   });
 
   test('bubble result count', async () => {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedStaticHtml`
         <settings-section>
           <select>
             <option>nohello</option>
@@ -315,7 +323,7 @@
   });
 
   test('diacritics', async () => {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedStaticHtml`
         <settings-section>
           <select>
             <option>año de oro</option>
diff --git a/chrome/test/data/webui/settings/settings_animated_pages_test.ts b/chrome/test/data/webui/settings/settings_animated_pages_test.ts
index b4416fb..53b4c01b 100644
--- a/chrome/test/data/webui/settings/settings_animated_pages_test.ts
+++ b/chrome/test/data/webui/settings/settings_animated_pages_test.ts
@@ -8,6 +8,7 @@
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 import {setupPopstateListener} from './test_util.js';
+import {getTrustedHtml} from './trusted_html.js';
 
 // clang-format on
 
@@ -46,13 +47,13 @@
   // Test simple case where the |focusConfig| key captures only the previous
   // route.
   test('FocusSubpageTrigger_SimpleKey', async function() {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedHtml(`
       <settings-animated-pages section="${testRoutes.SEARCH_ENGINES.section}">
         <div route-path="default">
           <button id="subpage-trigger"></button>
         </div>
         <div route-path="${testRoutes.SEARCH_ENGINES.path}"></div>
-      </settings-animated-pages>`;
+      </settings-animated-pages>`);
 
     const animatedPages =
         document.body.querySelector('settings-animated-pages')!;
@@ -75,7 +76,7 @@
   // route, to differentiate cases where a subpage can have multiple entry
   // points.
   test('FocusSubpageTrigger_FromToKey', async function() {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedHtml(`
       <settings-animated-pages section="${testRoutes.PRIVACY.section}">
         <div route-path="default">
           <button id="subpage-trigger1"></button>
@@ -84,7 +85,7 @@
           <button id="subpage-trigger2"></button>
         </div>
         <div route-path="${testRoutes.SITE_SETTINGS_COOKIES.path}"></div>
-      </settings-animated-pages>`;
+      </settings-animated-pages>`);
 
     const animatedPages =
         document.body.querySelector('settings-animated-pages')!;
@@ -121,13 +122,13 @@
   });
 
   test('IgnoresBubblingIronSelect', async function() {
-    document.body.innerHTML = `
+    document.body.innerHTML = getTrustedHtml(`
       <settings-animated-pages section="${testRoutes.PRIVACY.section}">
         <div route-path="default"></div>
         <settings-subpage route-path="${testRoutes.SITE_SETTINGS.path}">
           <div></div>
         </settings-subpage>
-      </settings-animated-pages>`;
+      </settings-animated-pages>`);
 
     const subpage = document.body.querySelector('settings-subpage')!;
     let counter = 0;
diff --git a/chrome/test/data/webui/settings/settings_performance_menu_test.ts b/chrome/test/data/webui/settings/settings_performance_menu_test.ts
index 233bcb1..60f625c7 100644
--- a/chrome/test/data/webui/settings/settings_performance_menu_test.ts
+++ b/chrome/test/data/webui/settings/settings_performance_menu_test.ts
@@ -16,7 +16,7 @@
   }
 
   setup(function() {
-    document.body.innerHTML = '';
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
     Router.getInstance().navigateTo(routes.PERFORMANCE, undefined);
     settingsMenu = document.createElement('settings-menu');
     settingsMenu.pageVisibility = pageVisibility;
@@ -54,4 +54,4 @@
         getPerformanceMenuItem()!.hidden,
         'performance menu item should be hidden when pageVisibility is false');
   });
-});
\ No newline at end of file
+});
diff --git a/chrome/test/data/webui/settings/sync_test_util.ts b/chrome/test/data/webui/settings/sync_test_util.ts
index 22d3509..16b06711 100644
--- a/chrome/test/data/webui/settings/sync_test_util.ts
+++ b/chrome/test/data/webui/settings/sync_test_util.ts
@@ -27,6 +27,8 @@
   preferencesSynced: boolean;
   readingListRegistered: boolean;
   readingListSynced: boolean;
+  savedTabGroupsRegistered: boolean;
+  savedTabGroupsSynced: boolean;
   syncAllDataTypes: boolean;
   tabsRegistered: boolean;
   tabsSynced: boolean;
@@ -60,6 +62,8 @@
     preferencesSynced: true,
     readingListRegistered: true,
     readingListSynced: true,
+    savedTabGroupsRegistered: true,
+    savedTabGroupsSynced: true,
     syncAllDataTypes: true,
     tabsRegistered: true,
     tabsSynced: true,
diff --git a/chrome/test/data/webui/settings/trusted_html.ts b/chrome/test/data/webui/settings/trusted_html.ts
new file mode 100644
index 0000000..98d861a
--- /dev/null
+++ b/chrome/test/data/webui/settings/trusted_html.ts
@@ -0,0 +1,25 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Provides a way to create TrustedHTML for HTML code that is
+ * injected during tests and can't leverage
+ * ui/webui/resources/js/static_types.ts because the HTML is not fully static.
+ */
+
+let policy: TrustedTypePolicy|null = null;
+
+export function getTrustedHtml(html: string): TrustedHTML {
+  if (policy === null) {
+    policy = window.trustedTypes!.createPolicy('webui-test-html', {
+      // Policy only used in test code, no need for any sanitization. DO NOT use
+      // in prod code.
+      createHTML: html => html,
+      createScriptURL: () => '',
+      createScript: () => '',
+    });
+  }
+
+  return policy.createHTML(html);
+}
diff --git a/chrome/test/data/webui/test_browser_proxy.ts b/chrome/test/data/webui/test_browser_proxy.ts
index 1305dd8..ba342f7f 100644
--- a/chrome/test/data/webui/test_browser_proxy.ts
+++ b/chrome/test/data/webui/test_browser_proxy.ts
@@ -41,13 +41,13 @@
  * });
  * --------------------------------------------------------------------------
  */
-export class TestBrowserProxy {
-  private resolverMap_: Map<string, MethodData>;
+export class TestBrowserProxy<T = any> {
+  private resolverMap_: Map<keyof T, MethodData>;
 
   /**
    * @param methodNames Names of all methods whose calls need to be tracked.
    */
-  constructor(methodNames: string[] = []) {
+  constructor(methodNames: Array<keyof T> = []) {
     this.resolverMap_ = new Map();
     methodNames.forEach(methodName => {
       this.createMethodData_(methodName);
@@ -58,12 +58,14 @@
    * Creates a |TestBrowserProxy|, which has mock functions for all functions of
    * class |clazz|.
    */
-  static fromClass<T>(clazz: Constructor<T>): (T&TestBrowserProxy) {
-    const methodNames = Object.getOwnPropertyNames(clazz.prototype)
-                            .filter(methodName => methodName !== 'constructor');
-    const proxy = new TestBrowserProxy(methodNames);
+  static fromClass<T>(clazz: Constructor<T>): (T&TestBrowserProxy<T>) {
+    const methodNames =
+        Object.getOwnPropertyNames(clazz.prototype)
+            .filter(methodName => methodName !== 'constructor') as
+        Array<keyof T>;
+    const proxy = new TestBrowserProxy<T>(methodNames);
     proxy.mockMethods_(methodNames);
-    return proxy as unknown as (T&TestBrowserProxy);
+    return proxy as unknown as (T & TestBrowserProxy<T>);
   }
 
   /**
@@ -72,9 +74,9 @@
    * |setResultFor(methodName)|, or set a result mapper function that will be
    * invoked when a method is called using |setResultMapperFor(methodName)|.
    */
-  private mockMethods_(methodNames: string[]) {
+  private mockMethods_(methodNames: Array<keyof T>) {
     methodNames.forEach(methodName => {
-      (this as unknown as {[key: string]: Function})[methodName] =
+      (this as unknown as {[key in keyof T]: Function})[methodName] =
           (...args: any[]) => this.methodCalled(methodName, ...args);
     });
   }
@@ -87,7 +89,7 @@
    *     arguments.
    * @return If set the result registered via |setResult[Mapper]For|.
    */
-  methodCalled(methodName: string, ...args: any[]): any {
+  methodCalled(methodName: keyof T, ...args: any[]): any {
     const methodData = this.resolverMap_.get(methodName);
     assert(methodData);
     const storedArgs = args.length === 1 ? args[0] : args;
@@ -102,14 +104,14 @@
   /**
    * @return A promise that is resolved when the given method is called.
    */
-  whenCalled(methodName: string): Promise<any> {
+  whenCalled(methodName: keyof T): Promise<any> {
     return this.getMethodData_(methodName).resolver.promise;
   }
 
   /**
    * Resets the PromiseResolver associated with the given method.
    */
-  resetResolver(methodName: string) {
+  resetResolver(methodName: keyof T) {
     this.getMethodData_(methodName);
     this.createMethodData_(methodName);
   }
@@ -126,14 +128,14 @@
   /**
    * Get number of times method is called.
    */
-  getCallCount(methodName: string): number {
+  getCallCount(methodName: keyof T): number {
     return this.getMethodData_(methodName).args.length;
   }
 
   /**
    * Returns the arguments of calls made to |method|.
    */
-  getArgs(methodName: string): any[] {
+  getArgs(methodName: keyof T): any[] {
     return this.getMethodData_(methodName).args;
   }
 
@@ -143,21 +145,21 @@
    * object each method invovation or have the returned value be different based
    * on the arguments.
    */
-  setResultMapperFor(methodName: string, resultMapper: Function) {
+  setResultMapperFor(methodName: keyof T, resultMapper: Function) {
     this.getMethodData_(methodName).resultMapper = resultMapper;
   }
 
   /**
    * Sets the return value of a method.
    */
-  setResultFor(methodName: string, value: any) {
+  setResultFor(methodName: keyof T, value: any) {
     this.getMethodData_(methodName).resultMapper = () => value;
   }
 
   /**
    * Try to give programmers help with mistyped methodNames.
    */
-  private getMethodData_(methodName: string): MethodData {
+  private getMethodData_(methodName: keyof T): MethodData {
     // Tip: check that the |methodName| is being passed to |this.constructor|.
     const methodData = this.resolverMap_.get(methodName);
     assert(
@@ -168,7 +170,7 @@
   /**
    * Creates a new |MethodData| for |methodName|.
    */
-  private createMethodData_(methodName: string) {
+  private createMethodData_(methodName: keyof T) {
     this.resolverMap_.set(
         methodName, {resolver: new PromiseResolver(), args: []});
   }
diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc
index 5d59c94..14b9744 100644
--- a/chrome/updater/configurator.cc
+++ b/chrome/updater/configurator.cc
@@ -56,7 +56,14 @@
       unzip_factory_(
           base::MakeRefCounted<update_client::InProcessUnzipperFactory>()),
       patch_factory_(
-          base::MakeRefCounted<update_client::InProcessPatcherFactory>()) {}
+          base::MakeRefCounted<update_client::InProcessPatcherFactory>()) {
+#if BUILDFLAG(IS_LINUX)
+  // On Linux creating the NetworkFetcherFactory requires performing blocking IO
+  // to load an external library. This should be done when the configurator is
+  // created.
+  GetNetworkFetcherFactory();
+#endif
+}
 Configurator::~Configurator() = default;
 
 double Configurator::InitialDelay() const {
diff --git a/chrome/updater/mac/keystone/ksinstall.mm b/chrome/updater/mac/keystone/ksinstall.mm
index 3d0b4987..0c41721 100644
--- a/chrome/updater/mac/keystone/ksinstall.mm
+++ b/chrome/updater/mac/keystone/ksinstall.mm
@@ -27,6 +27,7 @@
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "chrome/updater/app/app.h"
 #include "chrome/updater/updater_scope.h"
+#include "chrome/updater/util/mac_util.h"
 #include "chrome/updater/util/util.h"
 
 namespace updater {
@@ -50,16 +51,31 @@
 };
 
 void KSInstallApp::Uninstall(base::OnceCallback<void(int)> callback) {
-  const absl::optional<base::FilePath>& keystone_path = GetKeystoneFolderPath(
-      (geteuid() == 0) ? UpdaterScope::kSystem : UpdaterScope::kUser);
-
-  if (!keystone_path) {
-    PLOG(ERROR) << "Couldn't find Keystone path.";
-    std::move(callback).Run(1);
-  }
   base::ThreadPool::PostTaskAndReplyWithResult(
-      FROM_HERE, {base::MayBlock()},
-      base::BindOnce(&base::DeletePathRecursively, *keystone_path),
+      FROM_HERE, {base::MayBlock()}, base::BindOnce([]() {
+        UpdaterScope scope =
+            (geteuid() == 0) ? UpdaterScope::kSystem : UpdaterScope::kUser;
+        const absl::optional<base::FilePath>& keystone_path =
+            GetKeystoneFolderPath(scope);
+
+        if (!keystone_path || !base::DeletePathRecursively(*keystone_path)) {
+          PLOG(ERROR) << "Couldn't find/delete Keystone path.";
+          return false;
+        }
+        if (scope == UpdaterScope::kSystem) {
+          return base::DeleteFile(
+              GetLibraryFolderPath(scope)
+                  ->Append("LaunchDaemons")
+                  .Append("com.google.keystone.daemon.plist"));
+        } else {
+          base::FilePath launch_agent_dir =
+              GetLibraryFolderPath(scope)->Append("LaunchAgents");
+          return base::DeleteFile(launch_agent_dir.Append(
+                     "com.google.keystone.agent.plist")) &&
+                 base::DeleteFile(launch_agent_dir.Append(
+                     "com.google.keystone.xpcservice.plist"));
+        }
+      }),
       base::BindOnce(
           [](base::OnceCallback<void(int)> cb, bool result) {
             if (result) {
diff --git a/chrome/updater/mac/setup/setup.mm b/chrome/updater/mac/setup/setup.mm
index e5ab90e6..24f34ba8 100644
--- a/chrome/updater/mac/setup/setup.mm
+++ b/chrome/updater/mac/setup/setup.mm
@@ -152,7 +152,8 @@
     @LAUNCH_JOBKEY_PROGRAMARGUMENTS : program_arguments,
     @LAUNCH_JOBKEY_MACHSERVICES : @{GetUpdateServiceMachName(scope) : @YES},
     @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @YES,
-    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope)
+    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope),
+    @"AssociatedBundleIdentifiers" : @MAC_BUNDLE_IDENTIFIER_STRING
   };
 
   return base::ScopedCFTypeRef<CFDictionaryRef>(
@@ -178,7 +179,8 @@
     @LAUNCH_JOBKEY_PROGRAMARGUMENTS : program_arguments,
     @LAUNCH_JOBKEY_STARTINTERVAL : @3600,
     @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @YES,
-    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope)
+    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope),
+    @"AssociatedBundleIdentifiers" : @MAC_BUNDLE_IDENTIFIER_STRING
   };
 
   return base::ScopedCFTypeRef<CFDictionaryRef>(
@@ -210,7 +212,8 @@
     @LAUNCH_JOBKEY_MACHSERVICES :
         @{GetUpdateServiceInternalMachName(scope) : @YES},
     @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @YES,
-    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope)
+    @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : NSStringSessionType(scope),
+    @"AssociatedBundleIdentifiers" : @MAC_BUNDLE_IDENTIFIER_STRING
   };
 
   return base::ScopedCFTypeRef<CFDictionaryRef>(
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
index b24e2d4..57ecf05f 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -83,6 +83,9 @@
     private final Controller<Unit> mStartedState = new Controller<>();
     // Tracks the most recent Intent for the Activity.
     private final Controller<Intent> mGotIntentState = new Controller<>();
+    // Tracks the most recent session id for the Activity. Derived from
+    // mGotIntentState.
+    private final Controller<String> mSessionIdState = new Controller<>();
     // Set this to cause the Activity to finish.
     private final Controller<String> mIsFinishingState = new Controller<>();
     // Set in unittests to skip some behavior.
@@ -142,6 +145,18 @@
             });
         });
 
+        mGotIntentState.map(Intent::getExtras)
+                .map(CastWebContentsIntentUtils::getSessionId)
+                .subscribe(Observers.onEnter(mSessionIdState::set));
+
+        mStartedState.and(mSessionIdState).subscribe(both -> {
+            sendVisibilityChanged(
+                    both.second, CastWebContentsIntentUtils.VISIBITY_TYPE_FULL_SCREEN);
+            return () -> {
+                sendVisibilityChanged(both.second, CastWebContentsIntentUtils.VISIBITY_TYPE_HIDDEN);
+            };
+        });
+
         // Set a flag to exit sleep mode when this activity starts.
         mCreatedState.and(mGotIntentState)
                 .map(Both::getSecond)
@@ -174,20 +189,6 @@
             finishAndRemoveTask();
         }));
 
-        mStartedState.subscribe(x -> {
-            Context ctx = getApplicationContext();
-            Intent intent = getIntent();
-            String instanceId = CastWebContentsIntentUtils.getSessionId(intent.getExtras());
-            Intent visible = CastWebContentsIntentUtils.onVisibilityChange(
-                    instanceId, CastWebContentsIntentUtils.VISIBITY_TYPE_FULL_SCREEN);
-            LocalBroadcastManager.getInstance(ctx).sendBroadcastSync(visible);
-            return () -> {
-                Intent hidden = CastWebContentsIntentUtils.onVisibilityChange(
-                        instanceId, CastWebContentsIntentUtils.VISIBITY_TYPE_HIDDEN);
-                LocalBroadcastManager.getInstance(ctx).sendBroadcastSync(hidden);
-            };
-        });
-
         // If a new Intent arrives after finishing, start a new Activity instead of recycling this.
         gotIntentAfterFinishingState.subscribe(Observers.onEnter((Intent intent) -> {
             Log.d(TAG, "Got intent while finishing current activity, so start new activity.");
@@ -215,6 +216,7 @@
     @Override
     protected void onNewIntent(Intent intent) {
         if (DEBUG) Log.d(TAG, "onNewIntent");
+        setIntent(intent);
         mGotIntentState.set(intent);
     }
 
@@ -229,6 +231,7 @@
     protected void onStop() {
         if (DEBUG) Log.d(TAG, "onStop");
         mStartedState.reset();
+
         // If this device is in "lock task mode," then leaving the Activity will not return to the
         // Home screen and there will be no affordance for the user to return to this Activity.
         // When in this mode, leaving the Activity should tear down the Cast app.
@@ -325,6 +328,13 @@
                 && !BuildInfo.getInstance().isTV;
     }
 
+    // Sends the specified visibility change event to the current app (as reported by getIntent()).
+    private void sendVisibilityChanged(String sessionId, @VisibilityType int visibilityType) {
+        Context ctx = getApplicationContext();
+        Intent event = CastWebContentsIntentUtils.onVisibilityChange(sessionId, visibilityType);
+        LocalBroadcastManager.getInstance(ctx).sendBroadcastSync(event);
+    }
+
     public void finishForTesting() {
         mIsFinishingState.set("Finish for testing");
     }
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 4734877..139ce94 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -3369,76 +3369,76 @@
       </message>
 
       <!-- Quick Answers -->
-      <message name="IDS_ASH_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the settings-button in Quick-Answers related views.">
+      <message name="IDS_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the settings-button in Quick-Answers related views.">
         Quick answers settings
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the phonetics-button in Quick-Answers related views.">
+      <message name="IDS_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the phonetics-button in Quick-Answers related views.">
         Listen
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the dogfood feedback button in Quick-Answers related views.">
+      <message name="IDS_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT" desc="Tootip text for the dogfood feedback button in Quick-Answers related views.">
         Send feedback
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_DEFINITION_INTENT" desc="Display text of definition intent. This is used in the title of Quick Answers user consent dialog.">
+      <message name="IDS_QUICK_ANSWERS_DEFINITION_INTENT" desc="Display text of definition intent. This is used in the title of Quick Answers user consent dialog.">
         definition
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_TRANSLATION_INTENT" desc="Display text of translation intent. This is used in the title of Quick Answers user consent dialog.">
+      <message name="IDS_QUICK_ANSWERS_TRANSLATION_INTENT" desc="Display text of translation intent. This is used in the title of Quick Answers user consent dialog.">
         translation
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_UNIT_CONVERSION_INTENT" desc="Display text of unit conversion intent. This is used in the title of Quick Answers user consent dialog.">
+      <message name="IDS_QUICK_ANSWERS_UNIT_CONVERSION_INTENT" desc="Display text of unit conversion intent. This is used in the title of Quick Answers user consent dialog.">
         conversion
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT" desc="Title text of the dialog that opens up to seek user-consent for the Quick Answers feature.">
+      <message name="IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT" desc="Title text of the dialog that opens up to seek user-consent for the Quick Answers feature.">
         Get info related to your selection
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT" desc="A11y alert text for the Quick Answers user notice view.">
+      <message name="IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT" desc="A11y alert text for the Quick Answers user notice view.">
         New feature available, use Up arrow key to learn more.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE" desc="A11y description template for the Quick Answers user notice view.">
+      <message name="IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE" desc="A11y description template for the Quick Answers user notice view.">
         <ph name="DESC_TEXT">$1<ex>With a right-click or a long press, Assistant shows info such as the definition, translation or unit conversion for your selection.</ex></ph> Use Left or Right arrow keys to manage this feature.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT" desc="Title text of the dialog that opens up to seek user-consent for the Quick Answers feature when supported intent is generated.">
+      <message name="IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT" desc="Title text of the dialog that opens up to seek user-consent for the Quick Answers feature when supported intent is generated.">
         Get the <ph name="intent">$1<ex>definition</ex></ph> for "<ph name="query">$2<ex>unfathomable</ex></ph>" and more
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT" desc="Description in the dialog that opens up to seek user-consent for the Quick Answers feature.">
+      <message name="IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT" desc="Description in the dialog that opens up to seek user-consent for the Quick Answers feature.">
         Get definitions, translations, or unit conversions when you right-click or touch &amp; hold text
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON" desc="Display text on the no thanks button in the dialog that opens up to seek user-consent for the Quick Answers feature.">
+      <message name="IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON" desc="Display text on the no thanks button in the dialog that opens up to seek user-consent for the Quick Answers feature.">
         No thanks
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON" desc="Display text on the allow button in the dialog that opens up to seek user-consent for the Quick Answers feature.">
+      <message name="IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON" desc="Display text on the allow button in the dialog that opens up to seek user-consent for the Quick Answers feature.">
         Allow
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_LOADING" desc="Display text when the Quick Answers view is loading.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_LOADING" desc="Display text when the Quick Answers view is loading.">
         Loading...
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_NETWORK_ERROR" desc="Display text when network error occurs in the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_NETWORK_ERROR" desc="Display text when network error occurs in the Quick Answers view.">
         Cannot connect to internet.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_RETRY" desc="Display text when the Quick Answers view is retry.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_RETRY" desc="Display text when the Quick Answers view is retry.">
         Retry
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_NO_RESULT_V2" desc="Display text when the Quick Answers view receives no result (V2 version).">
+      <message name="IDS_QUICK_ANSWERS_VIEW_NO_RESULT_V2" desc="Display text when the Quick Answers view receives no result (V2 version).">
         See result in Google Search
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT" desc="A11y alert text for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT" desc="A11y alert text for the Quick Answers view.">
         Info related to your selection available. Use Up arrow key to access.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2" desc="A11y description template for the Quick Answers view (V2 version).">
+      <message name="IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2" desc="A11y description template for the Quick Answers view (V2 version).">
         <ph name="QUERY_TEXT">$1<ex>interested</ex></ph>; <ph name="RESULT_TEXT">$2<ex>showing curiosity or concern about something or someone; having a feeling of interest.</ex></ph>; Press Search plus Space to see result in Google Search.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT" desc="A11y name text for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT" desc="A11y name text for the Quick Answers view.">
         Info related to your selection
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC" desc="A11y retry label description for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC" desc="A11y retry label description for the Quick Answers view.">
         Cannot connect to the internet. Click to try again.
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE" desc="A11y retry label name template for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE" desc="A11y retry label name template for the Quick Answers view.">
         <ph name="DESC_TEXT">$1<ex>Cannot connect to the internet. Click to try again.</ex></ph>: Retry
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL" desc="Description text of the report query button for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL" desc="Description text of the report query button for the Quick Answers view.">
         Internal only
       </message>
-      <message name="IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL" desc="Description text of the report query button for the Quick Answers view.">
+      <message name="IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL" desc="Description text of the report query button for the Quick Answers view.">
         Report this query
       </message>
       <!-- ARC SDK Version Labels-->
@@ -3644,6 +3644,9 @@
       <message name="IDS_SETTINGS_APN_MORE_ACTIONS_TITLE" desc="Description of the tree dotted menu for APNs">
         More actions
       </message>
+      <message name="IDS_SETTINGS_ADD_APN_DIALOG_TITLE" desc="Title for the dialog that creates a new custom APN">
+        Add a new APN
+      </message>
       <!-- End of APN -->
     </messages>
   </release>
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_DEFINITION_INTENT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_DEFINITION_INTENT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_DEFINITION_INTENT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_DEFINITION_INTENT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_DOGFOOD_FEEDBACK_BUTTON_TOOLTIP_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_PHONETICS_BUTTON_TOOLTIP_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_TRANSLATION_INTENT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_TRANSLATION_INTENT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_TRANSLATION_INTENT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_TRANSLATION_INTENT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_UNIT_CONVERSION_INTENT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_UNIT_CONVERSION_INTENT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_UNIT_CONVERSION_INTENT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_UNIT_CONVERSION_INTENT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_ALLOW_BUTTON.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_DESC_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_NO_THANKS_BUTTON.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_CONSENT_VIEW_TITLE_TEXT_WITH_INTENT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_A11Y_INFO_DESC_TEMPLATE.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_USER_NOTICE_VIEW_TITLE_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_ALERT_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_INFO_DESC_TEMPLATE_V2.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_DESC.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_A11Y_RETRY_LABEL_NAME_TEMPLATE.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_LOADING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_LOADING.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_LOADING.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_LOADING.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_NETWORK_ERROR.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_NETWORK_ERROR.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_NETWORK_ERROR.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_NETWORK_ERROR.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_NO_RESULT_V2.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_NO_RESULT_V2.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_NO_RESULT_V2.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_NO_RESULT_V2.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_INTERNAL_LABEL.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_REPORT_QUERY_REPORT_LABEL.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_RETRY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_RETRY.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_ASH_QUICK_ANSWERS_VIEW_RETRY.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_QUICK_ANSWERS_VIEW_RETRY.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_SETTINGS_ADD_APN_DIALOG_TITLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SETTINGS_ADD_APN_DIALOG_TITLE.png.sha1
new file mode 100644
index 0000000..8848af5c
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SETTINGS_ADD_APN_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@
+6a6f84e1f7cb9f895444eab60ca0c50d2dfaaa28
\ No newline at end of file
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 78b7403..115fde1 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -497,6 +497,7 @@
       "//components/media_router/browser/android:test_support_java",
       "//components/messages/android:java",
       "//components/messages/android:unit_tests",
+      "//components/metrics:metrics_java",
       "//components/offline_items_collection/core:native_java_unittests_java",
       "//components/paint_preview/browser/android:java",
       "//components/paint_preview/player/android:unit_tests",
@@ -916,6 +917,7 @@
         "//components/browser_ui/client_certificate/android",
         "//components/browser_ui/client_certificate/android:java",
         "//components/download/internal/common:internal_java",
+        "//components/metrics:metrics_java",
         "//components/version_info",
         "//content/public/test/android:android_test_message_pump_support_java",
         "//content/shell:content_shell_app",
diff --git a/components/attribution_reporting/BUILD.gn b/components/attribution_reporting/BUILD.gn
index 594b1f4..6a3a895 100644
--- a/components/attribution_reporting/BUILD.gn
+++ b/components/attribution_reporting/BUILD.gn
@@ -67,6 +67,7 @@
     "parsing_utils_unittest.cc",
     "source_registration_unittest.cc",
     "suitable_origin_unittest.cc",
+    "trigger_registration_unittest.cc",
   ]
 
   deps = [
diff --git a/components/attribution_reporting/aggregatable_trigger_data_unittest.cc b/components/attribution_reporting/aggregatable_trigger_data_unittest.cc
index 3be0add6..19af714 100644
--- a/components/attribution_reporting/aggregatable_trigger_data_unittest.cc
+++ b/components/attribution_reporting/aggregatable_trigger_data_unittest.cc
@@ -54,88 +54,126 @@
     base::Value json;
     base::expected<AggregatableTriggerData, TriggerRegistrationError> expected;
   } kTestCases[] = {
-      {"required_fields_only", base::test::ParseJson(R"json({
-         "key_piece": "0x1234",
-         "source_keys": ["abc"]
-       })json"),
-       *AggregatableTriggerData::Create(
-           /*key_piece=*/4660, /*source_keys=*/{"abc"},
-           /*filters=*/Filters(), /*not_filters=*/Filters())},
-      {"empty_source_keys", base::test::ParseJson(R"json({
-         "key_piece": "0x1234",
-         "source_keys": []
-       })json"),
-       *AggregatableTriggerData::Create(
-           /*key_piece=*/4660, /*source_keys=*/{},
-           /*filters=*/Filters(), /*not_filters=*/Filters())},
-      {"filters", base::test::ParseJson(R"json({
-         "key_piece": "0x1",
-         "source_keys": ["a", "b"],
-         "filters": {"a": ["b", "c"]}
-      })json"),
-       *AggregatableTriggerData::Create(
-           /*key_piece=*/1, /*source_keys=*/{"a", "b"},
-           /*filters=*/*Filters::Create({{"a", {"b", "c"}}}),
-           /*not_filters=*/Filters())},
-      {"not_filters", base::test::ParseJson(R"json({
-         "key_piece": "0x2",
-         "source_keys": ["a", "b"],
-         "not_filters": {"a": ["b", "c"]}
-      })json"),
-       *AggregatableTriggerData::Create(
-           /*key_piece=*/2, /*source_keys=*/{"a", "b"},
-           /*filters=*/Filters(),
-           /*not_filters=*/*Filters::Create({{"a", {"b", "c"}}}))},
-      {"not_dictionary", base::Value(base::Value::List()),
-       base::unexpected(
-           TriggerRegistrationError::kAggregatableTriggerDataWrongType)},
-      {"key_piece_missing", base::Value(base::Value::Dict()),
-       base::unexpected(
-           TriggerRegistrationError::kAggregatableTriggerDataKeyPieceMissing)},
-      {"key_piece_wrong_type",
-       base::test::ParseJson(R"json({"key_piece":123})json"),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataKeyPieceWrongType)},
-      {"key_piece_wrong_format",
-       base::test::ParseJson(R"json({"key_piece":"1234"})json"),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataKeyPieceWrongFormat)},
-      {"source_keys_missing",
-       base::test::ParseJson(R"json({"key_piece":"0x1234"})json"),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataSourceKeysMissing)},
-      {"source_keys_wrong_type",
-       base::test::ParseJson(
-           R"json({"key_piece":"0x1234", "source_keys":{}})json"),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataSourceKeysWrongType)},
-      {"source_keys_key_wrong_type",
-       base::test::ParseJson(
-           R"json({"key_piece":"0x1234", "source_keys":[123]})json"),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataSourceKeysKeyWrongType)},
-      {"source_keys_too_many_keys",
-       make_aggregatable_trigger_data_with_keys(
-           kMaxAggregationKeysPerSourceOrTrigger + 1),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataSourceKeysTooManyKeys)},
-      {"source_keys_key_too_long",
-       make_aggregatable_trigger_data_with_key_length(
-           kMaxBytesPerAggregationKeyId + 1),
-       base::unexpected(TriggerRegistrationError::
-                            kAggregatableTriggerDataSourceKeysKeyTooLong)},
-      {"filters_wrong_type", base::test::ParseJson(R"json({
-         "key_piece": "0x1",
-         "source_keys": ["abc"],
-         "filters": 123
-       })json"),
-       base::unexpected(TriggerRegistrationError::kFiltersWrongType)},
-      {"not_filters_wrong_type", base::test::ParseJson(R"json({
-         "key_piece": "0x1",
-         "source_keys": ["abc"],
-         "not_filters": 123
-       })json"),
-       base::unexpected(TriggerRegistrationError::kFiltersWrongType)},
+      {
+          "required_fields_only",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x1234",
+            "source_keys": ["abc"]
+          })json"),
+          *AggregatableTriggerData::Create(
+              /*key_piece=*/4660, /*source_keys=*/{"abc"},
+              /*filters=*/Filters(), /*not_filters=*/Filters()),
+      },
+      {
+          "empty_source_keys",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x1234",
+            "source_keys": []
+          })json"),
+          *AggregatableTriggerData::Create(
+              /*key_piece=*/4660, /*source_keys=*/{},
+              /*filters=*/Filters(), /*not_filters=*/Filters()),
+      },
+      {
+          "filters",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x1",
+            "source_keys": ["a", "b"],
+            "filters": {"a": ["b", "c"]}
+         })json"),
+          *AggregatableTriggerData::Create(
+              /*key_piece=*/1, /*source_keys=*/{"a", "b"},
+              /*filters=*/*Filters::Create({{"a", {"b", "c"}}}),
+              /*not_filters=*/Filters()),
+      },
+      {
+          "not_filters",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x2",
+            "source_keys": ["a", "b"],
+            "not_filters": {"a": ["b", "c"]}
+          })json"),
+          *AggregatableTriggerData::Create(
+              /*key_piece=*/2, /*source_keys=*/{"a", "b"},
+              /*filters=*/Filters(),
+              /*not_filters=*/*Filters::Create({{"a", {"b", "c"}}})),
+      },
+      {
+          "not_dictionary",
+          base::Value(base::Value::List()),
+          base::unexpected(
+              TriggerRegistrationError::kAggregatableTriggerDataWrongType),
+      },
+      {
+          "key_piece_missing",
+          base::Value(base::Value::Dict()),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataKeyPieceMissing),
+      },
+      {
+          "key_piece_wrong_type",
+          base::test::ParseJson(R"json({"key_piece":123})json"),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataKeyPieceWrongType),
+      },
+      {
+          "key_piece_wrong_format",
+          base::test::ParseJson(R"json({"key_piece":"1234"})json"),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataKeyPieceWrongFormat),
+      },
+      {
+          "source_keys_missing",
+          base::test::ParseJson(R"json({"key_piece":"0x1234"})json"),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataSourceKeysMissing),
+      },
+      {
+          "source_keys_wrong_type",
+          base::test::ParseJson(
+              R"json({"key_piece":"0x1234", "source_keys":{}})json"),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataSourceKeysWrongType),
+      },
+      {
+          "source_keys_key_wrong_type",
+          base::test::ParseJson(
+              R"json({"key_piece":"0x1234", "source_keys":[123]})json"),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataSourceKeysKeyWrongType),
+      },
+      {
+          "source_keys_too_many_keys",
+          make_aggregatable_trigger_data_with_keys(
+              kMaxAggregationKeysPerSourceOrTrigger + 1),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataSourceKeysTooManyKeys),
+      },
+      {
+          "source_keys_key_too_long",
+          make_aggregatable_trigger_data_with_key_length(
+              kMaxBytesPerAggregationKeyId + 1),
+          base::unexpected(TriggerRegistrationError::
+                               kAggregatableTriggerDataSourceKeysKeyTooLong),
+      },
+      {
+          "filters_wrong_type",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x1",
+            "source_keys": ["abc"],
+            "filters": 123
+          })json"),
+          base::unexpected(TriggerRegistrationError::kFiltersWrongType),
+      },
+      {
+          "not_filters_wrong_type",
+          base::test::ParseJson(R"json({
+            "key_piece": "0x1",
+            "source_keys": ["abc"],
+            "not_filters": 123
+          })json"),
+          base::unexpected(TriggerRegistrationError::kFiltersWrongType),
+      },
   };
 
   for (auto& test_case : kTestCases) {
diff --git a/components/attribution_reporting/aggregatable_values.cc b/components/attribution_reporting/aggregatable_values.cc
index 618690e..fd4e3bc 100644
--- a/components/attribution_reporting/aggregatable_values.cc
+++ b/components/attribution_reporting/aggregatable_values.cc
@@ -12,6 +12,7 @@
 #include "base/types/expected.h"
 #include "base/values.h"
 #include "components/attribution_reporting/constants.h"
+#include "components/attribution_reporting/parsing_utils.h"
 #include "components/attribution_reporting/trigger_registration_error.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -21,10 +22,6 @@
 
 using ::attribution_reporting::mojom::TriggerRegistrationError;
 
-bool KeyIdHasValidLength(const std::string& key) {
-  return key.size() <= kMaxBytesPerAggregationKeyId;
-}
-
 bool IsValueInRange(int value) {
   return value > 0 && value <= kMaxAggregatableValue;
 }
@@ -34,7 +31,8 @@
     return false;
 
   return base::ranges::all_of(values, [](const auto& value) {
-    return KeyIdHasValidLength(value.first) && IsValueInRange(value.second);
+    return AggregationKeyIdHasValidLength(value.first) &&
+           IsValueInRange(value.second);
   });
 }
 
@@ -68,7 +66,7 @@
   Values::container_type container;
 
   for (auto [id, key_value] : *dict) {
-    if (!KeyIdHasValidLength(id)) {
+    if (!AggregationKeyIdHasValidLength(id)) {
       return base::unexpected(
           TriggerRegistrationError::kAggregatableValuesKeyTooLong);
     }
diff --git a/components/attribution_reporting/aggregatable_values_unittest.cc b/components/attribution_reporting/aggregatable_values_unittest.cc
index 9791b1a1..667399f9 100644
--- a/components/attribution_reporting/aggregatable_values_unittest.cc
+++ b/components/attribution_reporting/aggregatable_values_unittest.cc
@@ -108,7 +108,7 @@
     return AggregatableValues::FromJSON(&value);
   };
 
-  for (size_t count = 0; count < 50; count++) {
+  for (size_t count = 0; count < 51; count++) {
     EXPECT_TRUE(parse_dict_with_key_count(count).has_value());
   }
 
diff --git a/components/attribution_reporting/aggregation_keys_unittest.cc b/components/attribution_reporting/aggregation_keys_unittest.cc
index 0d0bf145..41d9741 100644
--- a/components/attribution_reporting/aggregation_keys_unittest.cc
+++ b/components/attribution_reporting/aggregation_keys_unittest.cc
@@ -33,32 +33,59 @@
     absl::optional<base::Value> json;
     base::expected<AggregationKeys, SourceRegistrationError> expected;
   } kTestCases[] = {
-      {"Null", absl::nullopt, AggregationKeys()},
-      {"Not a dictionary", base::Value(base::Value::List()),
-       base::unexpected(SourceRegistrationError::kAggregationKeysWrongType)},
-      {"key not a string", base::test::ParseJson(R"({"key":123})"),
-       base::unexpected(
-           SourceRegistrationError::kAggregationKeysValueWrongType)},
-      {"key doesn't start with 0x", base::test::ParseJson(R"({"key":"159"})"),
-       base::unexpected(
-           SourceRegistrationError::kAggregationKeysValueWrongFormat)},
-      {"Invalid key", base::test::ParseJson(R"({"key":"0xG59"})"),
-       base::unexpected(
-           SourceRegistrationError::kAggregationKeysValueWrongFormat)},
-      {"One valid key", base::test::ParseJson(R"({"key":"0x159"})"),
-       *AggregationKeys::FromKeys(
-           {{"key", absl::MakeUint128(/*high=*/0, /*low=*/345)}})},
+      {
+          "Null",
+          absl::nullopt,
+          AggregationKeys(),
+      },
+      {
+          "Not a dictionary",
+          base::Value(base::Value::List()),
+          base::unexpected(SourceRegistrationError::kAggregationKeysWrongType),
+      },
+      {
+          "key not a string",
+          base::test::ParseJson(R"({"key":123})"),
+          base::unexpected(
+              SourceRegistrationError::kAggregationKeysValueWrongType),
+      },
+      {
+          "key doesn't start with 0x",
+          base::test::ParseJson(R"({"key":"159"})"),
+          base::unexpected(
+              SourceRegistrationError::kAggregationKeysValueWrongFormat),
+      },
+      {
+          "Invalid key",
+          base::test::ParseJson(R"({"key":"0xG59"})"),
+          base::unexpected(
+              SourceRegistrationError::kAggregationKeysValueWrongFormat),
+      },
+      {
+          "One valid key",
+          base::test::ParseJson(R"({"key":"0x159"})"),
+          *AggregationKeys::FromKeys(
+              {{"key", absl::MakeUint128(/*high=*/0, /*low=*/345)}}),
+      },
       {"Two valid keys",
        base::test::ParseJson(
            R"({"key1":"0x159","key2":"0x50000000000000159"})"),
        *AggregationKeys::FromKeys({
-           {"key1", absl::MakeUint128(/*high=*/0, /*low=*/345)},
-           {"key2", absl::MakeUint128(/*high=*/5, /*low=*/345)},
+           {
+               "key1",
+               absl::MakeUint128(/*high=*/0, /*low=*/345),
+           },
+           {
+               "key2",
+               absl::MakeUint128(/*high=*/5, /*low=*/345),
+           },
        })},
-      {"Second key invalid",
-       base::test::ParseJson(R"({"key1":"0x159","key2":""})"),
-       base::unexpected(
-           SourceRegistrationError::kAggregationKeysValueWrongFormat)},
+      {
+          "Second key invalid",
+          base::test::ParseJson(R"({"key1":"0x159","key2":""})"),
+          base::unexpected(
+              SourceRegistrationError::kAggregationKeysValueWrongFormat),
+      },
   };
 
   for (const auto& test_case : kTestCases) {
diff --git a/components/attribution_reporting/bounded_list.h b/components/attribution_reporting/bounded_list.h
index 264b8eb94..ff7de36 100644
--- a/components/attribution_reporting/bounded_list.h
+++ b/components/attribution_reporting/bounded_list.h
@@ -11,6 +11,9 @@
 #include <vector>
 
 #include "base/check_op.h"
+#include "base/functional/invoke.h"
+#include "base/types/expected.h"
+#include "base/values.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace attribution_reporting {
@@ -25,6 +28,27 @@
     return BoundedList(std::move(vec));
   }
 
+  template <typename Error, typename F>
+  static base::expected<BoundedList, Error> Build(base::Value::List& list,
+                                                  Error out_of_bounds,
+                                                  F&& build_element) {
+    if (list.size() > kMaxSize)
+      return base::unexpected(out_of_bounds);
+
+    std::vector<T> vec;
+    vec.reserve(list.size());
+
+    for (auto& value : list) {
+      base::expected<T, Error> element = base::invoke(build_element, value);
+      if (!element.has_value())
+        return base::unexpected(element.error());
+
+      vec.push_back(std::move(*element));
+    }
+
+    return BoundedList(std::move(vec));
+  }
+
   BoundedList() = default;
 
   const std::vector<T>& vec() const { return vec_; }
diff --git a/components/attribution_reporting/parsing_utils.cc b/components/attribution_reporting/parsing_utils.cc
index cad6a75..285d32e 100644
--- a/components/attribution_reporting/parsing_utils.cc
+++ b/components/attribution_reporting/parsing_utils.cc
@@ -61,4 +61,12 @@
   return ParseInt64(dict, "priority").value_or(0);
 }
 
+absl::optional<uint64_t> ParseDebugKey(const base::Value::Dict& dict) {
+  return ParseUint64(dict, "debug_key");
+}
+
+bool ParseDebugReporting(const base::Value::Dict& dict) {
+  return dict.FindBool("debug_reporting").value_or(false);
+}
+
 }  // namespace attribution_reporting
diff --git a/components/attribution_reporting/parsing_utils.h b/components/attribution_reporting/parsing_utils.h
index 8de7848..de33686 100644
--- a/components/attribution_reporting/parsing_utils.h
+++ b/components/attribution_reporting/parsing_utils.h
@@ -33,6 +33,10 @@
 
 int64_t ParsePriority(const base::Value::Dict& dict);
 
+absl::optional<uint64_t> ParseDebugKey(const base::Value::Dict& dict);
+
+bool ParseDebugReporting(const base::Value::Dict& dict);
+
 }  // namespace attribution_reporting
 
 #endif  // COMPONENTS_ATTRIBUTION_REPORTING_PARSING_UTILS_H_
diff --git a/components/attribution_reporting/source_registration.cc b/components/attribution_reporting/source_registration.cc
index 86cd048..1a1a643 100644
--- a/components/attribution_reporting/source_registration.cc
+++ b/components/attribution_reporting/source_registration.cc
@@ -82,21 +82,6 @@
   SourceRegistration result(std::move(*destination),
                             std::move(reporting_origin));
 
-  result.source_event_id =
-      ParseUint64(registration, "source_event_id").value_or(0);
-
-  result.priority = ParsePriority(registration);
-
-  result.expiry = ParseTimeDeltaInSeconds(registration, "expiry");
-
-  result.event_report_window =
-      ParseTimeDeltaInSeconds(registration, "event_report_window");
-
-  result.aggregatable_report_window =
-      ParseTimeDeltaInSeconds(registration, "aggregatable_report_window");
-
-  result.debug_key = ParseUint64(registration, "debug_key");
-
   base::expected<FilterData, SourceRegistrationError> filter_data =
       FilterData::FromJSON(registration.Find("filter_data"));
   if (!filter_data.has_value())
@@ -111,8 +96,22 @@
 
   result.aggregation_keys = std::move(*aggregation_keys);
 
-  result.debug_reporting =
-      registration.FindBool("debug_reporting").value_or(false);
+  result.source_event_id =
+      ParseUint64(registration, "source_event_id").value_or(0);
+
+  result.priority = ParsePriority(registration);
+
+  result.expiry = ParseTimeDeltaInSeconds(registration, "expiry");
+
+  result.event_report_window =
+      ParseTimeDeltaInSeconds(registration, "event_report_window");
+
+  result.aggregatable_report_window =
+      ParseTimeDeltaInSeconds(registration, "aggregatable_report_window");
+
+  result.debug_key = ParseDebugKey(registration);
+
+  result.debug_reporting = ParseDebugReporting(registration);
 
   return result;
 }
diff --git a/components/attribution_reporting/trigger_registration.cc b/components/attribution_reporting/trigger_registration.cc
index bd81a9a6..7395a96 100644
--- a/components/attribution_reporting/trigger_registration.cc
+++ b/components/attribution_reporting/trigger_registration.cc
@@ -6,12 +6,98 @@
 
 #include <utility>
 
+#include "base/types/expected.h"
+#include "base/values.h"
 #include "components/attribution_reporting/aggregatable_trigger_data.h"
+#include "components/attribution_reporting/aggregatable_values.h"
 #include "components/attribution_reporting/event_trigger_data.h"
+#include "components/attribution_reporting/filters.h"
+#include "components/attribution_reporting/parsing_utils.h"
 #include "components/attribution_reporting/suitable_origin.h"
+#include "components/attribution_reporting/trigger_registration_error.mojom.h"
 
 namespace attribution_reporting {
 
+namespace {
+
+using ::attribution_reporting::mojom::TriggerRegistrationError;
+
+base::expected<EventTriggerDataList, TriggerRegistrationError>
+ParseEventTriggerDataList(base::Value* value) {
+  if (!value)
+    return EventTriggerDataList();
+
+  base::Value::List* list = value->GetIfList();
+  if (!list) {
+    return base::unexpected(
+        TriggerRegistrationError::kEventTriggerDataListWrongType);
+  }
+
+  return EventTriggerDataList::Build(
+      *list, TriggerRegistrationError::kEventTriggerDataListTooLong,
+      &EventTriggerData::FromJSON);
+}
+
+base::expected<AggregatableTriggerDataList, TriggerRegistrationError>
+ParseAggregatableTriggerDataList(base::Value* value) {
+  if (!value)
+    return AggregatableTriggerDataList();
+
+  base::Value::List* list = value->GetIfList();
+  if (!list) {
+    return base::unexpected(
+        TriggerRegistrationError::kAggregatableTriggerDataListWrongType);
+  }
+
+  return AggregatableTriggerDataList::Build(
+      *list, TriggerRegistrationError::kAggregatableTriggerDataListTooLong,
+      &AggregatableTriggerData::FromJSON);
+}
+
+}  // namespace
+
+// static
+base::expected<TriggerRegistration, TriggerRegistrationError>
+TriggerRegistration::Parse(base::Value::Dict registration,
+                           SuitableOrigin reporting_origin) {
+  auto filters = Filters::FromJSON(registration.Find("filters"));
+  if (!filters.has_value())
+    return base::unexpected(filters.error());
+
+  auto not_filters = Filters::FromJSON(registration.Find("not_filters"));
+  if (!not_filters.has_value())
+    return base::unexpected(not_filters.error());
+
+  auto event_triggers =
+      ParseEventTriggerDataList(registration.Find("event_trigger_data"));
+  if (!event_triggers.has_value())
+    return base::unexpected(event_triggers.error());
+
+  auto aggregatable_trigger_data = ParseAggregatableTriggerDataList(
+      registration.Find("aggregatable_trigger_data"));
+  if (!aggregatable_trigger_data.has_value())
+    return base::unexpected(aggregatable_trigger_data.error());
+
+  auto aggregatable_values =
+      AggregatableValues::FromJSON(registration.Find("aggregatable_values"));
+  if (!aggregatable_values.has_value())
+    return base::unexpected(aggregatable_values.error());
+
+  absl::optional<uint64_t> debug_key = ParseDebugKey(registration);
+  absl::optional<uint64_t> aggregatable_dedup_key =
+      ParseUint64(registration, "aggregatable_deduplication_key");
+  bool debug_reporting = ParseDebugReporting(registration);
+
+  return TriggerRegistration(std::move(reporting_origin), std::move(*filters),
+                             std::move(*not_filters), debug_key,
+                             aggregatable_dedup_key, std::move(*event_triggers),
+                             std::move(*aggregatable_trigger_data),
+                             std::move(*aggregatable_values), debug_reporting);
+}
+
+TriggerRegistration::TriggerRegistration(SuitableOrigin reporting_origin)
+    : reporting_origin(std::move(reporting_origin)) {}
+
 TriggerRegistration::TriggerRegistration(
     SuitableOrigin reporting_origin,
     Filters filters,
diff --git a/components/attribution_reporting/trigger_registration.h b/components/attribution_reporting/trigger_registration.h
index 908ce51a..9a1c764 100644
--- a/components/attribution_reporting/trigger_registration.h
+++ b/components/attribution_reporting/trigger_registration.h
@@ -10,17 +10,25 @@
 #include <vector>
 
 #include "base/component_export.h"
+#include "base/types/expected.h"
+#include "base/values.h"
 #include "components/attribution_reporting/aggregatable_trigger_data.h"
 #include "components/attribution_reporting/aggregatable_values.h"
 #include "components/attribution_reporting/event_trigger_data.h"
 #include "components/attribution_reporting/filters.h"
 #include "components/attribution_reporting/suitable_origin.h"
+#include "components/attribution_reporting/trigger_registration_error.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace attribution_reporting {
 
 class COMPONENT_EXPORT(ATTRIBUTION_REPORTING) TriggerRegistration {
  public:
+  static base::expected<TriggerRegistration, mojom::TriggerRegistrationError>
+  Parse(base::Value::Dict, SuitableOrigin reporting_origin);
+
+  explicit TriggerRegistration(SuitableOrigin reporting_origin);
+
   TriggerRegistration(SuitableOrigin reporting_origin,
                       Filters filters,
                       Filters not_filters,
diff --git a/components/attribution_reporting/trigger_registration_error.mojom b/components/attribution_reporting/trigger_registration_error.mojom
index 260d49c6..d8c42f8 100644
--- a/components/attribution_reporting/trigger_registration_error.mojom
+++ b/components/attribution_reporting/trigger_registration_error.mojom
@@ -30,4 +30,10 @@
   kAggregatableTriggerDataSourceKeysKeyTooLong,
 
   kEventTriggerDataWrongType,
+
+  kEventTriggerDataListWrongType,
+  kEventTriggerDataListTooLong,
+
+  kAggregatableTriggerDataListWrongType,
+  kAggregatableTriggerDataListTooLong,
 };
diff --git a/components/attribution_reporting/trigger_registration_unittest.cc b/components/attribution_reporting/trigger_registration_unittest.cc
new file mode 100644
index 0000000..af6cf9f
--- /dev/null
+++ b/components/attribution_reporting/trigger_registration_unittest.cc
@@ -0,0 +1,279 @@
+// 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 "components/attribution_reporting/trigger_registration.h"
+
+#include <stddef.h>
+
+#include <string>
+#include <utility>
+
+#include "base/containers/flat_set.h"
+#include "base/functional/invoke.h"
+#include "base/test/values_test_util.h"
+#include "base/types/expected.h"
+#include "base/values.h"
+#include "components/attribution_reporting/aggregatable_trigger_data.h"
+#include "components/attribution_reporting/aggregatable_values.h"
+#include "components/attribution_reporting/constants.h"
+#include "components/attribution_reporting/event_trigger_data.h"
+#include "components/attribution_reporting/filters.h"
+#include "components/attribution_reporting/suitable_origin.h"
+#include "components/attribution_reporting/test_utils.h"
+#include "components/attribution_reporting/trigger_registration_error.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/numeric/int128.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace attribution_reporting {
+namespace {
+
+using ::attribution_reporting::mojom::TriggerRegistrationError;
+
+template <typename F>
+TriggerRegistration TriggerRegistrationWith(SuitableOrigin reporting_origin,
+                                            F&& f) {
+  TriggerRegistration r(std::move(reporting_origin));
+  base::invoke<F, TriggerRegistration&>(std::move(f), r);
+  return r;
+}
+
+TEST(TriggerRegistrationTest, Parse) {
+  const auto reporting_origin =
+      *SuitableOrigin::Deserialize("https://r.example");
+
+  const struct {
+    const char* description;
+    const char* json;
+    base::expected<TriggerRegistration, TriggerRegistrationError> expected;
+  } kTestCases[] = {
+      {
+          "empty",
+          R"json({})json",
+          TriggerRegistration(reporting_origin),
+      },
+      {
+          "filters_valid",
+          R"json({"filters":{"a":["b"]}})json",
+          TriggerRegistrationWith(
+              reporting_origin,
+              [](auto& r) {
+                r.filters = *Filters::Create({{"a", {"b"}}});
+              }),
+      },
+      {
+          "filters_wrong_type",
+          R"json({"filters": 5})json",
+          base::unexpected(TriggerRegistrationError::kFiltersWrongType),
+      },
+      {
+          "not_filters_valid",
+          R"json({"not_filters":{"a":["b"]}})json",
+          TriggerRegistrationWith(
+              reporting_origin,
+              [](auto& r) {
+                r.not_filters = *Filters::Create({{"a", {"b"}}});
+              }),
+      },
+      {
+          "not_filters_wrong_type",
+          R"json({"not_filters": 5})json",
+          base::unexpected(TriggerRegistrationError::kFiltersWrongType),
+      },
+      {
+          "debug_key_valid",
+          R"json({"debug_key":"5"})json",
+          TriggerRegistrationWith(reporting_origin,
+                                  [](auto& r) { r.debug_key = 5; }),
+      },
+      {
+          "debug_key_invalid",
+          R"json({"debug_key":"-5"})json",
+          TriggerRegistration(reporting_origin),
+      },
+      {
+          "debug_key_wrong_type",
+          R"json({"debug_key":5})json",
+          TriggerRegistration(reporting_origin),
+      },
+      {
+          "aggregatable_dedup_key_valid",
+          R"json({"aggregatable_deduplication_key":"10"})json",
+          TriggerRegistrationWith(
+              reporting_origin, [](auto& r) { r.aggregatable_dedup_key = 10; }),
+      },
+      {
+          "aggregatable_dedup_key_invalid",
+          R"json({"aggregatable_deduplication_key":"-10"})json",
+          TriggerRegistration(reporting_origin),
+      },
+      {
+          "aggregatable_dedup_key_wrong_type",
+          R"json({"aggregatable_deduplication_key": 10})json",
+          TriggerRegistration(reporting_origin),
+      },
+      {
+          "event_triggers_valid",
+          R"json({"event_trigger_data":[{}, {"trigger_data":"5"}]})json",
+          TriggerRegistrationWith(
+              reporting_origin,
+              [](auto& r) {
+                r.event_triggers = *EventTriggerDataList::Create(
+                    {EventTriggerData(),
+                     EventTriggerData(/*data=*/5, /*priority=*/0,
+                                      /*dedup_key=*/absl::nullopt,
+                                      /*filters=*/Filters(),
+                                      /*not_filters=*/Filters())});
+              }),
+      },
+      {
+          "event_triggers_wrong_type",
+          R"json({"event_trigger_data":{}})json",
+          base::unexpected(
+              TriggerRegistrationError::kEventTriggerDataListWrongType),
+      },
+      {
+          "event_trigger_data_wrong_type",
+          R"json({"event_trigger_data":["abc"]})json",
+          base::unexpected(
+              TriggerRegistrationError::kEventTriggerDataWrongType),
+      },
+      {
+          "aggregatable_trigger_data_valid",
+          R"json({
+          "aggregatable_trigger_data":[
+            {
+              "key_piece": "0x1",
+              "source_keys": ["a"]
+            },
+            {
+              "key_piece": "0x2",
+              "source_keys": ["b"]
+            }
+          ]
+        })json",
+          TriggerRegistrationWith(reporting_origin,
+                                  [](auto& r) {
+                                    r.aggregatable_trigger_data =
+                                        *AggregatableTriggerDataList::Create(
+                                            {*AggregatableTriggerData::Create(
+                                                 /*key_piece=*/1,
+                                                 /*source_keys=*/{"a"},
+                                                 /*filters=*/Filters(),
+                                                 /*not_filters=*/Filters()),
+                                             *AggregatableTriggerData::Create(
+                                                 /*key_piece=*/2,
+                                                 /*source_keys=*/{"b"},
+                                                 /*filters=*/Filters(),
+                                                 /*not_filters=*/Filters())});
+                                  }),
+      },
+      {
+          "aggregatable_trigger_data_list_wrong_type",
+          R"json({"aggregatable_trigger_data": {}})json",
+          base::unexpected(
+              TriggerRegistrationError::kAggregatableTriggerDataListWrongType),
+      },
+      {
+          "aggregatable_trigger_data_wrong_type",
+          R"json({"aggregatable_trigger_data":["abc"]})json",
+          base::unexpected(
+              TriggerRegistrationError::kAggregatableTriggerDataWrongType),
+      },
+      {
+          "aggregatable_values_valid",
+          R"json({"aggregatable_values":{"a":1}})json",
+          TriggerRegistrationWith(
+              reporting_origin,
+              [](auto& r) {
+                r.aggregatable_values = *AggregatableValues::Create({{"a", 1}});
+              }),
+      },
+      {
+          "aggregatable_values_wrong_type",
+          R"json({"aggregatable_values":123})json",
+          base::unexpected(
+              TriggerRegistrationError::kAggregatableValuesWrongType),
+      },
+      {
+          "debug_reporting_valid",
+          R"json({"debug_reporting": true})json",
+          TriggerRegistrationWith(reporting_origin,
+                                  [](auto& r) { r.debug_reporting = true; }),
+      },
+      {
+          "debug_reporting_wrong_type",
+          R"json({"debug_reporting":"true"})json",
+          TriggerRegistration(reporting_origin),
+      },
+  };
+
+  for (const auto& test_case : kTestCases) {
+    base::Value value = base::test::ParseJson(test_case.json);
+    EXPECT_EQ(TriggerRegistration::Parse(std::move(value.GetDict()),
+                                         reporting_origin),
+              test_case.expected)
+        << test_case.description;
+  }
+}
+
+TEST(TriggerRegistrationTest, Parse_EventTriggerDataCount) {
+  const auto reporting_origin =
+      *SuitableOrigin::Deserialize("https://r.example");
+
+  const auto parse_with_event_triggers = [&](size_t n) {
+    base::Value::List list;
+    for (size_t i = 0; i < n; ++i) {
+      list.Append(base::Value::Dict());
+    }
+
+    base::Value::Dict dict;
+    dict.Set("event_trigger_data", std::move(list));
+    return TriggerRegistration::Parse(std::move(dict), reporting_origin);
+  };
+
+  for (size_t count = 0; count <= kMaxEventTriggerData; ++count) {
+    EXPECT_TRUE(parse_with_event_triggers(count).has_value());
+  }
+
+  EXPECT_EQ(
+      parse_with_event_triggers(kMaxEventTriggerData + 1),
+      base::unexpected(TriggerRegistrationError::kEventTriggerDataListTooLong));
+}
+
+TEST(TriggerRegistrationTest, Parse_AggregatableTriggerDataCount) {
+  const auto reporting_origin =
+      *SuitableOrigin::Deserialize("https://r.example");
+
+  const auto parse_with_aggregatable_trigger_data = [&](size_t n) {
+    base::Value::List list;
+    for (size_t i = 0; i < n; ++i) {
+      base::Value::Dict data;
+      data.Set("key_piece", "0x1");
+
+      base::Value::List source_keys;
+      source_keys.Append("abc");
+      data.Set("source_keys", std::move(source_keys));
+
+      list.Append(std::move(data));
+    }
+
+    base::Value::Dict dict;
+    dict.Set("aggregatable_trigger_data", std::move(list));
+    return TriggerRegistration::Parse(std::move(dict), reporting_origin);
+  };
+
+  for (size_t count = 0; count <= kMaxAggregatableTriggerDataPerTrigger;
+       ++count) {
+    EXPECT_TRUE(parse_with_aggregatable_trigger_data(count).has_value());
+  }
+
+  EXPECT_EQ(parse_with_aggregatable_trigger_data(
+                kMaxAggregatableTriggerDataPerTrigger + 1),
+            base::unexpected(
+                TriggerRegistrationError::kAggregatableTriggerDataListTooLong));
+}
+
+}  // namespace
+}  // namespace attribution_reporting
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc
index db4c998..ef84c9381 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -64,6 +64,37 @@
   return {};
 }
 
+int GetObfuscationLength() {
+  // The kAutofillKeyboardAccessory feature is only available on Android. So for
+  // other platforms, we'd always use the obfuscation length of 4. This build
+  // flag also makes sure that tests involving kAutofillKeyboardAccessory
+  // feature is getting the correct obfuscation length.
+#if BUILDFLAG(IS_ANDROID)
+  return base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory) ? 2
+                                                                            : 4;
+#else
+  return 4;
+#endif
+}
+
+bool ShouldSplitCardNameAndLastFourDigits() {
+#if BUILDFLAG(IS_IOS)
+  return false;
+#elif BUILDFLAG(IS_ANDROID)
+  return base::FeatureList::IsEnabled(
+             features::kAutofillEnableVirtualCardMetadata) &&
+         base::FeatureList::IsEnabled(
+             features::kAutofillEnableCardProductName) &&
+         // TODO(crbug.com/1313616): Remove keyboard accessory check and merge
+         // Android with Desktop after the logic for truncation is implemented.
+         !base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory);
+#else
+  return base::FeatureList::IsEnabled(
+             features::kAutofillEnableVirtualCardMetadata) &&
+         base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName);
+#endif
+}
+
 }  // namespace
 
 AutofillSuggestionGenerator::AutofillSuggestionGenerator(
@@ -419,41 +450,7 @@
     bool card_linked_offer_available) const {
   DCHECK(type.group() == FieldTypeGroup::kCreditCard);
 
-  // The kAutofillKeyboardAccessory feature is only available on Android. So for
-  // other platforms, we'd always use the obfuscation_length of 4.
-  int obfuscation_length =
-      base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory) ? 2
-                                                                         : 4;
-
   Suggestion suggestion;
-  suggestion.main_text =
-      type.GetStorableType() == CREDIT_CARD_NUMBER
-          ? Suggestion::Text(credit_card.CardIdentifierStringForAutofillDisplay(
-                                 GetDisplayNicknameForCreditCard(credit_card),
-                                 obfuscation_length),
-                             Suggestion::Text::IsPrimary(true))
-          : Suggestion::Text(credit_card.GetInfo(type, app_locale),
-                             Suggestion::Text::IsPrimary(true));
-#if BUILDFLAG(IS_ANDROID)
-  if (!base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory) &&
-      base::FeatureList::IsEnabled(
-          features::kAutofillEnableVirtualCardMetadata) &&
-      base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName) &&
-      type.GetStorableType() == CREDIT_CARD_NUMBER) {
-    // For the Android dropdown, populate the card name (nickname/product
-    // description/network) and the last 4 digits separately to allow them to
-    // be shown in separate views. If the suggestion text overflows, only the
-    // card name gets truncated in the view.
-    suggestion.main_text =
-        Suggestion::Text(credit_card.CardNameForAutofillDisplay(
-                             GetDisplayNicknameForCreditCard(credit_card)),
-                         Suggestion::Text::IsPrimary(true));
-    suggestion.minor_text = Suggestion::Text(
-        credit_card.ObfuscatedLastFourDigits(obfuscation_length),
-        Suggestion::Text::IsPrimary(true));
-  }
-#endif
-
   suggestion.icon = credit_card.CardIconStringForAutofillSuggestion();
   suggestion.payload = Suggestion::BackendId(credit_card.guid());
   suggestion.match = prefix_matched_suggestion ? Suggestion::PREFIX_MATCH
@@ -463,13 +460,15 @@
   suggestion.is_icon_at_start = true;
 #endif  // BUILDFLAG(IS_ANDROID)
 
-  // TODO (crbug.com/1364155): For the Android dropdown, when card name + last 4
-  // digits appears on the second line, split it into card name
-  // (nickname/product name/network) and last 4 digits.
-  std::u16string card_label =
-      GetCardLabel(credit_card, type, app_locale, obfuscation_length);
-  if (!card_label.empty())
-    suggestion.labels = {{Suggestion::Text(std::move(card_label))}};
+  auto [main_text, minor_text] =
+      GetSuggestionMainTextAndMinorTextForCard(credit_card, type, app_locale);
+  suggestion.main_text = std::move(main_text);
+  suggestion.minor_text = std::move(minor_text);
+  if (std::vector<Suggestion::Text> card_labels =
+          GetSuggestionLabelsForCard(credit_card, type, app_locale);
+      !card_labels.empty()) {
+    suggestion.labels.push_back(std::move(card_labels));
+  }
 
   SetCardArtURL(suggestion, credit_card, virtual_card_option);
 
@@ -500,54 +499,115 @@
   return suggestion;
 }
 
-std::u16string AutofillSuggestionGenerator::GetCardLabel(
+std::pair<Suggestion::Text, Suggestion::Text>
+AutofillSuggestionGenerator::GetSuggestionMainTextAndMinorTextForCard(
     const CreditCard& credit_card,
     const AutofillType& type,
-    const std::string& app_locale,
-    int obfuscation_length) const {
+    const std::string& app_locale) const {
+  std::u16string main_text;
+  std::u16string minor_text;
+  if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
+    std::u16string nickname = GetDisplayNicknameForCreditCard(credit_card);
+    if (ShouldSplitCardNameAndLastFourDigits()) {
+      main_text = credit_card.CardNameForAutofillDisplay(nickname);
+      minor_text = credit_card.ObfuscatedLastFourDigits(GetObfuscationLength());
+    } else {
+      main_text = credit_card.CardIdentifierStringForAutofillDisplay(
+          nickname, GetObfuscationLength());
+    }
+  } else {
+    main_text = credit_card.GetInfo(type, app_locale);
+  }
+
+  return {Suggestion::Text(main_text, Suggestion::Text::IsPrimary(true),
+                           Suggestion::Text::ShouldTruncate(
+                               ShouldSplitCardNameAndLastFourDigits())),
+          // minor_text should also be shown in primary style, since it is also
+          // on the first line.
+          Suggestion::Text(minor_text, Suggestion::Text::IsPrimary(true))};
+}
+
+std::vector<Suggestion::Text>
+AutofillSuggestionGenerator::GetSuggestionLabelsForCard(
+    const CreditCard& credit_card,
+    const AutofillType& type,
+    const std::string& app_locale) const {
   DCHECK(type.group() == FieldTypeGroup::kCreditCard);
 
   // If the focused field is a card number field.
   if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
-    return credit_card.GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
-                               app_locale);
+    return {Suggestion::Text(credit_card.GetInfo(
+        AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale))};
 #else
-    return credit_card.DescriptiveExpiration(app_locale);
+    return {Suggestion::Text(
+        ShouldSplitCardNameAndLastFourDigits()
+            ? credit_card.GetInfo(
+                  AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale)
+            : credit_card.DescriptiveExpiration(app_locale))};
 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   }
 
   // If the focused field is not a card number field AND the card number is
   // empty (i.e. local cards added via settings page).
+  std::u16string nickname = GetDisplayNicknameForCreditCard(credit_card);
   if (credit_card.number().empty()) {
     DCHECK_EQ(credit_card.record_type(), CreditCard::LOCAL_CARD);
 
     if (credit_card.HasNonEmptyValidNickname())
-      return credit_card.nickname();
+      return {Suggestion::Text(nickname)};
 
     if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) {
-      return credit_card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL),
-                                 app_locale);
+      return {Suggestion::Text(credit_card.GetInfo(
+          AutofillType(CREDIT_CARD_NAME_FULL), app_locale))};
     }
-    return std::u16string();
+    return {};
   }
 
   // If the focused field is not a card number field AND the card number is NOT
   // empty.
 #if BUILDFLAG(IS_ANDROID)
   // On Android devices, the label is formatted as
-  // "Nickname/Network  ••••1234" when the keyboard accessory experiment
-  // is disabled and as "••1234" when it's enabled.
-  return base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory)
-             ? credit_card.ObfuscatedLastFourDigits(obfuscation_length)
-             : credit_card.CardIdentifierStringForAutofillDisplay(
-                   GetDisplayNicknameForCreditCard(credit_card));
+  // "Product Description/Nickname/Network  ••••1234" when the keyboard
+  // accessory experiment is disabled and as "••1234" when it's enabled.
+  // TODO(crbug.com/1313616): Remove keyboard accessory check after the logic
+  // for truncation is implemented.
+  if (base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory)) {
+    return {Suggestion::Text(
+        credit_card.ObfuscatedLastFourDigits(GetObfuscationLength()))};
+  }
+
+  // E.g. "Product Description/Nickname/Network  ••••1234". If card name is too
+  // long, it will be truncated from the tail.
+  if (ShouldSplitCardNameAndLastFourDigits()) {
+    return {Suggestion::Text(credit_card.CardNameForAutofillDisplay(nickname),
+                             Suggestion::Text::IsPrimary(false),
+                             Suggestion::Text::ShouldTruncate(true)),
+            Suggestion::Text(
+                credit_card.ObfuscatedLastFourDigits(GetObfuscationLength()))};
+  }
+  // E.g. "Nickname/Network  ••••1234".
+  return {Suggestion::Text(
+      credit_card.CardIdentifierStringForAutofillDisplay(nickname))};
+
 #elif BUILDFLAG(IS_IOS)
   // E.g. "••••1234"".
-  return credit_card.ObfuscatedLastFourDigits();
+  return {Suggestion::Text(
+      credit_card.ObfuscatedLastFourDigits(GetObfuscationLength()))};
+
 #else
-  // E.g. "Nickname/Network  ••••1234, expires on 01/25".
-  return credit_card.CardIdentifierStringAndDescriptiveExpiration(app_locale);
+  // E.g. "Product Description/Nickname/Network  ••••1234". If card name is too
+  // long, it will be truncated from the tail.
+  if (ShouldSplitCardNameAndLastFourDigits()) {
+    return {Suggestion::Text(credit_card.CardNameForAutofillDisplay(nickname),
+                             Suggestion::Text::IsPrimary(false),
+                             Suggestion::Text::ShouldTruncate(true)),
+            Suggestion::Text(
+                credit_card.ObfuscatedLastFourDigits(GetObfuscationLength()))};
+  }
+  // E.g. "Product Description/Nickname/Network  ••••1234, expires on 01/25".
+  return {Suggestion::Text(
+      credit_card.CardIdentifierStringAndDescriptiveExpiration(app_locale))};
 #endif
 }
 
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.h b/components/autofill/core/browser/autofill_suggestion_generator.h
index ac633fb..58a225e 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.h
+++ b/components/autofill/core/browser/autofill_suggestion_generator.h
@@ -133,12 +133,24 @@
   std::map<InternalId, Suggestion::BackendId> internal_to_backend_map_;
 
  private:
-  // Get the suggestion label for the `credit_card`. Note this does not account
+  // Return the texts shown as the first line of the suggestion, based on the
+  // `credit_card` and the focused field `type`. The first index in the pair
+  // represents the main text, and the second index represents the minor text.
+  // The minor text can be empty, in which case the main text should be rendered
+  // as the entire first line. If the minor text is not empty, they should be
+  // combined. This splitting is implemented for situations where the first part
+  // of the first line of the suggestion should be truncated.
+  std::pair<Suggestion::Text, Suggestion::Text>
+  GetSuggestionMainTextAndMinorTextForCard(const CreditCard& credit_card,
+                                           const AutofillType& type,
+                                           const std::string& app_locale) const;
+
+  // Return the labels to be shown in the suggestion. Note this does not account
   // for virtual cards or card-linked offers.
-  std::u16string GetCardLabel(const CreditCard& credit_card,
-                              const AutofillType& type,
-                              const std::string& app_locale,
-                              int obfuscation_length) const;
+  std::vector<Suggestion::Text> GetSuggestionLabelsForCard(
+      const CreditCard& credit_card,
+      const AutofillType& type,
+      const std::string& app_locale) const;
 
   // Adjust the content of |suggestion| if it is a virtual card suggestion.
   void AdjustVirtualCardSuggestionContent(Suggestion& suggestion,
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
index 419041357..bd24dbbde 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -400,10 +400,12 @@
 // Verify that the suggestion's texts are populated correctly for a virtual card
 // suggestion when the cardholder name field is focused.
 TEST_F(AutofillSuggestionGeneratorTest,
-       CreateCreditCardSuggestion_VirtualCardMetadata_VirtualCardNameField) {
+       CreateCreditCardSuggestion_VirtualCardMetadata_NameField) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      features::kAutofillEnableVirtualCardMetadata);
+  scoped_feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableVirtualCardMetadata,
+                            features::kAutofillEnableCardProductName},
+      /*disabled_features=*/{});
 
   // Create a server card.
   CreditCard server_card = CreateServerCard();
@@ -420,25 +422,19 @@
   EXPECT_EQ(virtual_card_name_field_suggestion.minor_text.value, u"");
 
   ASSERT_EQ(virtual_card_name_field_suggestion.labels.size(), 2U);
-  ASSERT_EQ(virtual_card_name_field_suggestion.labels[0].size(), 1U);
-#if BUILDFLAG(IS_ANDROID)
-  // For Android, the label is "Network  ....1234".
-  EXPECT_EQ(virtual_card_name_field_suggestion.labels[0][0].value,
-            base::StrCat({u"Visa  ", internal::GetObfuscatedStringForCardDigits(
-                                         u"1111", 4)}));
-#elif BUILDFLAG(IS_IOS)
+
+#if BUILDFLAG(IS_IOS)
   // For IOS, the label is "....1234".
+  ASSERT_EQ(virtual_card_name_field_suggestion.labels[0].size(), 1U);
   EXPECT_EQ(virtual_card_name_field_suggestion.labels[0][0].value,
             internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #else
-  // For Desktop, the label is the descriptive expiration date formatted as
-  // "Network  ....1234, expires on mm/yy".
-  EXPECT_EQ(
-      virtual_card_name_field_suggestion.labels[0][0].value,
-      base::StrCat({u"Visa  ",
-                    internal::GetObfuscatedStringForCardDigits(u"1111", 4),
-                    u", expires on ", base::UTF8ToUTF16(test::NextMonth()),
-                    u"/", base::UTF8ToUTF16(test::NextYear().substr(2))}));
+  // For Desktop/Android, the label is "CardName  ....1234". Card name and last
+  // four are shown separately.
+  ASSERT_EQ(virtual_card_name_field_suggestion.labels[0].size(), 2U);
+  EXPECT_EQ(virtual_card_name_field_suggestion.labels[0][0].value, u"Visa");
+  EXPECT_EQ(virtual_card_name_field_suggestion.labels[0][1].value,
+            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #endif
   // The virtual card text should be populated in the labels to be shown in a
   // new line.
@@ -450,12 +446,12 @@
 // Verify that the suggestion's texts are populated correctly for a virtual card
 // suggestion when the card number field is focused.
 TEST_F(AutofillSuggestionGeneratorTest,
-       CreateCreditCardSuggestion_VirtualCardMetadata_VirtualCardNumberField) {
+       CreateCreditCardSuggestion_VirtualCardMetadata_NumberField) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
-      /* enabled_features */ {features::kAutofillEnableVirtualCardMetadata,
-                              features::kAutofillEnableCardProductName},
-      /* disabled_features */ {});
+      /*enabled_features=*/{features::kAutofillEnableVirtualCardMetadata,
+                            features::kAutofillEnableCardProductName},
+      /*disabled_features=*/{});
 
   // Create a server card.
   CreditCard server_card = CreateServerCard();
@@ -467,18 +463,17 @@
           /*virtual_card_option=*/true,
           /*card_linked_offer_available=*/false);
 
-#if BUILDFLAG(IS_ANDROID)
-  // For Android, split the first line and populate card name, last 4 digits
-  // separately.
-  EXPECT_EQ(virtual_card_number_field_suggestion.main_text.value, u"Visa");
-  EXPECT_EQ(virtual_card_number_field_suggestion.minor_text.value,
-            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
-#else
+#if BUILDFLAG(IS_IOS)
   // Only card number is displayed on the first line.
   EXPECT_EQ(virtual_card_number_field_suggestion.main_text.value,
             base::StrCat({u"Visa  ", internal::GetObfuscatedStringForCardDigits(
                                          u"1111", 4)}));
   EXPECT_EQ(virtual_card_number_field_suggestion.minor_text.value, u"");
+#else
+  // Card name and the obfuscated last four digits are shown separately.
+  EXPECT_EQ(virtual_card_number_field_suggestion.main_text.value, u"Visa");
+  EXPECT_EQ(virtual_card_number_field_suggestion.minor_text.value,
+            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #endif
 
   // "Virtual card" is the label.
@@ -491,10 +486,12 @@
 // Verify that the suggestion's texts are populated correctly for a masked
 // server card suggestion when the cardholder name field is focused.
 TEST_F(AutofillSuggestionGeneratorTest,
-       CreateCreditCardSuggestion_VirtualCardMetadata_NonVirtualCardNameField) {
+       CreateCreditCardSuggestion_MaskedServerCardMetadata_NameField) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      features::kAutofillEnableVirtualCardMetadata);
+  scoped_feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableVirtualCardMetadata,
+                            features::kAutofillEnableCardProductName},
+      /*disabled_features=*/{});
 
   // Create a server card.
   CreditCard server_card = CreateServerCard();
@@ -510,43 +507,32 @@
   EXPECT_EQ(real_card_name_field_suggestion.main_text.value, u"Elvis Presley");
   EXPECT_EQ(real_card_name_field_suggestion.minor_text.value, u"");
 
-#if BUILDFLAG(IS_ANDROID)
-  // For Android, the label is "Network  ....1234".
-  ASSERT_EQ(real_card_name_field_suggestion.labels.size(), 1U);
-  ASSERT_EQ(real_card_name_field_suggestion.labels[0].size(), 1U);
-  EXPECT_EQ(real_card_name_field_suggestion.labels[0][0].value,
-            base::StrCat({u"Visa  ", internal::GetObfuscatedStringForCardDigits(
-                                         u"1111", 4)}));
-#elif BUILDFLAG(IS_IOS)
+#if BUILDFLAG(IS_IOS)
   // For IOS, the label is "....1234".
   ASSERT_EQ(real_card_name_field_suggestion.labels.size(), 1U);
   ASSERT_EQ(real_card_name_field_suggestion.labels[0].size(), 1U);
   EXPECT_EQ(real_card_name_field_suggestion.labels[0][0].value,
             internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #else
-  // For Desktop, the label is the descriptive expiration date formatted as
-  // "Network  ....1234, expires on mm/yy".
+  // For Desktop/Android, the label is "CardName  ....1234". Card name and last
+  // four are shown separately.
   ASSERT_EQ(real_card_name_field_suggestion.labels.size(), 1U);
-  ASSERT_EQ(real_card_name_field_suggestion.labels[0].size(), 1U);
-  EXPECT_EQ(
-      real_card_name_field_suggestion.labels[0][0].value,
-      base::StrCat({u"Visa  ",
-                    internal::GetObfuscatedStringForCardDigits(u"1111", 4),
-                    u", expires on ", base::UTF8ToUTF16(test::NextMonth()),
-                    u"/", base::UTF8ToUTF16(test::NextYear().substr(2))}));
+  ASSERT_EQ(real_card_name_field_suggestion.labels[0].size(), 2U);
+  EXPECT_EQ(real_card_name_field_suggestion.labels[0][0].value, u"Visa");
+  EXPECT_EQ(real_card_name_field_suggestion.labels[0][1].value,
+            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #endif
 }
 
 // Verify that the suggestion's texts are populated correctly for a masked
 // server card suggestion when the card number field is focused.
-TEST_F(
-    AutofillSuggestionGeneratorTest,
-    CreateCreditCardSuggestion_VirtualCardMetadata_NonVirtualCardNumberField) {
+TEST_F(AutofillSuggestionGeneratorTest,
+       CreateCreditCardSuggestion_MaskedServerCardMetadata_NumberField) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
-      /* enabled_features */ {features::kAutofillEnableVirtualCardMetadata,
-                              features::kAutofillEnableCardProductName},
-      /* disabled_features */ {});
+      /*enabled_features=*/{features::kAutofillEnableVirtualCardMetadata,
+                            features::kAutofillEnableCardProductName},
+      /*disabled_features=*/{});
 
   // Create a server card.
   CreditCard server_card = CreateServerCard();
@@ -558,18 +544,18 @@
           /*virtual_card_option=*/false,
           /*card_linked_offer_available=*/false);
 
-#if BUILDFLAG(IS_ANDROID)
-  // For Android, split the first line and populate card name, last 4 digits
-  // separately.
-  EXPECT_EQ(real_card_number_field_suggestion.main_text.value, u"Visa");
-  EXPECT_EQ(real_card_number_field_suggestion.minor_text.value,
-            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
-#else
+#if BUILDFLAG(IS_IOS)
   // Only the card number is displayed on the first line.
   EXPECT_EQ(real_card_number_field_suggestion.main_text.value,
             base::StrCat({u"Visa  ", internal::GetObfuscatedStringForCardDigits(
                                          u"1111", 4)}));
   EXPECT_EQ(real_card_number_field_suggestion.minor_text.value, u"");
+#else
+  // For Desktop/Android, split the first line and populate card name, last 4
+  // digits separately.
+  EXPECT_EQ(real_card_number_field_suggestion.main_text.value, u"Visa");
+  EXPECT_EQ(real_card_number_field_suggestion.minor_text.value,
+            internal::GetObfuscatedStringForCardDigits(u"1111", 4));
 #endif
 
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
@@ -584,10 +570,9 @@
   // "Expires on mm/yy".
   ASSERT_EQ(real_card_number_field_suggestion.labels.size(), 1U);
   ASSERT_EQ(real_card_number_field_suggestion.labels[0].size(), 1U);
-  EXPECT_EQ(
-      real_card_number_field_suggestion.labels[0][0].value,
-      base::StrCat({u"Expires on ", base::UTF8ToUTF16(test::NextMonth()), u"/",
-                    base::UTF8ToUTF16(test::NextYear().substr(2))}));
+  EXPECT_EQ(real_card_number_field_suggestion.labels[0][0].value,
+            base::StrCat({base::UTF8ToUTF16(test::NextMonth()), u"/",
+                          base::UTF8ToUTF16(test::NextYear().substr(2))}));
 #endif
 }
 
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index c14456d..0fbb770 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -972,8 +972,12 @@
 
   void SetUp() override {
     BrowserAutofillManagerTest::SetUp();
-    features_.InitWithFeatureState(features::kAutofillKeyboardAccessory,
-                                   is_keyboard_accessory_enabled_);
+    feature_list_keyboard_accessory_.InitWithFeatureState(
+        features::kAutofillKeyboardAccessory, is_keyboard_accessory_enabled_);
+    feature_list_card_metadata_and_product_name_.InitWithFeatures(
+        /* enabled_features */ {},
+        /* disabled_features */ {features::kAutofillEnableVirtualCardMetadata,
+                                 features::kAutofillEnableCardProductName});
   }
 
   int ObfuscationLength() {
@@ -985,7 +989,8 @@
   }
 
  private:
-  base::test::ScopedFeatureList features_;
+  base::test::ScopedFeatureList feature_list_keyboard_accessory_;
+  base::test::ScopedFeatureList feature_list_card_metadata_and_product_name_;
   const bool is_keyboard_accessory_enabled_;
 };
 
@@ -1735,18 +1740,14 @@
 
   const FormFieldData& credit_card_number_field = form.fields[1];
   GetAutofillSuggestions(form, credit_card_number_field);
-  int obfuscation_length = base::FeatureList::IsEnabled(
-                               autofill::features::kAutofillKeyboardAccessory)
-                               ? 2
-                               : 4;
   const std::string visa_value =
       std::string("Visa  ") +
-      test::ObfuscatedCardDigitsAsUTF8("3456", obfuscation_length);
+      test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength());
   // Mastercard has a valid nickname. Display nickname + last four in the
   // suggestion title.
   const std::string master_card_value =
       kArbitraryNickname + "  " +
-      test::ObfuscatedCardDigitsAsUTF8("8765", obfuscation_length);
+      test::ObfuscatedCardDigitsAsUTF8("8765", ObfuscationLength());
 
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   const std::string visa_label = std::string("04/99");
diff --git a/components/autofill/core/browser/field_types.cc b/components/autofill/core/browser/field_types.cc
index bfbdf55..34eab73 100644
--- a/components/autofill/core/browser/field_types.cc
+++ b/components/autofill/core/browser/field_types.cc
@@ -111,8 +111,7 @@
       return true;
 
     case MERCHANT_PROMO_CODE:
-      return base::FeatureList::IsEnabled(
-          features::kAutofillParseMerchantPromoCodeFields);
+      return true;
 
     // Fillable credential fields.
     case USERNAME:
diff --git a/components/autofill/core/browser/form_parsing/form_field.cc b/components/autofill/core/browser/form_parsing/form_field.cc
index b965575..3e2cca2 100644
--- a/components/autofill/core/browser/form_parsing/form_field.cc
+++ b/components/autofill/core/browser/form_parsing/form_field.cc
@@ -207,12 +207,9 @@
   std::vector<AutofillField*> processed_fields = RemoveCheckableFields(fields);
 
   // Merchant promo code pass.
-  if (base::FeatureList::IsEnabled(
-          features::kAutofillParseMerchantPromoCodeFields)) {
-    ParseFormFieldsPass(MerchantPromoCodeField::Parse, processed_fields,
-                        field_candidates, page_language, pattern_source,
-                        log_manager);
-  }
+  ParseFormFieldsPass(MerchantPromoCodeField::Parse, processed_fields,
+                      field_candidates, page_language, pattern_source,
+                      log_manager);
 
   // IBAN pass.
   if (base::FeatureList::IsEnabled(features::kAutofillParseIBANFields)) {
diff --git a/components/autofill/core/browser/form_parsing/form_field_unittest.cc b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
index 2e966cd..c6c0844 100644
--- a/components/autofill/core/browser/form_parsing/form_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
@@ -202,10 +202,6 @@
 
 // Tests that `ParseSingleFieldForms` is called as part of `ParseFormFields`.
 TEST_P(FormFieldTest, ParseSingleFieldFormsInsideParseFormField) {
-  base::test::ScopedFeatureList scoped_feature;
-  scoped_feature.InitAndEnableFeature(
-      features::kAutofillParseMerchantPromoCodeFields);
-
   AddTextFormFieldData("", "Phone", PHONE_HOME_WHOLE_NUMBER);
   AddTextFormFieldData("", "Email", EMAIL_ADDRESS);
   AddTextFormFieldData("", "Promo code", MERCHANT_PROMO_CODE);
@@ -217,10 +213,6 @@
 
 // Test that `ParseSingleFieldForms` parses single field promo codes.
 TEST_P(FormFieldTest, ParseFormFieldsForSingleFieldPromoCode) {
-  base::test::ScopedFeatureList scoped_feature;
-  scoped_feature.InitAndEnableFeature(
-      features::kAutofillParseMerchantPromoCodeFields);
-
   // Parse single field promo code.
   AddTextFormFieldData("", "Promo code", MERCHANT_PROMO_CODE);
   EXPECT_EQ(1, ParseSingleFieldForms());
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
index e8325a0..9fd3029 100644
--- a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
+++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
@@ -17,11 +17,6 @@
     const LanguageCode& page_language,
     PatternSource pattern_source,
     LogManager* log_manager) {
-  if (!base::FeatureList::IsEnabled(
-          features::kAutofillParseMerchantPromoCodeFields)) {
-    return nullptr;
-  }
-
   AutofillField* field;
   base::span<const MatchPatternRef> merchant_promo_code_patterns =
       GetMatchPatterns("MERCHANT_PROMO_CODE", page_language, pattern_source);
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
index 21f7f385..11e9dadd 100644
--- a/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "components/autofill/core/browser/form_parsing/merchant_promo_code_field.h"
 
-#include "base/test/scoped_feature_list.h"
 #include "components/autofill/core/browser/form_parsing/parsing_test_utils.h"
 #include "components/autofill/core/common/autofill_payments_features.h"
 
@@ -21,11 +20,6 @@
   MerchantPromoCodeFieldTest& operator=(const MerchantPromoCodeFieldTest&) =
       delete;
 
-  void SetUp() override {
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kAutofillParseMerchantPromoCodeFields);
-  }
-
  protected:
   std::unique_ptr<FormField> Parse(
       AutofillScanner* scanner,
@@ -34,8 +28,6 @@
                                          GetActivePatternSource(),
                                          /*log_manager=*/nullptr);
   }
-
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 INSTANTIATE_TEST_SUITE_P(
@@ -99,14 +91,4 @@
   ClassifyAndVerify(ParseResult::NOT_PARSED);
 }
 
-TEST_P(MerchantPromoCodeFieldTest, ParsePromoCodeFlagOff) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(
-      features::kAutofillParseMerchantPromoCodeFields);
-  AddTextFormFieldData("promoCodeField", "Enter promo code here",
-                       MERCHANT_PROMO_CODE);
-
-  ClassifyAndVerify(ParseResult::NOT_PARSED);
-}
-
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index fdac98f..dcfefd0 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -1030,9 +1030,6 @@
 // Tests that heuristics for single field parseable types are run for forms with
 // fewer than 3 fields.
 TEST_F(FormStructureTestImpl, PromoCodeHeuristics_SmallForm) {
-  base::test::ScopedFeatureList scoped_feature;
-  scoped_feature.InitAndEnableFeature(
-      features::kAutofillParseMerchantPromoCodeFields);
   FormData form;
   form.url = GURL("http://www.foo.com/");
 
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc
index 839ceb7..2d18334f 100644
--- a/components/autofill/core/browser/payments/payments_client.cc
+++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -35,6 +35,8 @@
 #include "components/autofill/core/browser/payments/payments_requests/upload_card_request.h"
 #include "components/autofill/core/browser/payments/payments_service_url.h"
 #include "components/autofill/core/common/autofill_features.h"
+#include "components/signin/public/identity_manager/access_token_fetcher.h"
+#include "components/signin/public/identity_manager/access_token_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
 #include "components/signin/public/identity_manager/scope_set.h"
diff --git a/components/autofill/core/browser/payments/payments_client.h b/components/autofill/core/browser/payments/payments_client.h
index e4bfc6b..a34bd4c 100644
--- a/components/autofill/core/browser/payments/payments_client.h
+++ b/components/autofill/core/browser/payments/payments_client.h
@@ -22,12 +22,12 @@
 #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h"
 #include "components/autofill/core/browser/payments/card_unmask_delegate.h"
 #include "components/autofill/core/browser/payments/virtual_card_enrollment_flow.h"
-#include "components/signin/public/identity_manager/access_token_fetcher.h"
-#include "components/signin/public/identity_manager/access_token_info.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace signin {
+class AccessTokenFetcher;
+struct AccessTokenInfo;
 class IdentityManager;
 }  // namespace signin
 
diff --git a/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc
index f42cb40..af9d0d2 100644
--- a/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc
+++ b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/json/json_writer.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index 036888a..2edbf39f 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -182,12 +182,6 @@
              "AutofillParseIBANFields",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// When enabled, Autofill will attempt to find merchant promo/coupon/gift code
-// fields when parsing forms.
-BASE_FEATURE(kAutofillParseMerchantPromoCodeFields,
-             "AutofillParseMerchantPromoCodeFields",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // When enabled, Autofill will attempt to find standalone CVC fields for VCN
 // card on file when parsing forms.
 BASE_FEATURE(kAutofillParseVcnCardOnFileStandaloneCvcFields,
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h
index aa5f05f..159798b0 100644
--- a/components/autofill/core/common/autofill_payments_features.h
+++ b/components/autofill/core/common/autofill_payments_features.h
@@ -37,7 +37,6 @@
 BASE_DECLARE_FEATURE(kAutofillFillIbanFields);
 BASE_DECLARE_FEATURE(kAutofillFillMerchantPromoCodeFields);
 BASE_DECLARE_FEATURE(kAutofillParseIBANFields);
-BASE_DECLARE_FEATURE(kAutofillParseMerchantPromoCodeFields);
 BASE_DECLARE_FEATURE(kAutofillParseVcnCardOnFileStandaloneCvcFields);
 BASE_DECLARE_FEATURE(kAutofillSaveCardDismissOnNavigation);
 BASE_DECLARE_FEATURE(kAutofillSaveCardInfobarEditSupport);
diff --git a/components/autofill_assistant/browser/headless/client_headless.cc b/components/autofill_assistant/browser/headless/client_headless.cc
index 35461b2..f062dc8 100644
--- a/components/autofill_assistant/browser/headless/client_headless.cc
+++ b/components/autofill_assistant/browser/headless/client_headless.cc
@@ -32,6 +32,7 @@
 #include "components/password_manager/core/browser/password_change_success_tracker.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/security_state/core/security_state.h"
+#include "components/signin/public/identity_manager/access_token_info.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/version_info/version_info.h"
diff --git a/components/back_forward_cache/back_forward_cache_disable.cc b/components/back_forward_cache/back_forward_cache_disable.cc
index 888cfd64..5b1a28f 100644
--- a/components/back_forward_cache/back_forward_cache_disable.cc
+++ b/components/back_forward_cache/back_forward_cache_disable.cc
@@ -17,8 +17,6 @@
       return "SafeBrowsingTriggeredPopupBlocker";
     case DisabledReasonId::kSafeBrowsingThreatDetails:
       return "safe_browsing::ThreatDetails";
-    case DisabledReasonId::kAppBannerManager:
-      return "banners::AppBannerManager";
     case DisabledReasonId::kDomDistillerViewerSource:
       return "DomDistillerViewerSource";
     case DisabledReasonId::kDomDistiller_SelfDeletingRequestDelegate:
diff --git a/components/back_forward_cache/disabled_reason_id.h b/components/back_forward_cache/disabled_reason_id.h
index 4b8552a..ddfeee73 100644
--- a/components/back_forward_cache/disabled_reason_id.h
+++ b/components/back_forward_cache/disabled_reason_id.h
@@ -19,7 +19,8 @@
   kPopupBlockerTabHelper = 1,
   kSafeBrowsingTriggeredPopupBlocker = 2,
   kSafeBrowsingThreatDetails = 3,
-  kAppBannerManager = 4,
+  // Unblocked by https://crbug.com/1276864
+  // kAppBannerManager = 4,
   kDomDistillerViewerSource = 5,
   kDomDistiller_SelfDeletingRequestDelegate = 6,
   kOomInterventionTabHelper = 7,
diff --git a/components/browser_ui/util/android/BUILD.gn b/components/browser_ui/util/android/BUILD.gn
index 88639a1d1..047daa2 100644
--- a/components/browser_ui/util/android/BUILD.gn
+++ b/components/browser_ui/util/android/BUILD.gn
@@ -11,6 +11,7 @@
     "java/src/org/chromium/components/browser_ui/util/BrowserControlsVisibilityDelegate.java",
     "java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java",
     "java/src/org/chromium/components/browser_ui/util/ConversionUtils.java",
+    "java/src/org/chromium/components/browser_ui/util/DimensionCompat.java",
     "java/src/org/chromium/components/browser_ui/util/DownloadUtils.java",
     "java/src/org/chromium/components/browser_ui/util/FirstDrawDetector.java",
     "java/src/org/chromium/components/browser_ui/util/GlobalDiscardableReferencePool.java",
diff --git a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/DimensionCompat.java b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/DimensionCompat.java
new file mode 100644
index 0000000..82c8b5d
--- /dev/null
+++ b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/DimensionCompat.java
@@ -0,0 +1,193 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.browser_ui.util;
+
+import android.app.Activity;
+import android.graphics.Point;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowInsets;
+
+import androidx.annotation.Px;
+import androidx.annotation.RequiresApi;
+
+import org.chromium.base.ApiCompatibilityUtils;
+
+/**
+ * Collection of methods computing various height dimensions that differ by OS build version.
+ */
+public abstract class DimensionCompat {
+    protected final Activity mActivity;
+    protected final Runnable mPositionUpdater;
+
+    /**
+     * @param activity {@link Activity} in which the UI dimensions are queried
+     * @param positionUpdater {@link Runnable} to be invoked to reflect the app content frame
+     *        size updates if it resizes dynamically in the course of app lifecycle.
+     */
+    public static DimensionCompat create(Activity activity, Runnable positionUpdater) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return new DimensionCompatLegacy(activity, positionUpdater);
+        }
+        return new DimensionCompatR(activity, positionUpdater);
+    }
+
+    /** Updates the tab's height/size after user interaction/device rotation */
+    public abstract void updatePosition();
+
+    /**
+     * Returns window height. In multi-window mode, returns the window height of the current app
+     * excluding the navigation bar. In non-MW mode, it includes the navigation bar height as well.
+     */
+    public abstract @Px int getWindowHeight();
+
+    /** Returns the status bar height */
+    public abstract @Px int getStatusbarHeight();
+
+    /** Returns the bottom navigation bar height */
+    public abstract @Px int getNavbarHeight();
+
+    /** Implementation that supports R+ */
+    @RequiresApi(Build.VERSION_CODES.R)
+    private static class DimensionCompatR extends DimensionCompat {
+        private DimensionCompatR(Activity activity, Runnable positionUpdater) {
+            super(activity, positionUpdater);
+        }
+
+        @Override
+        public void updatePosition() {
+            mPositionUpdater.run();
+        }
+
+        @Override
+        @Px
+        public int getWindowHeight() {
+            return mActivity.getWindowManager().getCurrentWindowMetrics().getBounds().height();
+        }
+
+        @Override
+        @Px
+        public int getStatusbarHeight() {
+            return mActivity.getWindowManager()
+                    .getCurrentWindowMetrics()
+                    .getWindowInsets()
+                    .getInsets(WindowInsets.Type.statusBars())
+                    .top;
+        }
+
+        @Override
+        @Px
+        public int getNavbarHeight() {
+            return mActivity.getWindowManager()
+                    .getCurrentWindowMetrics()
+                    .getWindowInsets()
+                    .getInsets(WindowInsets.Type.navigationBars())
+                    .bottom;
+        }
+    }
+
+    DimensionCompat(Activity activity, Runnable positionUpdater) {
+        mActivity = activity;
+        mPositionUpdater = positionUpdater;
+    }
+
+    /** Implementation that supports version below R */
+    private static class DimensionCompatLegacy extends DimensionCompat {
+        private DimensionCompatLegacy(Activity activity, Runnable positionUpdater) {
+            super(activity, positionUpdater);
+        }
+
+        @Override
+        public void updatePosition() {
+            // On pre-R devices, We wait till the layout is complete and get the content
+            // |android.R.id.content| view height. See |getAppUsableScreenHeightFromContent|.
+            View contentFrame = mActivity.findViewById(android.R.id.content);
+
+            // Maybe invoked before layout inflation? Simply return here - position update will be
+            // attempted later again by |onPostInflationStartUp|.
+            if (contentFrame == null) return;
+
+            contentFrame.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    contentFrame.removeOnLayoutChangeListener(this);
+                    mPositionUpdater.run();
+                }
+            });
+        }
+
+        // TODO(jinsukkim): Explore the way to use androidx.window.WindowManager or
+        // androidx.window.java.WindowInfoRepoJavaAdapter once the androidx API get finalized and is
+        // available in Chromium to use #getCurrentWindowMetrics()/#currentWindowMetrics() to get
+        // the height of the display our Window currently in.
+        //
+        // The #getRealMetrics() method will give the physical size of the screen, which is
+        // generally fine when the app is not in multi-window mode and #getMetrics() will give the
+        // height excludes the decor views, so not suitable for our case. But in multi-window mode,
+        // we have no much choice, the closest way is to use #getMetrics() method, because we need
+        // to handle rotation.
+        @Override
+        @Px
+        public int getWindowHeight() {
+            DisplayMetrics displayMetrics = new DisplayMetrics();
+            if (ApiCompatibilityUtils.isInMultiWindowMode(mActivity)) {
+                mActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+            } else {
+                mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
+            }
+            return displayMetrics.heightPixels;
+        }
+
+        @Override
+        @SuppressWarnings({"DiscouragedApi", "InternalInsetResource"})
+        @Px
+        public int getStatusbarHeight() {
+            int statusBarHeight = 0;
+            final int statusBarHeightResourceId =
+                    mActivity.getResources().getIdentifier("status_bar_height", "dimen", "android");
+            if (statusBarHeightResourceId > 0) {
+                statusBarHeight =
+                        mActivity.getResources().getDimensionPixelSize(statusBarHeightResourceId);
+            }
+            return statusBarHeight;
+        }
+
+        @Override
+        @Px
+        public int getNavbarHeight() {
+            // Pre-R OS offers no official way to get the navigation bar height. A common way was
+            // to get it from a resource definition('navigation_bar_height') but it fails on some
+            // vendor-customized devices.
+            // A workaround here is to subtract the app-usable height from the whole display height.
+            // There are a couple of ways to get the app-usable height:
+            // 1) content frame + status bar height
+            // 2) |display.getSize|
+            // On some devices, only one returns the right height, the other returning a height
+            // bigger that the actual value. Heuristically we choose the smaller of the two.
+            return getWindowHeight()
+                    - Math.max(getAppUsableScreenHeightFromContent(),
+                            getAppUsableScreenHeightFromDisplay());
+        }
+
+        private int getAppUsableScreenHeightFromContent() {
+            // A correct way to get the client area height would be to use the parent of |content|
+            // to make sure to include the top action bar dimension. But CCT (or Chrome for that
+            // matter) doesn't have the top action bar. So getting the height of |content| is
+            // enough.
+            View contentFrame = mActivity.findViewById(android.R.id.content);
+            return contentFrame.getHeight() + getStatusbarHeight();
+        }
+
+        private int getAppUsableScreenHeightFromDisplay() {
+            Display display = mActivity.getWindowManager().getDefaultDisplay();
+            Point size = new Point();
+            display.getSize(size);
+            return size.y;
+        }
+    }
+}
diff --git a/components/commerce/core/account_checker.cc b/components/commerce/core/account_checker.cc
index b76e236..c1bac50f 100644
--- a/components/commerce/core/account_checker.cc
+++ b/components/commerce/core/account_checker.cc
@@ -138,27 +138,26 @@
       waa_timeout_ms, waa_post_data, traffic_annotation, identity_manager_);
   endpoint_fetcher.get()->Fetch(base::BindOnce(
       &AccountChecker::HandleFetchWaaResponse, weak_ptr_factory_.GetWeakPtr(),
-      pref_service_, std::move(endpoint_fetcher)));
+      std::move(endpoint_fetcher)));
 }
 
 void AccountChecker::HandleFetchWaaResponse(
-    PrefService* pref_service,
     std::unique_ptr<EndpointFetcher> endpoint_fetcher,
     std::unique_ptr<EndpointResponse> responses) {
   data_decoder::DataDecoder::ParseJsonIsolated(
-      responses->response,
-      base::BindOnce(
-          [](PrefService* pref_service,
-             data_decoder::DataDecoder::ValueOrError result) {
-            if (pref_service && result.has_value() && result->is_dict()) {
-              const char waa_response_key[] = "history_recording_enabled";
-              if (auto waa_enabled = result->FindBoolKey(waa_response_key)) {
-                pref_service->SetBoolean(kWebAndAppActivityEnabledForShopping,
-                                         *waa_enabled);
-              }
-            }
-          },
-          base::UnsafeDanglingUntriaged(pref_service)));
+      responses->response, base::BindOnce(&AccountChecker::OnFetchWaaJsonParsed,
+                                          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AccountChecker::OnFetchWaaJsonParsed(
+    data_decoder::DataDecoder::ValueOrError result) {
+  if (pref_service_ && result.has_value() && result->is_dict()) {
+    const char waa_response_key[] = "history_recording_enabled";
+    if (auto waa_enabled = result->FindBoolKey(waa_response_key)) {
+      pref_service_->SetBoolean(kWebAndAppActivityEnabledForShopping,
+                                *waa_enabled);
+    }
+  }
 }
 
 void AccountChecker::FetchPriceEmailPref() {
diff --git a/components/commerce/core/account_checker.h b/components/commerce/core/account_checker.h
index f2f5b37..169e4555 100644
--- a/components/commerce/core/account_checker.h
+++ b/components/commerce/core/account_checker.h
@@ -53,7 +53,6 @@
   // Handle the responses for fetching users' web and app activity consent
   // status.
   void HandleFetchWaaResponse(
-      PrefService* pref_service,
       // Passing the endpoint_fetcher ensures the endpoint_fetcher's
       // lifetime extends to the callback and is not destroyed
       // prematurely (which would result in cancellation of the request).
@@ -61,6 +60,8 @@
       std::unique_ptr<EndpointFetcher> endpoint_fetcher,
       std::unique_ptr<EndpointResponse> responses);
 
+  void OnFetchWaaJsonParsed(data_decoder::DataDecoder::ValueOrError result);
+
   // Send users' pref to server on whether to receive price tracking emails.
   void SendPriceEmailPref();
 
diff --git a/components/cronet/android/api.txt b/components/cronet/android/api.txt
index ee03250..195bd45 100644
--- a/components/cronet/android/api.txt
+++ b/components/cronet/android/api.txt
@@ -75,6 +75,7 @@
   public org.chromium.net.CronetEngine build();
 }
 public abstract class org.chromium.net.CronetEngine {
+  public static final int ACTIVE_REQUEST_COUNT_UNKNOWN;
   public static final int CONNECTION_METRIC_UNKNOWN;
   public static final int EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
   public static final int EFFECTIVE_CONNECTION_TYPE_OFFLINE;
@@ -91,6 +92,7 @@
   public abstract java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
   public abstract java.net.URLStreamHandlerFactory createURLStreamHandlerFactory();
   public abstract org.chromium.net.UrlRequest$Builder newUrlRequestBuilder(java.lang.String, org.chromium.net.UrlRequest$Callback, java.util.concurrent.Executor);
+  public int getActiveRequestCount();
   public abstract org.chromium.net.BidirectionalStream$Builder newBidirectionalStreamBuilder(java.lang.String, org.chromium.net.BidirectionalStream$Callback, java.util.concurrent.Executor);
   public void addRequestFinishedListener(org.chromium.net.RequestFinishedInfo$Listener);
   public void removeRequestFinishedListener(org.chromium.net.RequestFinishedInfo$Listener);
@@ -492,4 +494,4 @@
   public static org.chromium.net.apihelpers.JsonCronetCallback forJsonBody(org.chromium.net.apihelpers.RedirectHandler, org.chromium.net.apihelpers.CronetRequestCompletionListener<org.json.JSONObject>);
   public static org.chromium.net.apihelpers.UrlRequestCallbacks$CallbackAndResponseFuturePair<org.json.JSONObject, org.chromium.net.apihelpers.JsonCronetCallback> forJsonBody(org.chromium.net.apihelpers.RedirectHandler);
 }
-Stamp: a7a2c4b25dbfbd4e36d9b28664e201f4
+Stamp: 816e06e55228226dc92379f3092b1318
diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
index 8d9168d..ede49f2 100644
--- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
+++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -31,6 +31,10 @@
  */
 public abstract class CronetEngine {
     private static final String TAG = CronetEngine.class.getSimpleName();
+    /**
+     * The value of the active request count is unknown
+     */
+    public static final int ACTIVE_REQUEST_COUNT_UNKNOWN = -1;
 
     /**
      * The value of a connection metric is unknown.
@@ -606,6 +610,25 @@
             String url, UrlRequest.Callback callback, Executor executor);
 
     /**
+     * Returns the number of in-flight requests.
+     * <p>
+     * A request is in-flight if its start() method has been called but it hasn't reached a final
+     * state yet. A request reaches the final state when one of the following callbacks has been
+     * called:
+     * <ul>
+     *    <li>onSucceeded</li>
+     *    <li>onCanceled</li>
+     *    <li>onFailed</li>
+     * </ul>
+     *
+     * <a href="https://developer.android.com/guide/topics/connectivity/cronet/lifecycle">Cronet
+     *         requests's lifecycle</a> for more information.
+     */
+    public int getActiveRequestCount() {
+        return ACTIVE_REQUEST_COUNT_UNKNOWN;
+    }
+
+    /**
      * Creates a builder for {@link BidirectionalStream} objects. All callbacks for generated {@code
      * BidirectionalStream} objects will be invoked on {@code executor}. {@code executor} must not
      * run tasks on the current thread, otherwise the networking operations may block and exceptions
diff --git a/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java b/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java
index 7f61ace..66896a8 100644
--- a/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java
+++ b/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java
@@ -263,6 +263,13 @@
     }
 
     @Override
+    public int getActiveRequestCount() {
+        synchronized (mLock) {
+            return mActiveRequestCount;
+        }
+    }
+
+    @Override
     protected ExperimentalBidirectionalStream createBidirectionalStream(String url,
             BidirectionalStream.Callback callback, Executor executor, String httpMethod,
             List<Map.Entry<String, String>> requestHeaders, @StreamPriority int priority,
diff --git a/components/cronet/android/implementation_api_version.txt b/components/cronet/android/implementation_api_version.txt
index 209e3ef..b5045cc 100644
--- a/components/cronet/android/implementation_api_version.txt
+++ b/components/cronet/android/implementation_api_version.txt
@@ -1 +1 @@
-20
+21
\ No newline at end of file
diff --git a/components/cronet/android/interface_api_version.txt b/components/cronet/android/interface_api_version.txt
index 209e3ef..aabe6ec3 100644
--- a/components/cronet/android/interface_api_version.txt
+++ b/components/cronet/android/interface_api_version.txt
@@ -1 +1 @@
-20
+21
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
index e4c2df6..f12ba832 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
@@ -319,6 +319,11 @@
         return "Cronet/" + ImplVersion.getCronetVersionWithLastChange();
     }
 
+    @Override
+    public int getActiveRequestCount() {
+        return mActiveRequestCount.get();
+    }
+
     private CronetVersion buildCronetVersion() {
         String version = getVersionString();
         // getVersionString()'s output looks like "Cronet/w.x.y.z@hash". CronetVersion only cares
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java b/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java
index 9a81119..59519dd 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java
@@ -198,6 +198,11 @@
     }
 
     @Override
+    public int getActiveRequestCount() {
+        return mActiveRequestCount.get();
+    }
+
+    @Override
     public void bindToNetwork(long networkHandle) {
         throw new UnsupportedOperationException(
                 "The multi-network API is not supported by the Java implementation "
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index a4364ab5..480ce21 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -386,7 +386,7 @@
         callback.setAutoAdvance(false);
 
         ExperimentalUrlRequest.Builder urlRequestBuilder =
-                (ExperimentalUrlRequest.Builder) testFramework.mCronetEngine.newUrlRequestBuilder(
+                testFramework.mCronetEngine.newUrlRequestBuilder(
                         mUrl, callback, callback.getExecutor());
         urlRequestBuilder.bindToNetwork(defaultNetwork.getNetworkHandle());
         UrlRequest urlRequest = urlRequestBuilder.build();
@@ -442,7 +442,7 @@
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
         callback.setAutoAdvance(false);
         ExperimentalUrlRequest.Builder urlRequestBuilder =
-                (ExperimentalUrlRequest.Builder) testFramework.mCronetEngine.newUrlRequestBuilder(
+                testFramework.mCronetEngine.newUrlRequestBuilder(
                         mUrl, callback, callback.getExecutor());
         ConnectivityManagerDelegate delegate =
                 new ConnectivityManagerDelegate(InstrumentationRegistry.getTargetContext());
@@ -610,6 +610,164 @@
     @Test
     @SmallTest
     @Feature({"Cronet"})
+    public void testGetActiveRequestCount() throws Exception {
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback1 = new TestUrlRequestCallback();
+        TestUrlRequestCallback callback2 = new TestUrlRequestCallback();
+        callback1.setAutoAdvance(false);
+        callback2.setAutoAdvance(false);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request1 =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback1, callback1.getExecutor()).build();
+        UrlRequest request2 =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback2, callback2.getExecutor()).build();
+        request1.start();
+        request2.start();
+        assertEquals(2, cronetEngine.getActiveRequestCount());
+        callback1.waitForNextStep();
+        callback1.setAutoAdvance(true);
+        callback1.startNextRead(request1);
+        callback1.blockForDone();
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback2.waitForNextStep();
+        callback2.setAutoAdvance(true);
+        callback2.startNextRead(request2);
+        callback2.blockForDone();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testGetActiveRequestCountOnReachingSucceeded() throws Exception {
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        callback.setAutoAdvance(false);
+        callback.setBlockOnTerminalState(true);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor()).build();
+        request.start();
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback.waitForNextStep();
+        callback.startNextRead(request);
+        callback.waitForNextStep();
+        callback.startNextRead(request);
+        callback.waitForTerminalToStart();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        callback.setBlockOnTerminalState(false);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testGetActiveRequestCountOnReachingCancel() throws Exception {
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        callback.setAutoAdvance(false);
+        callback.setBlockOnTerminalState(true);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor()).build();
+        request.start();
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        request.cancel();
+        callback.waitForTerminalToStart();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        callback.setBlockOnTerminalState(false);
+        assertTrue(callback.mOnCanceledCalled);
+        assertEquals(ResponseStep.ON_CANCELED, callback.mResponseStep);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testGetActiveRequestCountOnReachingFail() throws Exception {
+        final String badUrl = "www.unreachable-url.com";
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        callback.setAutoAdvance(false);
+        callback.setBlockOnTerminalState(true);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request =
+                cronetEngine.newUrlRequestBuilder(badUrl, callback, callback.getExecutor()).build();
+        request.start();
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback.waitForTerminalToStart();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        callback.setBlockOnTerminalState(false);
+        assertTrue(callback.mOnErrorCalled);
+        assertEquals(ResponseStep.ON_FAILED, callback.mResponseStep);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testGetActiveRequestCountWithCancel() throws Exception {
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback1 = new TestUrlRequestCallback();
+        TestUrlRequestCallback callback2 = new TestUrlRequestCallback();
+        callback1.setAutoAdvance(false);
+        callback2.setAutoAdvance(false);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request1 =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback1, callback1.getExecutor()).build();
+        UrlRequest request2 =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback2, callback2.getExecutor()).build();
+        request1.start();
+        request2.start();
+        assertEquals(2, cronetEngine.getActiveRequestCount());
+        request1.cancel();
+        callback1.blockForDone();
+        assertTrue(callback1.mOnCanceledCalled);
+        assertEquals(ResponseStep.ON_CANCELED, callback1.mResponseStep);
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback2.waitForNextStep();
+        callback2.setAutoAdvance(true);
+        callback2.startNextRead(request2);
+        callback2.blockForDone();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testGetActiveRequestCountWithError() throws Exception {
+        final String badUrl = "www.unreachable-url.com";
+        final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
+        CronetEngine cronetEngine = testFramework.mCronetEngine;
+        TestUrlRequestCallback callback1 = new TestUrlRequestCallback();
+        TestUrlRequestCallback callback2 = new TestUrlRequestCallback();
+        callback1.setAutoAdvance(false);
+        callback2.setAutoAdvance(false);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        UrlRequest request1 =
+                cronetEngine.newUrlRequestBuilder(badUrl, callback1, callback1.getExecutor())
+                        .build();
+        UrlRequest request2 =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback2, callback2.getExecutor()).build();
+        request1.start();
+        request2.start();
+        assertEquals(2, cronetEngine.getActiveRequestCount());
+        callback1.blockForDone();
+        assertTrue(callback1.mOnErrorCalled);
+        assertEquals(ResponseStep.ON_FAILED, callback1.mResponseStep);
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback2.waitForNextStep();
+        callback2.setAutoAdvance(true);
+        callback2.startNextRead(request2);
+        callback2.blockForDone();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Cronet"})
     @OnlyRunNativeCronet
     // Tests that NetLog contains events emitted by all live CronetEngines.
     public void testNetLogContainEventsFromAllLiveEngines() throws Exception {
@@ -1335,7 +1493,7 @@
     public void testGetGlobalMetricsDeltas() throws Exception {
         final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
 
-        byte delta1[] = testFramework.mCronetEngine.getGlobalMetricsDeltas();
+        byte[] delta1 = testFramework.mCronetEngine.getGlobalMetricsDeltas();
 
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
         UrlRequest.Builder builder = testFramework.mCronetEngine.newUrlRequestBuilder(
@@ -1351,7 +1509,7 @@
             }
         });
         new Thread(task).start();
-        byte delta2[] = task.get();
+        byte[] delta2 = task.get();
         assertTrue(delta2.length != 0);
         assertFalse(Arrays.equals(delta1, delta2));
     }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
index 0d6443c..9f4213c5 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
@@ -53,6 +53,10 @@
     // Whether to permit calls on the network thread.
     private boolean mAllowDirectExecutor;
 
+    // Whether to stop the executor thread after reaching a terminal method.
+    // Terminal methods are (onSucceeded, onFailed or onCancelled)
+    private boolean mBlockOnTerminalState;
+
     // Conditionally fail on certain steps.
     private FailureType mFailureType = FailureType.NONE;
     private ResponseStep mFailureStep = ResponseStep.NOTHING;
@@ -60,6 +64,9 @@
     // Signals when request is done either successfully or not.
     private final ConditionVariable mDone = new ConditionVariable();
 
+    // Hangs the calling thread until a terminal method has started executing.
+    private final ConditionVariable mWaitForTerminalToStart = new ConditionVariable();
+
     // Signaled on each step when mAutoAdvance is false.
     private final ConditionVariable mStepBlock = new ConditionVariable();
 
@@ -140,6 +147,19 @@
         fillInExecutorThread();
     }
 
+    /**
+     * This blocks the callback executor thread once it has reached a final state callback.
+     * In order to continue execution, this method must be called again and providing {@code false}
+     * to continue execution.
+     * @param blockOnTerminalState the state to set for the executor thread
+     */
+    public void setBlockOnTerminalState(boolean blockOnTerminalState) {
+        mBlockOnTerminalState = blockOnTerminalState;
+        if (!blockOnTerminalState) {
+            mDone.open();
+        }
+    }
+
     public void setAutoAdvance(boolean autoAdvance) {
         mAutoAdvance = autoAdvance;
     }
@@ -157,6 +177,14 @@
         mDone.block();
     }
 
+    /**
+     * Blocks the calling thread until one of the final states has been called.
+     * This is called before the callback has finished executed.
+     */
+    public void waitForTerminalToStart() {
+        mWaitForTerminalToStart.block();
+    }
+
     public void waitForNextStep() {
         mStepBlock.block();
         mStepBlock.close();
@@ -259,6 +287,8 @@
 
         mResponseStep = ResponseStep.ON_SUCCEEDED;
         mResponseInfo = info;
+        mWaitForTerminalToStart.open();
+        if (mBlockOnTerminalState) mDone.block();
         openDone();
         maybeThrowCancelOrPause(request);
     }
@@ -289,6 +319,8 @@
         mResponseStep = ResponseStep.ON_FAILED;
         mOnErrorCalled = true;
         mError = error;
+        mWaitForTerminalToStart.open();
+        if (mBlockOnTerminalState) mDone.block();
         openDone();
         maybeThrowCancelOrPause(request);
     }
@@ -304,6 +336,8 @@
 
         mResponseStep = ResponseStep.ON_CANCELED;
         mOnCanceledCalled = true;
+        mWaitForTerminalToStart.open();
+        if (mBlockOnTerminalState) mDone.block();
         openDone();
         maybeThrowCancelOrPause(request);
     }
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc
index 51fa923..e0b700f8 100644
--- a/components/exo/wayland/clients/client_base.cc
+++ b/components/exo/wayland/clients/client_base.cc
@@ -141,50 +141,54 @@
 
   if (strcmp(interface, "wl_compositor") == 0) {
     globals->compositor.reset(static_cast<wl_compositor*>(
-        wl_registry_bind(registry, id, &wl_compositor_interface, 3)));
+        wl_registry_bind(registry, id, &wl_compositor_interface, version)));
   } else if (strcmp(interface, "wl_shm") == 0) {
     globals->shm.reset(static_cast<wl_shm*>(
-        wl_registry_bind(registry, id, &wl_shm_interface, 1)));
+        wl_registry_bind(registry, id, &wl_shm_interface, version)));
   } else if (strcmp(interface, "wl_shell") == 0) {
     globals->shell.reset(static_cast<wl_shell*>(
-        wl_registry_bind(registry, id, &wl_shell_interface, 1)));
+        wl_registry_bind(registry, id, &wl_shell_interface, version)));
   } else if (strcmp(interface, "wl_seat") == 0) {
     globals->seat.reset(static_cast<wl_seat*>(
-        wl_registry_bind(registry, id, &wl_seat_interface, 5)));
+        wl_registry_bind(registry, id, &wl_seat_interface, version)));
   } else if (strcmp(interface, "wp_presentation") == 0) {
     globals->presentation.reset(static_cast<wp_presentation*>(
-        wl_registry_bind(registry, id, &wp_presentation_interface, 1)));
+        wl_registry_bind(registry, id, &wp_presentation_interface, version)));
   } else if (strcmp(interface, "zaura_shell") == 0) {
     globals->aura_shell.reset(static_cast<zaura_shell*>(
-        wl_registry_bind(registry, id, &zaura_shell_interface, 34)));
+        wl_registry_bind(registry, id, &zaura_shell_interface, version)));
   } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
     globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>(
         wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface,
                          std::min(params.linux_dmabuf_version, version))));
   } else if (strcmp(interface, "wl_subcompositor") == 0) {
     globals->subcompositor.reset(static_cast<wl_subcompositor*>(
-        wl_registry_bind(registry, id, &wl_subcompositor_interface, 1)));
+        wl_registry_bind(registry, id, &wl_subcompositor_interface, version)));
   } else if (strcmp(interface, "zcr_color_manager_v1") == 0) {
-    globals->color_manager.reset(static_cast<zcr_color_manager_v1*>(
-        wl_registry_bind(registry, id, &zcr_color_manager_v1_interface, 1)));
+    globals->color_manager.reset(
+        static_cast<zcr_color_manager_v1*>(wl_registry_bind(
+            registry, id, &zcr_color_manager_v1_interface, version)));
   } else if (strcmp(interface, "zwp_input_timestamps_manager_v1") == 0) {
     globals->input_timestamps_manager.reset(
         static_cast<zwp_input_timestamps_manager_v1*>(wl_registry_bind(
-            registry, id, &zwp_input_timestamps_manager_v1_interface, 1)));
+            registry, id, &zwp_input_timestamps_manager_v1_interface,
+            version)));
   } else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
-    globals->fullscreen_shell.reset(static_cast<zwp_fullscreen_shell_v1*>(
-        wl_registry_bind(registry, id, &zwp_fullscreen_shell_v1_interface, 1)));
+    globals->fullscreen_shell.reset(
+        static_cast<zwp_fullscreen_shell_v1*>(wl_registry_bind(
+            registry, id, &zwp_fullscreen_shell_v1_interface, version)));
   } else if (strcmp(interface, "wl_output") == 0) {
     globals->output.reset(static_cast<wl_output*>(
-        wl_registry_bind(registry, id, &wl_output_interface, 1)));
+        wl_registry_bind(registry, id, &wl_output_interface, version)));
   } else if (strcmp(interface, "zwp_linux_explicit_synchronization_v1") == 0) {
     globals->linux_explicit_synchronization.reset(
         static_cast<zwp_linux_explicit_synchronization_v1*>(wl_registry_bind(
             registry, id, &zwp_linux_explicit_synchronization_v1_interface,
-            1)));
+            version)));
   } else if (strcmp(interface, "zcr_vsync_feedback_v1") == 0) {
-    globals->vsync_feedback.reset(static_cast<zcr_vsync_feedback_v1*>(
-        wl_registry_bind(registry, id, &zcr_vsync_feedback_v1_interface, 1)));
+    globals->vsync_feedback.reset(
+        static_cast<zcr_vsync_feedback_v1*>(wl_registry_bind(
+            registry, id, &zcr_vsync_feedback_v1_interface, version)));
   } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
     globals->xdg_shell_v6.reset(static_cast<zxdg_shell_v6*>(
         wl_registry_bind(registry, id, &zxdg_shell_v6_interface, version)));
@@ -1311,6 +1315,8 @@
       [](void* data, struct zaura_output* zaura_output, int32_t transform) {
         CastToClientBase(data)->HandleLogicalTransform(transform);
       },
+      [](void* data, struct zaura_output* zaura_output, uint32_t display_id_hi,
+         uint32_t display_id_lo) {},
   };
 
   std::unique_ptr<zaura_output> aura_output(zaura_shell_get_aura_output(
diff --git a/components/exo/wayland/protocol/aura-shell.xml b/components/exo/wayland/protocol/aura-shell.xml
index af29837..43f6d86 100644
--- a/components/exo/wayland/protocol/aura-shell.xml
+++ b/components/exo/wayland/protocol/aura-shell.xml
@@ -24,7 +24,7 @@
     DEALINGS IN THE SOFTWARE.
   </copyright>
 
-  <interface name="zaura_shell" version="44">
+  <interface name="zaura_shell" version="45">
     <description summary="aura_shell">
       The global interface exposing aura shell capabilities is used to
       instantiate an interface extension for a wl_surface object.
@@ -537,7 +537,7 @@
     </request>
   </interface>
 
-  <interface name="zaura_output" version="43">
+  <interface name="zaura_output" version="45">
     <description summary="aura shell interface to a wl_output">
       An additional interface to a wl_output object, which allows the
       client to access aura shell specific functionality for output.
@@ -692,6 +692,14 @@
       <arg name="display_id_hi" type="uint"/>
       <arg name="display_id_lo" type="uint"/>
     </event>
+
+    <!-- Version 45 additions -->
+    <event name="activated" since="45">
+      <description summary="target display for new windows">
+        Notifies that this output is now active output. It is typically used as a
+        target when a new window is created without specific bounds.
+      </description>
+    </event>
   </interface>
 
   <interface name="zaura_toplevel" version="44">
diff --git a/components/exo/wayland/wayland_display_observer.cc b/components/exo/wayland/wayland_display_observer.cc
index 2432fa68..dcdd07ba 100644
--- a/components/exo/wayland/wayland_display_observer.cc
+++ b/components/exo/wayland/wayland_display_observer.cc
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "ash/shell.h"
 #include "chrome-color-management-server-protocol.h"
 #include "components/exo/wayland/server_util.h"
 #include "components/exo/wayland/wayland_display_output.h"
@@ -29,6 +30,7 @@
 }
 
 WaylandDisplayHandler::~WaylandDisplayHandler() {
+  ash::Shell::Get()->RemoveShellObserver(this);
   for (auto& obs : observers_)
     obs.OnOutputDestroyed();
   if (xdg_output_resource_)
@@ -40,6 +42,7 @@
   // Adding itself as an observer will send the initial display metrics.
   AddObserver(this);
   output_->RegisterOutput(output_resource_);
+  ash::Shell::Get()->AddShellObserver(this);
 }
 
 void WaylandDisplayHandler::AddObserver(WaylandDisplayObserver* observer) {
@@ -96,6 +99,17 @@
   }
 }
 
+void WaylandDisplayHandler::OnDisplayForNewWindowsChanged() {
+  DCHECK(output_resource_);
+  if (output_->id() !=
+      display::Screen::GetScreen()->GetDisplayForNewWindows().id()) {
+    return;
+  }
+
+  for (auto& observer : observers_)
+    observer.SendActiveDisplay();
+}
+
 void WaylandDisplayHandler::OnXdgOutputCreated(
     wl_resource* xdg_output_resource) {
   DCHECK(!xdg_output_resource_);
@@ -211,6 +225,8 @@
   return true;
 }
 
+void WaylandDisplayHandler::SendActiveDisplay() {}
+
 void WaylandDisplayHandler::OnOutputDestroyed() {
   // destroying itself.
   RemoveObserver(this);
diff --git a/components/exo/wayland/wayland_display_observer.h b/components/exo/wayland/wayland_display_observer.h
index a6ea00c..1297385f 100644
--- a/components/exo/wayland/wayland_display_observer.h
+++ b/components/exo/wayland/wayland_display_observer.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 #include <wayland-server-protocol-core.h>
 
+#include "ash/shell_observer.h"
 #include "base/observer_list.h"
 #include "ui/display/display.h"
 #include "ui/display/display_observer.h"
@@ -29,6 +30,11 @@
   // to be followed by "done" event, |false| otherwise.
   virtual bool SendDisplayMetrics(const display::Display& display,
                                   uint32_t changed_metrics) = 0;
+
+  // Called when the server should send the active display information to the
+  // client.
+  virtual void SendActiveDisplay() = 0;
+
   // Called when wl_output is destroyed.
   virtual void OnOutputDestroyed() = 0;
 
@@ -37,7 +43,8 @@
 };
 
 class WaylandDisplayHandler : public display::DisplayObserver,
-                              public WaylandDisplayObserver {
+                              public WaylandDisplayObserver,
+                              public ash::ShellObserver {
  public:
   WaylandDisplayHandler(WaylandDisplayOutput* output,
                         wl_resource* output_resource);
@@ -75,8 +82,12 @@
   // Overridden from WaylandDisplayObserver:
   bool SendDisplayMetrics(const display::Display& display,
                           uint32_t changed_metrics) override;
+  void SendActiveDisplay() override;
   void OnOutputDestroyed() override;
 
+  // ShellObserver:
+  void OnDisplayForNewWindowsChanged() override;
+
   // Output.
   WaylandDisplayOutput* output_;
 
diff --git a/components/exo/wayland/wayland_display_observer_unittest.cc b/components/exo/wayland/wayland_display_observer_unittest.cc
index d8d1dab..b79584a2 100644
--- a/components/exo/wayland/wayland_display_observer_unittest.cc
+++ b/components/exo/wayland/wayland_display_observer_unittest.cc
@@ -60,6 +60,8 @@
     wl_client_destroy(client_);
     wl_display_destroy(wayland_display_);
     close(fds_[1]);
+    handler_.reset();
+    output_.reset();
 
     test::ExoTestBase::TearDown();
   }
diff --git a/components/exo/wayland/zaura_shell.cc b/components/exo/wayland/zaura_shell.cc
index f343e300..c35bd0c 100644
--- a/components/exo/wayland/zaura_shell.cc
+++ b/components/exo/wayland/zaura_shell.cc
@@ -955,6 +955,13 @@
   return !!display_handler_;
 }
 
+void AuraOutput::SendActiveDisplay() {
+  if (wl_resource_get_version(resource_) >=
+      ZAURA_OUTPUT_ACTIVATED_SINCE_VERSION) {
+    zaura_output_send_activated(resource_);
+  }
+}
+
 void AuraOutput::SendInsets(const gfx::Insets& insets) {
   zaura_output_send_insets(resource_, insets.top(), insets.left(),
                            insets.bottom(), insets.right());
diff --git a/components/exo/wayland/zaura_shell.h b/components/exo/wayland/zaura_shell.h
index f80f74a..083f78b6 100644
--- a/components/exo/wayland/zaura_shell.h
+++ b/components/exo/wayland/zaura_shell.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include "ash/shell_observer.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "components/exo/surface.h"
 #include "components/exo/surface_observer.h"
@@ -26,7 +27,7 @@
 namespace wayland {
 class SerialTracker;
 
-constexpr uint32_t kZAuraShellVersion = 44;
+constexpr uint32_t kZAuraShellVersion = 45;
 
 // Adds bindings to the Aura Shell. Normally this implies Ash on ChromeOS
 // builds. On non-ChromeOS builds the protocol provides access to Aura windowing
@@ -174,6 +175,7 @@
   // Overridden from WaylandDisplayObserver:
   bool SendDisplayMetrics(const display::Display& display,
                           uint32_t changed_metrics) override;
+  void SendActiveDisplay() override;
   void OnOutputDestroyed() override;
 
   bool HasDisplayHandlerForTesting() const;
diff --git a/components/exo/wayland/zaura_shell_unittest.cc b/components/exo/wayland/zaura_shell_unittest.cc
index c388e70..249bf74 100644
--- a/components/exo/wayland/zaura_shell_unittest.cc
+++ b/components/exo/wayland/zaura_shell_unittest.cc
@@ -13,9 +13,12 @@
 #include "ash/shell.h"
 #include "ash/wm/desks/desks_util.h"
 #include "ash/wm/window_util.h"
+#include "base/containers/cxx20_erase_list.h"
 #include "base/time/time.h"
 #include "components/exo/buffer.h"
+#include "components/exo/shell_surface.h"
 #include "components/exo/test/exo_test_base.h"
+#include "components/exo/test/shell_surface_builder.h"
 #include "components/exo/wayland/scoped_wl.h"
 #include "components/exo/wayland/wayland_display_observer.h"
 #include "components/exo/wayland/wayland_display_output.h"
@@ -415,6 +418,7 @@
 
   MOCK_METHOD(void, SendInsets, (const gfx::Insets&), (override));
   MOCK_METHOD(void, SendLogicalTransform, (int32_t), (override));
+  MOCK_METHOD(void, SendActiveDisplay, (), (override));
 };
 
 class ZAuraOutputTest : public test::ExoTestBase {
@@ -433,28 +437,101 @@
     wayland_display_.reset(wl_display_create());
     client_ = wl_client_create(wayland_display_.get(), fds[0]);
 
-    wl_resource* output_resource =
-        wl_resource_create(client_, &wl_output_interface, kWlOutputVersion, 0);
-    display_handler_ = std::make_unique<WaylandDisplayHandler>(&display_output_,
-                                                               output_resource);
+    UpdateDisplayOutput();
   }
 
-  std::unique_ptr<MockAuraOutput> CreateAuraOutput(int version) {
-    return std::make_unique<::testing::NiceMock<MockAuraOutput>>(
-        wl_resource_create(client_, &zaura_output_interface, version, 0),
-        display_handler_.get());
+  void TearDown() override {
+    output_holder_list_.clear();
+    test::ExoTestBase::TearDown();
   }
 
-  std::unique_ptr<WaylandDisplayHandler> display_handler_;
+  void ResetDisplayOutput() {
+    for (auto& holder : output_holder_list_) {
+      holder->aura_output.reset();
+      holder->output.reset();
+    }
+  }
+
+  void UpdateDisplayOutput() {
+    auto display_list = display::Screen::GetScreen()->GetAllDisplays();
+    auto iter = output_holder_list_.begin();
+    while (iter != output_holder_list_.end()) {
+      auto* out_ptr = (*iter)->output.get();
+      bool erased = base::EraseIf(display_list,
+                                  [out_ptr](const display::Display& display) {
+                                    return display.id() == out_ptr->id();
+                                  });
+      if (erased)
+        ++iter;
+      else
+        iter = output_holder_list_.erase(iter);
+    }
+
+    for (auto& display : display_list) {
+      auto output_holder = std::make_unique<OutputHolder>();
+      output_holder->client = client_;
+      output_holder->output =
+          std::make_unique<WaylandDisplayOutput>(display.id());
+
+      wl_resource* output_resource = wl_resource_create(
+          client_, &wl_output_interface, kWlOutputVersion, 0);
+      output_holder->handler = std::make_unique<WaylandDisplayHandler>(
+          output_holder->output.get(), output_resource);
+      output_holder->handler->Initialize();
+      output_holder->CreateAuraOutput();
+
+      output_holder_list_.push_back(std::move(output_holder));
+    }
+  }
+
+  MockAuraOutput* GetPrimaryAuraOutput() {
+    return GetAuraOutput(
+        display::Screen::GetScreen()->GetPrimaryDisplay().id());
+  }
+
+  MockAuraOutput* GetAuraOutput(int64_t display_id) {
+    return GetOutputHolder(display_id)->aura_output.get();
+  }
+
+  WaylandDisplayHandler* GetPrimaryDisplayHandler() {
+    return GetOutputHolder(
+               display::Screen::GetScreen()->GetPrimaryDisplay().id())
+        ->handler.get();
+  }
+
+  struct OutputHolder {
+    std::unique_ptr<MockAuraOutput> aura_output;
+    std::unique_ptr<WaylandDisplayOutput> output;
+    std::unique_ptr<WaylandDisplayHandler> handler;
+
+    wl_client* client;
+
+    void CreateAuraOutput() {
+      DCHECK(!aura_output);
+      aura_output = std::make_unique<::testing::NiceMock<MockAuraOutput>>(
+          wl_resource_create(client, &zaura_output_interface,
+                             kZAuraShellVersion, 0),
+          handler.get());
+    }
+  };
+
+  OutputHolder* GetOutputHolder(int64_t display_id) {
+    auto iter = base::ranges::find_if(
+        output_holder_list_,
+        [display_id](const std::unique_ptr<OutputHolder>& holder) {
+          return holder->output->id() == display_id;
+        });
+    return iter == output_holder_list_.end() ? nullptr : iter->get();
+  }
 
  private:
-  WaylandDisplayOutput display_output_{0};
+  std::vector<std::unique_ptr<OutputHolder>> output_holder_list_;
   std::unique_ptr<wl_display, WlDisplayDeleter> wayland_display_;
   wl_client* client_ = nullptr;
 };
 
 TEST_F(ZAuraOutputTest, SendInsets) {
-  auto mock_aura_output = CreateAuraOutput(ZAURA_OUTPUT_INSETS_SINCE_VERSION);
+  auto* mock_aura_output = GetPrimaryAuraOutput();
 
   UpdateDisplay("800x600");
   display::Display display =
@@ -472,8 +549,7 @@
 }
 
 TEST_F(ZAuraOutputTest, SendLogicalTransform) {
-  auto mock_aura_output =
-      CreateAuraOutput(ZAURA_OUTPUT_LOGICAL_TRANSFORM_SINCE_VERSION);
+  auto* mock_aura_output = GetPrimaryAuraOutput();
 
   UpdateDisplay("800x600");
   display::Display display =
@@ -515,21 +591,66 @@
       display, display::DisplayObserver::DISPLAY_METRIC_ROTATION);
 }
 
-// Make sure that data associated with wl/aura outputs are destroyd
+// Make sure that data associated with wl/aura outputs are destroyed
 // properly regardless of which one is destroyed first.
 TEST_F(ZAuraOutputTest, DestroyAuraOutput) {
-  auto mock_aura_output =
-      CreateAuraOutput(ZAURA_OUTPUT_LOGICAL_TRANSFORM_SINCE_VERSION);
-  EXPECT_EQ(1u, display_handler_->CountObserversForTesting());
-  mock_aura_output.reset();
-  EXPECT_EQ(0u, display_handler_->CountObserversForTesting());
+  auto* output_holder =
+      GetOutputHolder(display::Screen::GetScreen()->GetPrimaryDisplay().id());
 
-  mock_aura_output =
-      CreateAuraOutput(ZAURA_OUTPUT_LOGICAL_TRANSFORM_SINCE_VERSION);
-  EXPECT_EQ(1u, display_handler_->CountObserversForTesting());
-  EXPECT_TRUE(mock_aura_output->HasDisplayHandlerForTesting());
-  display_handler_.reset();
-  EXPECT_FALSE(mock_aura_output->HasDisplayHandlerForTesting());
+  EXPECT_EQ(1u, GetPrimaryDisplayHandler()->CountObserversForTesting());
+  output_holder->aura_output.reset();
+  EXPECT_EQ(0u, GetPrimaryDisplayHandler()->CountObserversForTesting());
+  output_holder->CreateAuraOutput();
+
+  EXPECT_EQ(1u, GetPrimaryDisplayHandler()->CountObserversForTesting());
+  EXPECT_TRUE(output_holder->aura_output->HasDisplayHandlerForTesting());
+  output_holder->handler.reset();
+  EXPECT_FALSE(output_holder->aura_output->HasDisplayHandlerForTesting());
+}
+
+// Make sure that data associated with wl/aura outputs are destroyed
+// properly regardless of which one is destroyed first.
+TEST_F(ZAuraOutputTest, ActiveDisplay) {
+  UpdateDisplay("800x600, 800x600");
+  UpdateDisplayOutput();
+  auto* screen = display::Screen::GetScreen();
+  int64_t primary_id = screen->GetAllDisplays()[0].id();
+  int64_t secondary_id = screen->GetAllDisplays()[1].id();
+
+  auto* primary_output_holder = GetOutputHolder(primary_id);
+  auto* secondary_output_holder = GetOutputHolder(secondary_id);
+
+  auto shell_surface =
+      test::ShellSurfaceBuilder({100, 100}).BuildShellSurface();
+
+  auto test_widget = CreateTestWidget();
+  test_widget->SetBounds({800, 0, 100, 100});
+
+  ASSERT_EQ(screen->GetDisplayNearestWindow(shell_surface->host_window()).id(),
+            primary_id);
+  ASSERT_EQ(
+      screen->GetDisplayNearestWindow(test_widget->GetNativeWindow()).id(),
+      secondary_id);
+
+  EXPECT_CALL(*(primary_output_holder->aura_output), SendActiveDisplay())
+      .Times(1);
+  EXPECT_CALL(*(secondary_output_holder->aura_output), SendActiveDisplay())
+      .Times(0);
+  shell_surface->GetWidget()->Activate();
+  testing::Mock::VerifyAndClearExpectations(
+      primary_output_holder->aura_output.get());
+  testing::Mock::VerifyAndClearExpectations(
+      secondary_output_holder->aura_output.get());
+
+  EXPECT_CALL(*(primary_output_holder->aura_output), SendActiveDisplay())
+      .Times(0);
+  EXPECT_CALL(*(secondary_output_holder->aura_output), SendActiveDisplay())
+      .Times(1);
+  test_widget->Activate();
+  testing::Mock::VerifyAndClearExpectations(
+      primary_output_holder->aura_output.get());
+  testing::Mock::VerifyAndClearExpectations(
+      secondary_output_holder->aura_output.get());
 }
 
 }  // namespace wayland
diff --git a/components/exo/wayland/zcr_color_manager.cc b/components/exo/wayland/zcr_color_manager.cc
index 4bd042a..1c4611c 100644
--- a/components/exo/wayland/zcr_color_manager.cc
+++ b/components/exo/wayland/zcr_color_manager.cc
@@ -214,6 +214,7 @@
         color_management_output_resource_);
     return true;
   }
+  void SendActiveDisplay() override {}
 
  private:
   WaylandDisplayHandler* wayland_display_handler_;
diff --git a/components/exo/wayland/zcr_remote_shell_impl.cc b/components/exo/wayland/zcr_remote_shell_impl.cc
index 53271cd..b3ebb77 100644
--- a/components/exo/wayland/zcr_remote_shell_impl.cc
+++ b/components/exo/wayland/zcr_remote_shell_impl.cc
@@ -363,6 +363,8 @@
   return true;
 }
 
+void WaylandRemoteOutput::SendActiveDisplay() {}
+
 void WaylandRemoteOutput::OnOutputDestroyed() {
   display_handler_->RemoveObserver(this);
   display_handler_ = nullptr;
diff --git a/components/exo/wayland/zcr_remote_shell_impl.h b/components/exo/wayland/zcr_remote_shell_impl.h
index 22dc0cee..b200ccd9 100644
--- a/components/exo/wayland/zcr_remote_shell_impl.h
+++ b/components/exo/wayland/zcr_remote_shell_impl.h
@@ -37,6 +37,7 @@
   // Overridden from WaylandDisplayObserver:
   bool SendDisplayMetrics(const display::Display& display,
                           uint32_t changed_metrics) override;
+  void SendActiveDisplay() override;
   void OnOutputDestroyed() override;
 
  private:
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc
index 0738dbaa..094081d8 100644
--- a/components/feed/core/v2/metrics_reporter.cc
+++ b/components/feed/core/v2/metrics_reporter.cc
@@ -757,6 +757,7 @@
     case FeedUserActionType::kFollowingFeedSelectedSortByLatest:
     case FeedUserActionType::kTappedFollowOnRecommendationFollowAccelerator:
     case FeedUserActionType::kTappedGotItFeedPostFollowActiveHelp:
+    case FeedUserActionType::kTappedRefreshFollowingFeedOnSnackbar:
       // Nothing additional for these actions. Note that some of these are iOS
       // only.
 
diff --git a/components/feed/core/v2/public/common_enums.cc b/components/feed/core/v2/public/common_enums.cc
index fd51189..4aabcc74 100644
--- a/components/feed/core/v2/public/common_enums.cc
+++ b/components/feed/core/v2/public/common_enums.cc
@@ -136,6 +136,8 @@
       return out << "kTappedFollowOnRecommendationFollowAccelerator";
     case FeedUserActionType::kTappedGotItFeedPostFollowActiveHelp:
       return out << "kTappedGotItFeedPostFollowActiveHelp";
+    case FeedUserActionType::kTappedRefreshFollowingFeedOnSnackbar:
+      return out << "kTappedRefreshFollowingFeedOnSnackbar";
   }
 }
 
diff --git a/components/feed/core/v2/public/common_enums.h b/components/feed/core/v2/public/common_enums.h
index 0c1f09f..7363220 100644
--- a/components/feed/core/v2/public/common_enums.h
+++ b/components/feed/core/v2/public/common_enums.h
@@ -145,7 +145,8 @@
   // User action caused a unfollow failed snackbar to be shown. User action not
   // reported here. iOS only.
   kShowUnfollowFailedSnackbar = 51,
-  // User tapped to go to feed using the snackbar 'go to feed' option.
+  // User tapped to go to Following feed using the snackbar 'go to Following'
+  // option.
   kTappedGoToFeedOnSnackbar = 52,
   // User tapped the Crow button in the context menu.
   kTappedCrowButton = 53,
@@ -171,8 +172,11 @@
   // User tapped the follow accelerator which is presented after a user taps
   // on a recommendation that is in the feed.
   kTappedFollowOnRecommendationFollowAccelerator = 62,
+  // User requested to refresh the Following feed using the post-follow snackbar
+  // 'refresh' action.
+  kTappedRefreshFollowingFeedOnSnackbar = 63,
 
-  kMaxValue = kTappedFollowOnRecommendationFollowAccelerator,
+  kMaxValue = kTappedRefreshFollowingFeedOnSnackbar,
 };
 
 // For testing and debugging only.
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerCoordinator.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerCoordinator.java
index 6ccaae7..e448f6b9 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerCoordinator.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerCoordinator.java
@@ -124,7 +124,10 @@
                 setOnTouchRunnable(null);
                 setOnTitleChanged(null);
                 mTimer.cancelTimer();
+                // Make it unable to be focused if it is not in the front.
+                mView.enableA11y(false);
             } else {
+                mView.enableA11y(true);
                 setOnTouchRunnable(mTimer::resetTimer);
                 announceForAccessibility();
                 setOnTitleChanged(() -> {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
index 9d60df8..288567d79 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
@@ -85,6 +85,11 @@
         }
     }
 
+    void enableA11y(boolean enabled) {
+        setImportantForAccessibility(enabled ? IMPORTANT_FOR_ACCESSIBILITY_AUTO
+                                             : IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+    }
+
     void setTitle(String title) {
         mTitle.setText(title);
         if (mOnTitleChanged != null) mOnTitleChanged.run();
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 4f51fa6..74b6a7a9 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -9,6 +9,55 @@
   import("//build/config/android/rules.gni")
 }
 
+if (is_android) {
+  generate_jni("jni_headers") {
+    namespace = "metrics"
+    sources = [
+      "android/java/src/org/chromium/components/metrics/LowEntropySource.java",
+    ]
+  }
+
+  java_cpp_features("java_features_srcjar") {
+    # External code should depend on ":foo_java" instead.
+    visibility = [ ":*" ]
+    sources = [ "//components/metrics/metrics_features.cc" ]
+    template =
+        "//components/metrics/android/java_templates/MetricsFeatures.java.tmpl"
+  }
+
+  java_cpp_strings("java_switches_srcjar") {
+    # External code should depend on ":metrics_java" instead.
+    visibility = [ ":*" ]
+    sources = [ "//components/metrics/metrics_switches.cc" ]
+    template =
+        "//components/metrics/android/java_templates/MetricsSwitches.java.tmpl"
+  }
+
+  java_cpp_enum("java_enum_srcjar") {
+    # External code should depend on ":metrics_java" instead.
+    visibility = [ ":*" ]
+    sources = [ "stability_metrics_helper.h" ]
+  }
+
+  android_library("metrics_java") {
+    # Right now, this only includes the Java switches. But if we need more Java
+    # files, they should be added here as necessary.
+    srcjar_deps = [
+      ":java_enum_srcjar",
+      ":java_features_srcjar",
+      ":java_switches_srcjar",
+    ]
+    sources = [
+      "android/java/src/org/chromium/components/metrics/LowEntropySource.java",
+    ]
+    deps = [
+      "//base:base_java",
+      "//base:jni_java",
+      "//third_party/androidx:androidx_annotation_annotation_java",
+    ]
+  }
+}
+
 static_library("metrics") {
   sources = [
     "android_metrics_provider.cc",
@@ -149,6 +198,7 @@
 
   if (is_android) {
     sources += [ "drive_metrics_provider_android.cc" ]
+    deps += [ ":jni_headers" ]
   }
 
   if (is_ios) {
@@ -205,41 +255,6 @@
   }
 }
 
-if (is_android) {
-  java_cpp_features("java_features_srcjar") {
-    # External code should depend on ":foo_java" instead.
-    visibility = [ ":*" ]
-    sources = [ "//components/metrics/metrics_features.cc" ]
-    template =
-        "//components/metrics/android/java_templates/MetricsFeatures.java.tmpl"
-  }
-
-  java_cpp_strings("java_switches_srcjar") {
-    # External code should depend on ":metrics_java" instead.
-    visibility = [ ":*" ]
-    sources = [ "//components/metrics/metrics_switches.cc" ]
-    template =
-        "//components/metrics/android/java_templates/MetricsSwitches.java.tmpl"
-  }
-
-  java_cpp_enum("java_enum_srcjar") {
-    # External code should depend on ":metrics_java" instead.
-    visibility = [ ":*" ]
-    sources = [ "stability_metrics_helper.h" ]
-  }
-
-  android_library("metrics_java") {
-    # Right now, this only includes the Java switches. But if we need more Java
-    # files, they should be added here as necessary.
-    srcjar_deps = [
-      ":java_enum_srcjar",
-      ":java_features_srcjar",
-      ":java_switches_srcjar",
-    ]
-    deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
-  }
-}
-
 # The component metrics provider is a separate target because it depends upon
 # (the large) component_updater code, and is not needed for some entities that
 # depend on :metrics.
diff --git a/components/metrics/android/java/src/org/chromium/components/metrics/LowEntropySource.java b/components/metrics/android/java/src/org/chromium/components/metrics/LowEntropySource.java
new file mode 100644
index 0000000..eec667f
--- /dev/null
+++ b/components/metrics/android/java/src/org/chromium/components/metrics/LowEntropySource.java
@@ -0,0 +1,91 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.metrics;
+
+import android.content.SharedPreferences;
+
+import androidx.annotation.MainThread;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.CalledByNative;
+
+import java.util.Random;
+
+/**
+ * Generates a new non-identifying entropy source used to seed persistent activities. Has a static
+ * cache so that the new low entropy source value will only be generated on first access.
+ * Low entropy source is queried by entropy_source.cc that caches it in prefs. On Android, it is
+ * generated in Java so that it can be used by FRE experiments when the native is not available yet.
+ */
+@MainThread
+public class LowEntropySource {
+    // Should be equal to the value of EntropyState::kMaxLowEntropySize in C++.
+    public static final int MAX_LOW_ENTROPY_SIZE = 8000;
+
+    private static final class LazyHolder {
+        private static final int LOW_ENTROPY_SOURCE_STATIC_CACHE = generateInternal();
+    }
+
+    private static final class LazyHolderForPseudo {
+        private static final int PSEUDO_LOW_ENTROPY_SOURCE_STATIC_CACHE = generateInternal();
+    }
+
+    private static final String KEY_LOW_ENTROPY_SOURCE_FRE_COMPLETED =
+            "low_entropy_source_fre_completed";
+
+    /**
+     * Provides access to non-identifying entropy source for FRE trials.
+     * See {@link #generateLowEntropySource()} for details.
+     *
+     * WARNING: This should only be used on first run, as otherwise the value generated by this code
+     * will not correspond to what is used on the C++ side. Calling this method after FRE is
+     * completed will throw an exception.
+     */
+    public static int generateLowEntropySourceForFirstRunTrial() {
+        ThreadUtils.assertOnUiThread();
+        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
+        if (prefs.getBoolean(KEY_LOW_ENTROPY_SOURCE_FRE_COMPLETED, false)) {
+            throw new IllegalStateException(
+                    "LowEntropySource can't be used from Java after FRE has been completed!");
+        }
+
+        return generateLowEntropySource();
+    }
+
+    /**
+     * Should be invoked when the FRE is completed to notify LowEntropySource that
+     * {@link #generateLowEntropySourceForFirstRunTrial} can no longer be used.
+     */
+    public static void markFirstRunComplete() {
+        ThreadUtils.assertOnUiThread();
+        SharedPreferences.Editor editor = ContextUtils.getAppSharedPreferences().edit();
+        editor.putBoolean(KEY_LOW_ENTROPY_SOURCE_FRE_COMPLETED, true);
+        editor.apply();
+    }
+
+    /**
+     * Generates a new non-identifying entropy source. Has a static cache, so subsequent calls will
+     * return the same value during the process lifetime.
+     */
+    @CalledByNative
+    private static int generateLowEntropySource() {
+        return LazyHolder.LOW_ENTROPY_SOURCE_STATIC_CACHE;
+    }
+
+    /**
+     * Generates a new non-identifying low entropy source using the same method that's used for the
+     * actual low entropy source. This one, however, is only used for statistical validation, and
+     * *not* for randomization or experiment assignment.
+     */
+    @CalledByNative
+    private static int generatePseudoLowEntropySource() {
+        return LazyHolderForPseudo.PSEUDO_LOW_ENTROPY_SOURCE_STATIC_CACHE;
+    }
+
+    private static int generateInternal() {
+        return new Random().nextInt(MAX_LOW_ENTROPY_SIZE);
+    }
+}
diff --git a/components/metrics/entropy_state.cc b/components/metrics/entropy_state.cc
index 87f05da..b0eb119 100644
--- a/components/metrics/entropy_state.cc
+++ b/components/metrics/entropy_state.cc
@@ -12,6 +12,11 @@
 #include "components/metrics/metrics_switches.h"
 #include "components/prefs/pref_service.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/jni_android.h"
+#include "components/metrics/jni_headers/LowEntropySource_jni.h"
+#endif  // BUILDFLAG(IS_ANDROID)
+
 namespace metrics {
 
 namespace {
@@ -22,10 +27,16 @@
 // new low entropy source value to prefs multiple times, it stays the same
 // value.
 int GenerateLowEntropySource() {
+#if BUILDFLAG(IS_ANDROID)
+  // Note: As in the non-Android case below, the Java implementation also uses
+  // a static cache, so subsequent invocations will return the same value.
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_LowEntropySource_generateLowEntropySource(env);
+#else
   static const int low_entropy_source =
       base::RandInt(0, EntropyState::kMaxLowEntropySize - 1);
-  ;
   return low_entropy_source;
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 // Generates a new non-identifying low entropy source using the same method
@@ -33,10 +44,16 @@
 // used for statistical validation, and *not* for randomization or experiment
 // assignment.
 int GeneratePseudoLowEntropySource() {
+#if BUILDFLAG(IS_ANDROID)
+  // Note: As in the non-Android case below, the Java implementation also uses
+  // a static cache, so subsequent invocations will return the same value.
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_LowEntropySource_generatePseudoLowEntropySource(env);
+#else
   static const int pseudo_low_entropy_source =
       base::RandInt(0, EntropyState::kMaxLowEntropySize - 1);
-  ;
   return pseudo_low_entropy_source;
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 }  // namespace
diff --git a/components/metrics/entropy_state.h b/components/metrics/entropy_state.h
index 7ef237f..eae9b7e 100644
--- a/components/metrics/entropy_state.h
+++ b/components/metrics/entropy_state.h
@@ -55,6 +55,9 @@
   // The argument used to generate a non-identifying entropy source. We want no
   // more than 13 bits of entropy, so use this max to return a number in the
   // range [0, 7999] as the entropy source (12.97 bits of entropy).
+  //
+  // The value should be kept consistent with
+  // LowEntropySource.MAX_LOW_ENTROPY_SIZE in Java.
   static constexpr int kMaxLowEntropySize = 8000;
 
  private:
diff --git a/components/metrics/generate_expired_histograms_array.gni b/components/metrics/generate_expired_histograms_array.gni
index 4b9057e0..39028b3 100644
--- a/components/metrics/generate_expired_histograms_array.gni
+++ b/components/metrics/generate_expired_histograms_array.gni
@@ -179,7 +179,6 @@
       "//tools/metrics/histograms/metadata/weblayer/histograms.xml",
       "//tools/metrics/histograms/metadata/windows/histograms.xml",
       "//tools/metrics/histograms/metadata/xr/histograms.xml",
-      "//tools/metrics/histograms/metadata/obsolete_histograms.xml",
       "//tools/metrics/histograms/enums.xml",
     ]
 
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/Module.java b/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/Module.java
index f593912..83b3bdc 100644
--- a/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/Module.java
+++ b/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/Module.java
@@ -194,7 +194,7 @@
      */
     private static Object instantiateReflectively(String moduleName, String className) {
         Context context = ContextUtils.getApplicationContext();
-        if (BundleUtils.isIsolatedSplitInstalled(context, moduleName)) {
+        if (BundleUtils.isIsolatedSplitInstalled(moduleName)) {
             context = BundleUtils.createIsolatedSplitContext(context, moduleName);
         }
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/ModuleEngine.java b/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/ModuleEngine.java
index 0501abe..3e692f4 100644
--- a/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/ModuleEngine.java
+++ b/components/module_installer/android/java/src/org/chromium/components/module_installer/builder/ModuleEngine.java
@@ -41,8 +41,7 @@
     @Override
     public boolean isInstalled(String moduleName) {
         // If the module is in an installed isolated split, it is installed.
-        if (BundleUtils.isIsolatedSplitInstalled(
-                    ContextUtils.getApplicationContext(), moduleName)) {
+        if (BundleUtils.isIsolatedSplitInstalled(moduleName)) {
             return true;
         }
 
diff --git a/components/named_mojo_ipc_server/named_mojo_ipc_server.cc b/components/named_mojo_ipc_server/named_mojo_ipc_server.cc
index fc92f11..2439c07 100644
--- a/components/named_mojo_ipc_server/named_mojo_ipc_server.cc
+++ b/components/named_mojo_ipc_server/named_mojo_ipc_server.cc
@@ -159,7 +159,7 @@
 
   endpoint_connector_.AsyncCall(&NamedMojoServerEndpointConnector::Connect)
       .WithArgs(std::move(endpoint))
-      .Then(on_invitation_sent_callback_for_testing_);
+      .Then(on_server_endpoint_created_callback_for_testing_);
 }
 
 void NamedMojoIpcServerBase::OnServerEndpointConnected(
@@ -178,7 +178,7 @@
 }
 
 void NamedMojoIpcServerBase::OnServerEndpointConnectionFailed() {
-  resent_invitation_on_error_timer_.Start(
+  resend_invitation_on_error_timer_.Start(
       FROM_HERE, kResentInvitationOnErrorDelay, this,
       &NamedMojoIpcServerBase::SendInvitation);
 }
diff --git a/components/named_mojo_ipc_server/named_mojo_ipc_server.h b/components/named_mojo_ipc_server/named_mojo_ipc_server.h
index f6a5a0a5..da08f1b6 100644
--- a/components/named_mojo_ipc_server/named_mojo_ipc_server.h
+++ b/components/named_mojo_ipc_server/named_mojo_ipc_server.h
@@ -50,9 +50,9 @@
 
   // Sets a callback to be run when an invitation is sent. Used by unit tests
   // only.
-  void set_on_invitation_sent_callback_for_testing(
+  void set_on_server_endpoint_created_callback_for_testing(
       const base::RepeatingClosure& callback) {
-    on_invitation_sent_callback_for_testing_ = callback;
+    on_server_endpoint_created_callback_for_testing_ = callback;
   }
 
   size_t GetNumberOfActiveConnectionsForTesting() const {
@@ -123,9 +123,9 @@
 
   base::SequenceBound<NamedMojoServerEndpointConnector> endpoint_connector_;
   ActiveConnectionMap active_connections_;
-  base::OneShotTimer resent_invitation_on_error_timer_;
+  base::OneShotTimer resend_invitation_on_error_timer_;
 
-  base::RepeatingClosure on_invitation_sent_callback_for_testing_ =
+  base::RepeatingClosure on_server_endpoint_created_callback_for_testing_ =
       base::DoNothing();
 
   base::WeakPtrFactory<NamedMojoIpcServerBase> weak_factory_{this};
diff --git a/components/named_mojo_ipc_server/named_mojo_ipc_server_unittest.cc b/components/named_mojo_ipc_server/named_mojo_ipc_server_unittest.cc
index b7b9850..22b00be1 100644
--- a/components/named_mojo_ipc_server/named_mojo_ipc_server_unittest.cc
+++ b/components/named_mojo_ipc_server/named_mojo_ipc_server_unittest.cc
@@ -10,14 +10,18 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
+#include "base/command_line.h"
 #include "base/functional/bind.h"
+#include "base/process/process.h"
 #include "base/process/process_handle.h"
 #include "base/run_loop.h"
-#include "base/task/sequenced_task_runner.h"
+#include "base/strings/string_piece.h"
 #include "base/test/bind.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/mock_callback.h"
+#include "base/test/multiprocess_test.h"
 #include "base/test/task_environment.h"
+#include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
@@ -33,9 +37,9 @@
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "testing/multiprocess_func_list.h"
 
 namespace named_mojo_ipc_server {
-
 namespace {
 
 using testing::_;
@@ -45,17 +49,16 @@
     const std::string& input,
     test::mojom::Echo::EchoStringCallback callback)>;
 
-void SendEchoAndVerifyResponse(mojo::Remote<test::mojom::Echo>& echo_remote) {
-  base::RunLoop echo_response_run_loop;
-  base::MockCallback<test::mojom::Echo::EchoStringCallback> callback;
-  EXPECT_CALL(callback, Run("test string"))
-      .WillOnce(
-          base::test::RunOnceClosure(echo_response_run_loop.QuitClosure()));
-  echo_remote->EchoString("test string", callback.Get());
-  echo_response_run_loop.Run();
-}
-
-}  // namespace
+static const char kEchoClientName[] = "EchoClient";
+static const char kClientProcessServerNameSwitch[] =
+    "named-mojo-ipc-server-test-server-name";
+static const char kClientProcessExitAfterConnectSwitch[] =
+    "named-mojo-ipc-server-test-exit-after-connect";
+static const char kClientProcessHangAfterConnectSwitch[] =
+    "named-mojo-ipc-server-test-hang-after-connect";
+static const char kClientProcessWaitUntilDisconnectedSwitch[] =
+    "named-mojo-ipc-server-test-wait-until-disconnected";
+static constexpr int kInvalidEndpointExitCode = 42;
 
 class NamedMojoIpcServerTest : public testing::Test, public test::mojom::Echo {
  public:
@@ -66,56 +69,59 @@
   void TearDown() override;
 
  protected:
-  mojo::PlatformChannelEndpoint ConnectToTestServer();
-  mojo::Remote<test::mojom::Echo> ConnectAndCreateEchoRemote(
-      mojo::IsolatedConnection& client_connection);
-  void WaitForInvitationSent();
+  void CreateIpcServer();
+  base::Process LaunchClientProcess(base::StringPiece extra_switch = {});
+  int WaitForProcessExit(base::Process& process);
+  void WaitForServerEndpointCreated();
 
-  base::test::TaskEnvironment task_environment_;
-  base::Thread ipc_thread_{"ipc!"};
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::IO};
+
+  // Helper thread to wait for process exit without blocking the main thread.
+  base::Thread wait_for_process_exit_thread_{"wait_for_process_exit"};
+
   std::unique_ptr<NamedMojoIpcServer<test::mojom::Echo>> ipc_server_;
 
   mojo::ReceiverId last_echo_string_receiver_id_ = 0u;
+  base::ProcessId last_echo_string_peer_pid_ = base::kNullProcessId;
 
   // If this is set, EchoString() will run this callback instead of responding
   // to the callback automatically.
   EchoStringHandler echo_string_handler_;
 
+  base::RepeatingClosure on_echo_string_called_;
+
  private:
   void EchoString(const std::string& input,
                   EchoStringCallback callback) override;
 
-  void OnInvitationSent();
+  void OnServerEndpointCreated();
 
   std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_;
   mojo::NamedPlatformChannel::ServerName test_server_name_;
 
   // Run loops that wait for NamedMojoIpcServerBase::ObserverForTesting methods
   // to be called.
-  std::unique_ptr<base::RunLoop> on_invitation_sent_run_loop_;
+  std::unique_ptr<base::RunLoop> on_server_endpoint_created_run_loop_;
 };
 
 NamedMojoIpcServerTest::NamedMojoIpcServerTest() {
-  ipc_thread_.StartWithOptions(
-      base::Thread::Options(base::MessagePumpType::IO, 0));
   ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
-      ipc_thread_.task_runner(),
+      task_environment_.GetMainThreadTaskRunner(),
       mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
+  wait_for_process_exit_thread_.StartWithOptions(
+      base::Thread::Options(base::MessagePumpType::IO, 0));
 
   test_server_name_ = test::GenerateRandomServerName();
-  ipc_server_ = std::make_unique<NamedMojoIpcServer<test::mojom::Echo>>(
-      test_server_name_, this,
-      base::BindRepeating([](base::ProcessId) { return true; }));
-  ipc_server_->set_on_invitation_sent_callback_for_testing(base::BindRepeating(
-      &NamedMojoIpcServerTest::OnInvitationSent, base::Unretained(this)));
-  on_invitation_sent_run_loop_ = std::make_unique<base::RunLoop>();
+  CreateIpcServer();
+  on_server_endpoint_created_run_loop_ = std::make_unique<base::RunLoop>();
 }
 
 NamedMojoIpcServerTest::~NamedMojoIpcServerTest() = default;
 
 void NamedMojoIpcServerTest::SetUp() {
   ipc_server_->StartServer();
-  WaitForInvitationSent();
+  WaitForServerEndpointCreated();
 }
 
 void NamedMojoIpcServerTest::TearDown() {
@@ -124,20 +130,46 @@
   task_environment_.RunUntilIdle();
 }
 
-mojo::PlatformChannelEndpoint NamedMojoIpcServerTest::ConnectToTestServer() {
-  return mojo::NamedPlatformChannel::ConnectToServer(test_server_name_);
+void NamedMojoIpcServerTest::CreateIpcServer() {
+  ipc_server_ = std::make_unique<NamedMojoIpcServer<test::mojom::Echo>>(
+      test_server_name_, this,
+      base::BindRepeating([](base::ProcessId) { return true; }));
+  ipc_server_->set_on_server_endpoint_created_callback_for_testing(
+      base::BindRepeating(&NamedMojoIpcServerTest::OnServerEndpointCreated,
+                          base::Unretained(this)));
 }
 
-mojo::Remote<test::mojom::Echo>
-NamedMojoIpcServerTest::ConnectAndCreateEchoRemote(
-    mojo::IsolatedConnection& client_connection) {
-  return mojo::Remote<test::mojom::Echo>(mojo::PendingRemote<test::mojom::Echo>(
-      client_connection.Connect(ConnectToTestServer()), /* version= */ 0));
+void NamedMojoIpcServerTest::WaitForServerEndpointCreated() {
+  on_server_endpoint_created_run_loop_->Run();
+  on_server_endpoint_created_run_loop_ = std::make_unique<base::RunLoop>();
 }
 
-void NamedMojoIpcServerTest::WaitForInvitationSent() {
-  on_invitation_sent_run_loop_->Run();
-  on_invitation_sent_run_loop_ = std::make_unique<base::RunLoop>();
+base::Process NamedMojoIpcServerTest::LaunchClientProcess(
+    base::StringPiece extra_switch) {
+  base::CommandLine cmd_line = base::GetMultiProcessTestChildBaseCommandLine();
+  cmd_line.AppendSwitchNative(kClientProcessServerNameSwitch,
+                              test_server_name_);
+  if (!extra_switch.empty()) {
+    cmd_line.AppendSwitch(extra_switch);
+  }
+  return base::SpawnMultiProcessTestChild(kEchoClientName, cmd_line,
+                                          /* options= */ {});
+}
+
+int NamedMojoIpcServerTest::WaitForProcessExit(base::Process& process) {
+  int exit_code;
+  bool process_exited = false;
+  base::RunLoop wait_for_process_exit_loop;
+  wait_for_process_exit_thread_.task_runner()->PostTaskAndReply(
+      FROM_HERE, base::BindLambdaForTesting([&]() {
+        process_exited = base::WaitForMultiprocessTestChildExit(
+            process, TestTimeouts::action_timeout(), &exit_code);
+      }),
+      wait_for_process_exit_loop.QuitClosure());
+  wait_for_process_exit_loop.Run();
+  process.Close();
+  EXPECT_TRUE(process_exited);
+  return exit_code;
 }
 
 void NamedMojoIpcServerTest::EchoString(const std::string& input,
@@ -149,29 +181,34 @@
 
   std::move(callback).Run(input);
   last_echo_string_receiver_id_ = ipc_server_->current_receiver();
-  ASSERT_EQ(base::GetCurrentProcId(), ipc_server_->current_peer_pid());
+  last_echo_string_peer_pid_ = ipc_server_->current_peer_pid();
+
+  if (on_echo_string_called_) {
+    on_echo_string_called_.Run();
+  }
 }
 
-void NamedMojoIpcServerTest::OnInvitationSent() {
-  on_invitation_sent_run_loop_->Quit();
+void NamedMojoIpcServerTest::OnServerEndpointCreated() {
+  on_server_endpoint_created_run_loop_->Quit();
 }
 
 TEST_F(NamedMojoIpcServerTest, SendEcho) {
-  mojo::IsolatedConnection client_connection;
-  auto echo_remote = ConnectAndCreateEchoRemote(client_connection);
-  SendEchoAndVerifyResponse(echo_remote);
+  base::Process child_process = LaunchClientProcess();
+  base::ProcessId child_pid = child_process.Pid();
+  EXPECT_EQ(0, WaitForProcessExit(child_process));
+  EXPECT_EQ(child_pid, last_echo_string_peer_pid_);
 }
 
 TEST_F(NamedMojoIpcServerTest, DeleteNamedMojoServer_NoLingeringInvitations) {
   ipc_server_.reset();
   base::RunLoop().RunUntilIdle();
   // For posix, the socket doesn't seem to be closed immediately after the
-  // isolated connection is deleted, so we wait for 1s to make sure the socket
-  // is really closed.
+  // connection is deleted, so we wait for 1s to make sure the socket is really
+  // closed.
   base::PlatformThread::Sleep(base::Seconds(1));
 
-  auto endpoint = ConnectToTestServer();
-  ASSERT_FALSE(endpoint.is_valid());
+  base::Process child_process = LaunchClientProcess();
+  EXPECT_EQ(kInvalidEndpointExitCode, WaitForProcessExit(child_process));
 }
 
 TEST_F(NamedMojoIpcServerTest, DisconnectHandler) {
@@ -183,49 +220,44 @@
   });
   ipc_server_->set_disconnect_handler(disconnect_handler.Get());
 
-  auto client_connection = std::make_unique<mojo::IsolatedConnection>();
-  auto echo_remote = ConnectAndCreateEchoRemote(*client_connection);
+  base::Process child_process = LaunchClientProcess();
+  WaitForProcessExit(child_process);
 
-  // Must send some IPC to be considered connected.
-  SendEchoAndVerifyResponse(echo_remote);
-
-  echo_remote.reset();
-  client_connection.reset();
   disconnect_run_loop.Run();
 }
 
 TEST_F(NamedMojoIpcServerTest, DeleteNamedMojoServer_RemoteDisconnected) {
-  mojo::IsolatedConnection client_connection;
-  auto echo_remote = ConnectAndCreateEchoRemote(client_connection);
-  SendEchoAndVerifyResponse(echo_remote);
+  base::RunLoop wait_for_echo_string_called_run_loop;
+  on_echo_string_called_ = wait_for_echo_string_called_run_loop.QuitClosure();
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessWaitUntilDisconnectedSwitch);
+  wait_for_echo_string_called_run_loop.Run();
 
-  base::RunLoop disconnect_run_loop;
-  echo_remote.set_disconnect_handler(disconnect_run_loop.QuitClosure());
   ipc_server_.reset();
-  disconnect_run_loop.Run();
+  WaitForProcessExit(child_process);
 }
 
 TEST_F(NamedMojoIpcServerTest, StopServer_RemoteDisconnected) {
-  mojo::IsolatedConnection client_connection;
-  auto echo_remote = ConnectAndCreateEchoRemote(client_connection);
-  SendEchoAndVerifyResponse(echo_remote);
+  base::RunLoop wait_for_echo_string_called_run_loop;
+  on_echo_string_called_ = wait_for_echo_string_called_run_loop.QuitClosure();
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessWaitUntilDisconnectedSwitch);
+  wait_for_echo_string_called_run_loop.Run();
 
-  base::RunLoop disconnect_run_loop;
-  echo_remote.set_disconnect_handler(disconnect_run_loop.QuitClosure());
   ipc_server_->StopServer();
-  disconnect_run_loop.Run();
+  WaitForProcessExit(child_process);
 }
 
 TEST_F(NamedMojoIpcServerTest, CloseReceiver_RemoteDisconnected) {
-  mojo::IsolatedConnection client_connection;
-  auto echo_remote = ConnectAndCreateEchoRemote(client_connection);
-  SendEchoAndVerifyResponse(echo_remote);
+  base::RunLoop wait_for_echo_string_called_run_loop;
+  on_echo_string_called_ = wait_for_echo_string_called_run_loop.QuitClosure();
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessWaitUntilDisconnectedSwitch);
+  wait_for_echo_string_called_run_loop.Run();
   ASSERT_EQ(1u, ipc_server_->GetNumberOfActiveConnectionsForTesting());
 
-  base::RunLoop disconnect_run_loop;
-  echo_remote.set_disconnect_handler(disconnect_run_loop.QuitClosure());
   ipc_server_->Close(last_echo_string_receiver_id_);
-  disconnect_run_loop.Run();
+  WaitForProcessExit(child_process);
   ASSERT_EQ(0u, ipc_server_->GetNumberOfActiveConnectionsForTesting());
 }
 
@@ -235,42 +267,37 @@
   ASSERT_EQ(0u, ipc_server_->GetNumberOfActiveConnectionsForTesting());
 }
 
-TEST_F(NamedMojoIpcServerTest, RemoteDisconnected_ConnectionRemoved) {
-  mojo::IsolatedConnection client_connection;
-  auto echo_remote = ConnectAndCreateEchoRemote(client_connection);
-  SendEchoAndVerifyResponse(echo_remote);
+TEST_F(NamedMojoIpcServerTest, RemoteProcessTerminated_ConnectionRemoved) {
+  base::RunLoop wait_for_echo_string_called_run_loop;
+  on_echo_string_called_ = wait_for_echo_string_called_run_loop.QuitClosure();
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessWaitUntilDisconnectedSwitch);
+  wait_for_echo_string_called_run_loop.Run();
   ASSERT_EQ(1u, ipc_server_->GetNumberOfActiveConnectionsForTesting());
 
   base::RunLoop disconnect_run_loop;
   ipc_server_->set_disconnect_handler(disconnect_run_loop.QuitClosure());
-  echo_remote.reset();
+  base::TerminateMultiProcessTestChild(child_process, 0, true);
   disconnect_run_loop.Run();
   ASSERT_EQ(0u, ipc_server_->GetNumberOfActiveConnectionsForTesting());
 }
 
 TEST_F(NamedMojoIpcServerTest,
-       RemoteDisconnectedBeforeBound_NewInvitationIsSent) {
-  mojo::IsolatedConnection client_connection;
-  auto handle = client_connection.Connect(ConnectToTestServer());
-  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
-      FROM_HERE, base::BindLambdaForTesting([&]() { handle.reset(); }));
-  WaitForInvitationSent();
+       RemoteTerminatedBeforeBound_NewServerEndpointCreated) {
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessExitAfterConnectSwitch);
+  WaitForProcessExit(child_process);
+  WaitForServerEndpointCreated();
 }
 
-TEST_F(NamedMojoIpcServerTest, RemoteConnectsAndHangs_NewInvitationIsSent) {
-  mojo::IsolatedConnection client_connection;
-  auto handle = client_connection.Connect(ConnectToTestServer());
-  WaitForInvitationSent();
+TEST_F(NamedMojoIpcServerTest,
+       RemoteConnectsAndHangs_NewServerEndpointCreated) {
+  base::Process child_process =
+      LaunchClientProcess(kClientProcessHangAfterConnectSwitch);
+  WaitForServerEndpointCreated();
 }
 
 TEST_F(NamedMojoIpcServerTest, ParallelIpcs) {
-  base::RunLoop echo_response_run_loop;
-  base::MockCallback<EchoStringCallback> echo_mock_callback;
-  EXPECT_CALL(echo_mock_callback, Run(_))
-      .WillOnce(Return())
-      .WillOnce(
-          base::test::RunOnceClosure(echo_response_run_loop.QuitClosure()));
-
   base::MockCallback<EchoStringHandler> mock_echo_string_handler;
   echo_string_handler_ = mock_echo_string_handler.Get();
   std::string first_input;
@@ -285,15 +312,78 @@
         std::move(callback).Run(input);
       });
 
-  mojo::IsolatedConnection client_connection_1;
-  auto echo_remote_1 = ConnectAndCreateEchoRemote(client_connection_1);
-  echo_remote_1->EchoString("test string 1", echo_mock_callback.Get());
-  WaitForInvitationSent();
+  base::Process child_process_1 = LaunchClientProcess();
+  WaitForServerEndpointCreated();
 
-  mojo::IsolatedConnection client_connection_2;
-  auto echo_remote_2 = ConnectAndCreateEchoRemote(client_connection_2);
-  echo_remote_2->EchoString("test string 2", echo_mock_callback.Get());
-  echo_response_run_loop.Run();
+  base::Process child_process_2 = LaunchClientProcess();
+
+  WaitForProcessExit(child_process_1);
+  WaitForProcessExit(child_process_2);
 }
 
+TEST_F(NamedMojoIpcServerTest, IpcServerRestarted_NewIpcsCanBeMade) {
+  base::Process child_process = LaunchClientProcess();
+  WaitForProcessExit(child_process);
+
+  ipc_server_.reset();
+  CreateIpcServer();
+  ipc_server_->StartServer();
+  WaitForServerEndpointCreated();
+
+  child_process = LaunchClientProcess();
+  WaitForProcessExit(child_process);
+}
+
+// Client process main function. The default behavior is to send "test string"
+// to the EchoString() interface and verify that the server returns the same
+// string.
+MULTIPROCESS_TEST_MAIN(EchoClient) {
+  base::test::TaskEnvironment task_environment{
+      base::test::TaskEnvironment::MainThreadType::IO};
+  auto ipc_support = std::make_unique<mojo::core::ScopedIPCSupport>(
+      task_environment.GetMainThreadTaskRunner(),
+      mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
+
+  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+  auto server_name =
+      cmd_line->GetSwitchValueNative(kClientProcessServerNameSwitch);
+  EXPECT_FALSE(server_name.empty());
+  auto endpoint = mojo::NamedPlatformChannel::ConnectToServer(server_name);
+  if (!endpoint.is_valid()) {
+    return kInvalidEndpointExitCode;
+  }
+  if (cmd_line->HasSwitch(kClientProcessExitAfterConnectSwitch)) {
+    return 0;
+  }
+  if (cmd_line->HasSwitch(kClientProcessHangAfterConnectSwitch)) {
+    base::RunLoop().Run();
+    return 0;
+  }
+  std::unique_ptr<mojo::IsolatedConnection> connection =
+      std::make_unique<mojo::IsolatedConnection>();
+  auto echo_remote =
+      mojo::Remote<test::mojom::Echo>(mojo::PendingRemote<test::mojom::Echo>(
+          connection->Connect(std::move(endpoint)), /* version= */ 0));
+  base::RunLoop wait_for_disconnect_run_loop;
+  echo_remote.set_disconnect_handler(
+      wait_for_disconnect_run_loop.QuitClosure());
+
+  base::RunLoop echo_response_run_loop;
+  auto callback = base::BindLambdaForTesting([&](const std::string& response) {
+    ASSERT_EQ("test string", response);
+    echo_response_run_loop.Quit();
+  });
+  echo_remote->EchoString("test string", std::move(callback));
+
+  if (cmd_line->HasSwitch(kClientProcessWaitUntilDisconnectedSwitch)) {
+    // The server might close the connection before the response is sent, so we
+    // don't wait for the echo response here.
+    wait_for_disconnect_run_loop.Run();
+  } else {
+    echo_response_run_loop.Run();
+  }
+  return 0;
+}
+
+}  // namespace
 }  // namespace named_mojo_ipc_server
diff --git a/components/omnibox/browser/local_history_zero_suggest_provider.cc b/components/omnibox/browser/local_history_zero_suggest_provider.cc
index be24bc4c..b560d38 100644
--- a/components/omnibox/browser/local_history_zero_suggest_provider.cc
+++ b/components/omnibox/browser/local_history_zero_suggest_provider.cc
@@ -49,8 +49,12 @@
 std::u16string GetSearchTermsFromURL(const GURL& url,
                                      TemplateURLService* template_url_service) {
   DCHECK(template_url_service);
+  const TemplateURL* default_provider =
+      template_url_service->GetDefaultSearchProvider();
+  DCHECK(default_provider);
+
   std::u16string search_terms;
-  template_url_service->GetDefaultSearchProvider()->ExtractSearchTermsFromURL(
+  default_provider->ExtractSearchTermsFromURL(
       url, template_url_service->search_terms_data(), &search_terms);
   return base::i18n::ToLower(base::CollapseWhitespace(search_terms, false));
 }
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 6823f390..c7ad9a22 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -819,6 +819,7 @@
 
   const TemplateURL* default_search_provider =
       client_->GetTemplateURLService()->GetDefaultSearchProvider();
+  DCHECK(default_search_provider);
   keyword_ = default_search_provider->keyword();
   is_keyword_hint_ = false;
   keyword_mode_entry_method_ = entry_method;
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn
index 763e837..ebc0b648 100644
--- a/components/optimization_guide/core/BUILD.gn
+++ b/components/optimization_guide/core/BUILD.gn
@@ -65,6 +65,14 @@
     "//components/optimization_guide:machine_learning_tflite_buildflags",
     "//third_party/re2",
   ]
+  deps = [
+    ":features",
+    "//base",
+    "//components/optimization_guide/proto:optimization_guide_proto",
+    "//net",
+    "//url",
+  ]
+
   if (build_with_tflite_lib) {
     public_deps += [
       "//components/optimization_guide/core:machine_learning",
@@ -74,15 +82,8 @@
       "//third_party/tflite_support",
       "//third_party/tflite_support:tflite_support_proto",
     ]
+    deps += [ ":machine_learning" ]
   }
-  deps = [
-    ":features",
-    ":machine_learning",
-    "//base",
-    "//components/optimization_guide/proto:optimization_guide_proto",
-    "//net",
-    "//url",
-  ]
 }
 
 mojom("interfaces") {
diff --git a/components/password_manager/core/browser/http_credentials_cleaner.cc b/components/password_manager/core/browser/http_credentials_cleaner.cc
index 45fbbd92..420d1e1 100644
--- a/components/password_manager/core/browser/http_credentials_cleaner.cc
+++ b/components/password_manager/core/browser/http_credentials_cleaner.cc
@@ -83,7 +83,7 @@
   if (user_it == https_credentials_map_.end()) {
     // Credentials are not migrated yet.
     base::UmaHistogramEnumeration(
-        "PasswordManager.HttpCredentials",
+        "PasswordManager.HttpCredentials2",
         is_hsts ? HttpCredentialType::kHasNoMatchingHttpsWithHsts
                 : HttpCredentialType::kHasNoMatchingHttpsWithoutHsts);
     if (is_hsts) {
@@ -99,7 +99,7 @@
     // The password store contains the same credentials (signon_realm, scheme,
     // username and password) on HTTPS version of the form.
     base::UmaHistogramEnumeration(
-        "PasswordManager.HttpCredentials",
+        "PasswordManager.HttpCredentials2",
         is_hsts ? HttpCredentialType::kHasEquivalentHttpsWithHsts
                 : HttpCredentialType::kHasEquivalentHttpsWithoutHsts);
     if (is_hsts) {
@@ -108,7 +108,7 @@
     }
   } else {
     base::UmaHistogramEnumeration(
-        "PasswordManager.HttpCredentials",
+        "PasswordManager.HttpCredentials2",
         is_hsts ? HttpCredentialType::kHasConflictingHttpsWithHsts
                 : HttpCredentialType::kHasConflictingHttpsWithoutHsts);
   }
diff --git a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
index 180317d3..1405ab0 100644
--- a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
+++ b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -218,7 +218,7 @@
   task_environment.RunUntilIdle();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.HttpCredentials",
+      "PasswordManager.HttpCredentials2",
       static_cast<HttpCredentialCleaner::HttpCredentialType>(
           static_cast<int>(test.expected) * 2 + test.is_hsts_enabled),
       1);
diff --git a/components/password_manager/core/browser/http_password_store_migrator.cc b/components/password_manager/core/browser/http_password_store_migrator.cc
index f041604..ee8df22a 100644
--- a/components/password_manager/core/browser/http_password_store_migrator.cc
+++ b/components/password_manager/core/browser/http_password_store_migrator.cc
@@ -135,9 +135,9 @@
 
   // Only log data if there was at least one migrated password.
   if (!results_.empty()) {
-    base::UmaHistogramCounts100("PasswordManager.HttpPasswordMigrationCount",
+    base::UmaHistogramCounts100("PasswordManager.HttpPasswordMigrationCount2",
                                 results_.size());
-    base::UmaHistogramEnumeration("PasswordManager.HttpPasswordMigrationMode",
+    base::UmaHistogramEnumeration("PasswordManager.HttpPasswordMigrationMode2",
                                   mode_);
   }
 
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index d3b32ee..53415ba 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -278,7 +278,7 @@
 }
 
 void LogDatabaseInitError(DatabaseInitError error) {
-  UMA_HISTOGRAM_ENUMERATION("PasswordManager.LoginDatabaseInit", error,
+  UMA_HISTOGRAM_ENUMERATION("PasswordManager.LoginDatabaseInit2", error,
                             DATABASE_INIT_ERROR_COUNT);
 }
 
@@ -952,7 +952,7 @@
 void LoginDatabase::ReportBubbleSuppressionMetrics() {
 #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
   base::UmaHistogramCustomCounts(
-      "PasswordManager.BubbleSuppression.AccountsInStatisticsTable",
+      "PasswordManager.BubbleSuppression.AccountsInStatisticsTable2",
       stats_table_.GetNumAccounts(), 0, 1000, 100);
 #endif  // !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
 }
@@ -975,7 +975,7 @@
   base::StringPiece suffix_for_store =
       is_account_store_.value() ? ".AccountStore" : "";
   base::UmaHistogramCounts100(base::StrCat({kPasswordManager, suffix_for_store,
-                                            ".InaccessiblePasswords"}),
+                                            ".InaccessiblePasswords2"}),
                               failed_encryption);
 }
 
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index c760f287..a96e3c07 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -1551,11 +1551,11 @@
   db().ReportMetrics();
   account_db.ReportMetrics();
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.InaccessiblePasswords",
+  histogram_tester.ExpectUniqueSample("PasswordManager.InaccessiblePasswords2",
                                       0, 1);
 #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.BubbleSuppression.AccountsInStatisticsTable", 4, 1);
+      "PasswordManager.BubbleSuppression.AccountsInStatisticsTable2", 4, 1);
 #endif  // !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
 }
 
@@ -1581,7 +1581,7 @@
   account_db.ReportMetrics();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.InaccessiblePasswords", 0, 1);
+      "PasswordManager.AccountStore.InaccessiblePasswords2", 0, 1);
 }
 
 TEST_F(LoginDatabaseTest, NoMetadata) {
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc
index bb69702..bf85343 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -169,7 +169,7 @@
 }
 
 void LogPasswordSyncState(PasswordSyncState state) {
-  base::UmaHistogramEnumeration("PasswordManager.PasswordSyncState2", state);
+  base::UmaHistogramEnumeration("PasswordManager.PasswordSyncState3", state);
 }
 
 void LogApplySyncChangesState(ApplySyncChangesState state) {
@@ -358,7 +358,7 @@
 void LogProtectedPasswordHashCounts(size_t gaia_hash_count,
                                     bool does_primary_account_exists,
                                     bool is_signed_in) {
-  base::UmaHistogramCounts100("PasswordManager.SavedGaiaPasswordHashCount",
+  base::UmaHistogramCounts100("PasswordManager.SavedGaiaPasswordHashCount2",
                               static_cast<int>(gaia_hash_count));
 
   // Log parallel metrics for sync and signed-in non-sync accounts in addition
@@ -366,11 +366,11 @@
   // are protecting compared to syncing users.
   if (does_primary_account_exists) {
     base::UmaHistogramCounts100(
-        "PasswordManager.SavedGaiaPasswordHashCount.Sync",
+        "PasswordManager.SavedGaiaPasswordHashCount2.Sync",
         static_cast<int>(gaia_hash_count));
   } else if (is_signed_in) {
     base::UmaHistogramCounts100(
-        "PasswordManager.SavedGaiaPasswordHashCount.SignedInNonSync",
+        "PasswordManager.SavedGaiaPasswordHashCount2.SignedInNonSync",
         static_cast<int>(gaia_hash_count));
   }
 }
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index 81ac1da..a27ba5e 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -120,7 +120,7 @@
 
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
-// Metrics: "PasswordManager.PasswordSyncState2"
+// Metrics: "PasswordManager.PasswordSyncState3"
 enum class PasswordSyncState {
   kSyncingOk = 0,
   kNotSyncingFailedRead = 1,
diff --git a/components/password_manager/core/browser/store_metrics_reporter.cc b/components/password_manager/core/browser/store_metrics_reporter.cc
index d418a68c..8d8cee5 100644
--- a/components/password_manager/core/browser/store_metrics_reporter.cc
+++ b/components/password_manager/core/browser/store_metrics_reporter.cc
@@ -78,7 +78,7 @@
                                   int sample) {
   base::UmaHistogramCustomCounts(
       base::StrCat({kPasswordManager, suffix_for_store,
-                    ".TotalAccountsHiRes2.WithScheme.", scheme}),
+                    ".TotalAccountsHiRes3.WithScheme.", scheme}),
       sample, 1, 1000, 100);
 }
 
@@ -115,7 +115,7 @@
     }
 
     constexpr base::StringPiece kAccountsPerSiteSuffix =
-        ".AccountsPerSiteHiRes2";
+        ".AccountsPerSiteHiRes3";
 
     if (password_type == PasswordForm::Type::kGenerated) {
       total_generated_accounts += accounts_per_site;
@@ -138,7 +138,7 @@
   }
 
   static constexpr base::StringPiece kTotalAccountsByTypeSuffix =
-      ".TotalAccountsHiRes2.ByType";
+      ".TotalAccountsHiRes3.ByType";
 
   LogAccountStatHiRes(
       base::StrCat({kPasswordManager, store_suffix, kTotalAccountsByTypeSuffix,
@@ -156,7 +156,7 @@
       total_user_created_accounts + total_generated_accounts);
 
   LogAccountStatHiRes(
-      base::StrCat({kPasswordManager, store_suffix, ".BlacklistedSitesHiRes2",
+      base::StrCat({kPasswordManager, store_suffix, ".BlacklistedSitesHiRes3",
                     custom_passphrase_suffix}),
       blocklisted_sites);
 }
@@ -215,12 +215,12 @@
 
   base::UmaHistogramCounts1000(
       base::StrCat({kPasswordManager, suffix_for_store,
-                    ".PasswordNotes.CountCredentialsWithNonEmptyNotes"}),
+                    ".PasswordNotes.CountCredentialsWithNonEmptyNotes2"}),
       credentials_with_non_empty_notes_count);
 
   const std::string histogram_name =
       base::StrCat({kPasswordManager, suffix_for_store,
-                    ".PasswordNotes.CountNotesPerCredential"});
+                    ".PasswordNotes.CountNotesPerCredential2"});
   base::ranges::for_each(forms, [histogram_name](const auto& form) {
     base::UmaHistogramCounts100(histogram_name, form->notes.size());
   });
@@ -239,7 +239,7 @@
     const int times_used = form->times_used;
 
     static constexpr base::StringPiece kTimesPasswordUsedSuffix =
-        ".TimesPasswordUsed2";
+        ".TimesPasswordUsed3";
 
     if (type == PasswordForm::Type::kGenerated) {
       LogTimesUsedStat(
@@ -281,7 +281,7 @@
                  ? SyncingAccountState::kSyncingAndSyncPasswordSaved
                  : SyncingAccountState::kSyncingAndSyncPasswordNotSaved);
   base::UmaHistogramEnumeration(
-      base::StrCat({kPasswordManager, ".SyncingAccountState2"}),
+      base::StrCat({kPasswordManager, ".SyncingAccountState3"}),
       sync_account_state);
 }
 
@@ -318,10 +318,10 @@
   }
 
   base::UmaHistogramCustomCounts(
-      base::StrCat({kPasswordManager, ".CredentialsWithDuplicates2"}),
+      base::StrCat({kPasswordManager, ".CredentialsWithDuplicates3"}),
       credentials_with_duplicates, 0, 32, 6);
   base::UmaHistogramCustomCounts(
-      base::StrCat({kPasswordManager, ".CredentialsWithMismatchedDuplicates2"}),
+      base::StrCat({kPasswordManager, ".CredentialsWithMismatchedDuplicates3"}),
       credentials_with_mismatched_duplicates, 0, 32, 6);
 }
 
@@ -332,12 +332,12 @@
     return !form->password_issues.contains(InsecureType::kLeaked);
   });
   base::UmaHistogramCounts100(
-      base::StrCat({kPasswordManager, ".CompromisedCredentials2.CountLeaked"}),
+      base::StrCat({kPasswordManager, ".CompromisedCredentials3.CountLeaked"}),
       count_leaked);
   if (bulk_check_done) {
     base::UmaHistogramCounts100(
         base::StrCat({kPasswordManager,
-                      ".CompromisedCredentials2.CountLeakedAfterBulkCheck"}),
+                      ".CompromisedCredentials3.CountLeakedAfterBulkCheck"}),
         count_leaked);
   }
 
@@ -345,7 +345,7 @@
     return !form->password_issues.contains(InsecureType::kPhished);
   });
   base::UmaHistogramCounts100(
-      base::StrCat({kPasswordManager, ".CompromisedCredentials2.CountPhished"}),
+      base::StrCat({kPasswordManager, ".CompromisedCredentials3.CountPhished"}),
       count_phished);
 }
 
@@ -410,19 +410,19 @@
   if (is_opted_in) {
     base::UmaHistogramCounts100(
         base::StrCat(
-            {kPasswordManager, ".AccountStoreVsProfileStore3.Additional"}),
+            {kPasswordManager, ".AccountStoreVsProfileStore4.Additional"}),
         additional);
     base::UmaHistogramCounts100(
         base::StrCat(
-            {kPasswordManager, ".AccountStoreVsProfileStore3.Missing"}),
+            {kPasswordManager, ".AccountStoreVsProfileStore4.Missing"}),
         missing);
     base::UmaHistogramCounts100(
         base::StrCat(
-            {kPasswordManager, ".AccountStoreVsProfileStore3.Identical"}),
+            {kPasswordManager, ".AccountStoreVsProfileStore4.Identical"}),
         identical);
     base::UmaHistogramCounts100(
         base::StrCat(
-            {kPasswordManager, ".AccountStoreVsProfileStore3.Conflicting"}),
+            {kPasswordManager, ".AccountStoreVsProfileStore4.Conflicting"}),
         conflicting);
   }
 }
@@ -430,7 +430,7 @@
 void ReportBiometricAuthenticationBeforeFillingMetrics(PrefService* prefs) {
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
   base::UmaHistogramBoolean(
-      base::StrCat({kPasswordManager, ".BiometricAuthBeforeFillingEnabled"}),
+      base::StrCat({kPasswordManager, ".BiometricAuthBeforeFillingEnabled2"}),
       prefs->GetBoolean(
           password_manager::prefs::kBiometricAuthenticationBeforeFilling));
 #endif
@@ -486,7 +486,7 @@
   is_opted_in_ = features_util::IsOptedInForAccountStorage(prefs, sync_service);
 
   base::UmaHistogramBoolean(
-      base::StrCat({kPasswordManager, ".Enabled3"}),
+      base::StrCat({kPasswordManager, ".Enabled4"}),
       prefs->GetBoolean(password_manager::prefs::kCredentialsEnableService));
 
   ReportBiometricAuthenticationBeforeFillingMetrics(prefs);
diff --git a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
index c0f82ea..32699f0 100644
--- a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
+++ b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
@@ -188,7 +188,7 @@
       /*is_under_advanced_protection=*/false,
       /*done_callback*/ base::DoNothing());
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.Enabled3",
+  histogram_tester.ExpectUniqueSample("PasswordManager.Enabled4",
                                       password_manager_enabled, 1);
 }
 
@@ -209,7 +209,7 @@
       /*done_callback*/ base::DoNothing());
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.BiometricAuthBeforeFillingEnabled",
+      "PasswordManager.BiometricAuthBeforeFillingEnabled2",
       biometric_auth_before_filling_enabled, 1);
 }
 #endif
@@ -227,7 +227,7 @@
       profile_store.get(), /*account_store=*/nullptr, sync_service(),
       identity_manager(), &prefs_, /*password_reuse_manager=*/nullptr,
       /*is_under_advanced_protection=*/false, done_callback.Get());
-  histogram_tester.ExpectTotalCount("PasswordManager.Enabled3", 1);
+  histogram_tester.ExpectTotalCount("PasswordManager.Enabled4", 1);
   EXPECT_CALL(done_callback, Run());
   RunUntilIdle();
 
@@ -240,7 +240,7 @@
       profile_store.get(), /*account_store=*/nullptr, sync_service(),
       identity_manager(), &prefs_, /*password_reuse_manager=*/nullptr,
       /*is_under_advanced_protection=*/false, done_callback2.Get());
-  histogram_tester2.ExpectTotalCount("PasswordManager.Enabled3", 0);
+  histogram_tester2.ExpectTotalCount("PasswordManager.Enabled4", 0);
   EXPECT_CALL(done_callback2, Run());
   RunUntilIdle();
 
@@ -275,29 +275,29 @@
   RunUntilIdle();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.AccountsPerSiteHiRes2."
+      "PasswordManager.ProfileStore.AccountsPerSiteHiRes3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       1, 2);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.AccountsPerSiteHiRes2."
+      "PasswordManager.ProfileStore.AccountsPerSiteHiRes3."
       "UserCreated."
       "WithoutCustomPassphrase",
       1, 3);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.AccountsPerSiteHiRes2."
+      "PasswordManager.ProfileStore.AccountsPerSiteHiRes3."
       "UserCreated."
       "WithoutCustomPassphrase",
       2, 2);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.AccountsPerSiteHiRes2."
+      "PasswordManager.ProfileStore.AccountsPerSiteHiRes3."
       "Overall."
       "WithoutCustomPassphrase",
       1, 5);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.AccountsPerSiteHiRes2."
+      "PasswordManager.ProfileStore.AccountsPerSiteHiRes3."
       "Overall."
       "WithoutCustomPassphrase",
       2, 2);
@@ -335,44 +335,44 @@
   RunUntilIdle();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "ByType."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       2, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "ByType."
       "UserCreated."
       "WithoutCustomPassphrase",
       7, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "ByType.Overall."
       "WithoutCustomPassphrase",
       9, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "WithScheme."
       "Android",
       2, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "WithScheme.Ftp",
       1, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "WithScheme.Http",
       5, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "WithScheme.Https",
       1, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.ProfileStore.TotalAccountsHiRes2."
+      "PasswordManager.ProfileStore.TotalAccountsHiRes3."
       "WithScheme.Other",
       0, 1);
 
@@ -409,50 +409,50 @@
   RunUntilIdle();
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       2, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       4, 1);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       0, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       1, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       3, 1);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       0, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       1, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       2, 1);
   // The bucket for 3 and 4 is the same. Thus we expect two samples here.
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.ProfileStore.TimesPasswordUsed2."
+      "PasswordManager.ProfileStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       3, 2);
@@ -500,29 +500,29 @@
   RunUntilIdle();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.AccountsPerSiteHiRes2."
+      "PasswordManager.AccountStore.AccountsPerSiteHiRes3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       1, 2);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.AccountsPerSiteHiRes2."
+      "PasswordManager.AccountStore.AccountsPerSiteHiRes3."
       "UserCreated."
       "WithoutCustomPassphrase",
       1, 3);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.AccountsPerSiteHiRes2."
+      "PasswordManager.AccountStore.AccountsPerSiteHiRes3."
       "UserCreated."
       "WithoutCustomPassphrase",
       2, 2);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.AccountsPerSiteHiRes2."
+      "PasswordManager.AccountStore.AccountsPerSiteHiRes3."
       "Overall."
       "WithoutCustomPassphrase",
       1, 5);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.AccountsPerSiteHiRes2."
+      "PasswordManager.AccountStore.AccountsPerSiteHiRes3."
       "Overall."
       "WithoutCustomPassphrase",
       2, 2);
@@ -566,41 +566,41 @@
   RunUntilIdle();
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "ByType.AutoGenerated."
       "WithoutCustomPassphrase",
       2, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "ByType.UserCreated."
       "WithoutCustomPassphrase",
       7, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "ByType.Overall."
       "WithoutCustomPassphrase",
       9, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "WithScheme.Android",
       2, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "WithScheme.Ftp",
       1, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "WithScheme.Http",
       5, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "WithScheme.Https",
       1, 1);
   histogram_tester.ExpectUniqueSample(
-      "PasswordManager.AccountStore.TotalAccountsHiRes2."
+      "PasswordManager.AccountStore.TotalAccountsHiRes3."
       "WithScheme.Other",
       0, 1);
 
@@ -643,50 +643,50 @@
   RunUntilIdle();
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       2, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "AutoGenerated."
       "WithoutCustomPassphrase",
       4, 1);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       0, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       1, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "UserCreated."
       "WithoutCustomPassphrase",
       3, 1);
 
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       0, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       1, 1);
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       2, 1);
   // The bucket for 3 and 4 is the same. Thus we expect two samples here.
   histogram_tester.ExpectBucketCount(
-      "PasswordManager.AccountStore.TimesPasswordUsed2."
+      "PasswordManager.AccountStore.TimesPasswordUsed3."
       "Overall."
       "WithoutCustomPassphrase",
       3, 2);
@@ -743,11 +743,11 @@
   RunUntilIdle();
 
   EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "PasswordManager.CredentialsWithDuplicates2"),
+                  "PasswordManager.CredentialsWithDuplicates3"),
               testing::ElementsAre(base::Bucket(0, 1)));
   EXPECT_THAT(
       histogram_tester.GetAllSamples("PasswordManager."
-                                     "CredentialsWithMismatchedDuplicates2"),
+                                     "CredentialsWithMismatchedDuplicates3"),
       testing::ElementsAre(base::Bucket(0, 1)));
 
   profile_store->ShutdownOnUIThread();
@@ -796,11 +796,11 @@
 
   // There should be 2 groups of "exact" duplicates.
   EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "PasswordManager.CredentialsWithDuplicates2"),
+                  "PasswordManager.CredentialsWithDuplicates3"),
               testing::ElementsAre(base::Bucket(2, 1)));
   EXPECT_THAT(
       histogram_tester.GetAllSamples("PasswordManager."
-                                     "CredentialsWithMismatchedDuplicates2"),
+                                     "CredentialsWithMismatchedDuplicates3"),
       testing::ElementsAre(base::Bucket(0, 1)));
 
   profile_store->ShutdownOnUIThread();
@@ -846,11 +846,11 @@
   RunUntilIdle();
 
   EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "PasswordManager.CredentialsWithDuplicates2"),
+                  "PasswordManager.CredentialsWithDuplicates3"),
               testing::ElementsAre(base::Bucket(0, 1)));
   EXPECT_THAT(
       histogram_tester.GetAllSamples("PasswordManager."
-                                     "CredentialsWithMismatchedDuplicates2"),
+                                     "CredentialsWithMismatchedDuplicates3"),
       testing::ElementsAre(base::Bucket(1, 1)));
 
   profile_store->ShutdownOnUIThread();
@@ -955,36 +955,36 @@
 
     if (opted_in) {
       histogram_tester.ExpectUniqueSample(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Additional",
           2, 1);
       histogram_tester.ExpectUniqueSample(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Missing",
           4, 1);
       histogram_tester.ExpectUniqueSample(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Identical",
           2, 1);
       histogram_tester.ExpectUniqueSample(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Conflicting",
           1, 1);
     } else {
       histogram_tester.ExpectTotalCount(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Additional",
           0);
       histogram_tester.ExpectTotalCount(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Missing",
           0);
       histogram_tester.ExpectTotalCount(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Identical",
           0);
       histogram_tester.ExpectTotalCount(
-          "PasswordManager.AccountStoreVsProfileStore3."
+          "PasswordManager.AccountStoreVsProfileStore4."
           "Conflicting",
           0);
     }
@@ -1034,46 +1034,46 @@
   password_form.username_value = u"test1@gmail.com";
   password_form.notes = {PasswordNote(u"note", base::Time::Now())};
   profile_store->AddLogin(password_form);
-  // ProfileStore - CountCredentialsWithNonEmptyNotes: 1
+  // ProfileStore - CountCredentialsWithNonEmptyNotes2: 1
 
   password_form.username_value = u"test2@gmail.com";
   password_form.notes = {PasswordNote(u"another note", base::Time::Now()),
                          PasswordNote(std::u16string(), base::Time::Now())};
   profile_store->AddLogin(password_form);
-  // ProfileStore - CountCredentialsWithNonEmptyNotes: 2
+  // ProfileStore - CountCredentialsWithNonEmptyNotes2: 2
 
   password_form.username_value = u"test3@gmail.com";
   password_form.notes = {PasswordNote(std::u16string(), base::Time::Now()),
                          PasswordNote(u"some note", base::Time::Now())};
   profile_store->AddLogin(password_form);
-  // ProfileStore -  CountCredentialsWithNonEmptyNotes: 3
+  // ProfileStore -  CountCredentialsWithNonEmptyNotes2: 3
 
   password_form.username_value = u"test4@gmail.com";
   password_form.notes = {PasswordNote(std::u16string(), base::Time::Now())};
   profile_store->AddLogin(password_form);
-  // ProfileStore - CountCredentialsWithNonEmptyNotes: 3
+  // ProfileStore - CountCredentialsWithNonEmptyNotes2: 3
 
   password_form.username_value = u"test5@gmail.com";
   password_form.notes = {};
   profile_store->AddLogin(password_form);
-  // ProfileStore - CountCredentialsWithNonEmptyNotes: 3
+  // ProfileStore - CountCredentialsWithNonEmptyNotes2: 3
 
   auto account_store =
       base::MakeRefCounted<TestPasswordStore>(IsAccountStore(true));
   account_store->Init(&prefs_, /*affiliated_match_helper=*/nullptr);
 
   account_store->AddLogin(password_form);
-  // AccountStore - CountCredentialsWithNonEmptyNotes: 0
+  // AccountStore - CountCredentialsWithNonEmptyNotes2: 0
 
   password_form.username_value = u"test6@gmail.com";
   password_form.notes = {PasswordNote(std::u16string(), base::Time::Now())};
   account_store->AddLogin(password_form);
-  // AccountStore - CountCredentialsWithNonEmptyNotes: 0
+  // AccountStore - CountCredentialsWithNonEmptyNotes2: 0
 
   password_form.username_value = u"test7@gmail.com";
   password_form.notes = {PasswordNote(u"note", base::Time::Now())};
   account_store->AddLogin(password_form);
-  // AccountStore - CountCredentialsWithNonEmptyNotes: 1
+  // AccountStore - CountCredentialsWithNonEmptyNotes2: 1
 
   base::HistogramTester histogram_tester;
   StoreMetricsReporter reporter(profile_store.get(), account_store.get(),
@@ -1085,21 +1085,21 @@
   RunUntilIdle();
 
   EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "PasswordManager.ProfileStore.PasswordNotes.CountNotesPerCredential"),
+      histogram_tester.GetAllSamples("PasswordManager.ProfileStore."
+                                     "PasswordNotes.CountNotesPerCredential2"),
       BucketsAre(base::Bucket(0, 1), base::Bucket(1, 2), base::Bucket(2, 2)));
   histogram_tester.ExpectBucketCount(
       "PasswordManager.ProfileStore.PasswordNotes."
-      "CountCredentialsWithNonEmptyNotes",
+      "CountCredentialsWithNonEmptyNotes2",
       3, 1);
 
   EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "PasswordManager.AccountStore.PasswordNotes.CountNotesPerCredential"),
+      histogram_tester.GetAllSamples("PasswordManager.AccountStore."
+                                     "PasswordNotes.CountNotesPerCredential2"),
       BucketsAre(base::Bucket(0, 1), base::Bucket(1, 2)));
   histogram_tester.ExpectBucketCount(
       "PasswordManager.AccountStore.PasswordNotes."
-      "CountCredentialsWithNonEmptyNotes",
+      "CountCredentialsWithNonEmptyNotes2",
       1, 1);
 
   account_store->ShutdownOnUIThread();
diff --git a/components/password_manager/core/browser/sync/password_model_type_controller.cc b/components/password_manager/core/browser/sync/password_model_type_controller.cc
index 7993c55..1c2b3ea5 100644
--- a/components/password_manager/core/browser/sync/password_model_type_controller.cc
+++ b/components/password_manager/core/browser/sync/password_model_type_controller.cc
@@ -33,7 +33,7 @@
 
 void RecordClearedOnStartup(ClearedOnStartup state) {
   base::UmaHistogramEnumeration(
-      "PasswordManager.AccountStorage.ClearedOnStartup", state);
+      "PasswordManager.AccountStorage.ClearedOnStartup2", state);
 }
 
 void PasswordStoreClearDone(bool cleared) {
@@ -67,10 +67,9 @@
               base::Unretained(this))) {
   identity_manager_->AddObserver(this);
 
-  DCHECK_EQ(
-      base::FeatureList::IsEnabled(features::kEnablePasswordsAccountStorage),
-      !!account_password_store_for_cleanup);
-  if (base::FeatureList::IsEnabled(features::kEnablePasswordsAccountStorage)) {
+  if (account_password_store_for_cleanup) {
+    DCHECK(
+        base::FeatureList::IsEnabled(features::kEnablePasswordsAccountStorage));
     // Note: Right now, we're still in the middle of SyncService initialization,
     // so we can't check IsOptedInForAccountStorage() yet (SyncService might not
     // have determined the syncing account yet). Post a task do to it after the
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 335f05c..a6f7666 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -320,7 +320,7 @@
       batch->SetModelTypeState(model_state);
     }
   }
-  base::UmaHistogramEnumeration("PasswordManager.SyncMetadataReadError",
+  base::UmaHistogramEnumeration("PasswordManager.SyncMetadataReadError2",
                                 sync_metadata_read_error);
 
   if (batch) {
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
index 167ba43..bdd5cf2 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -885,7 +885,7 @@
       PasswordSyncBridge(mock_processor().CreateForwardingProcessor(),
                          mock_password_store_sync(), base::DoNothing());
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError",
+  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2",
                                       /*kNone*/ 0, 1);
 }
 
@@ -911,7 +911,7 @@
       PasswordSyncBridge(mock_processor().CreateForwardingProcessor(),
                          mock_password_store_sync(), base::DoNothing());
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError",
+  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2",
                                       3, 1);
 }
 
@@ -949,7 +949,7 @@
       mock_processor().CreateForwardingProcessor(), mock_password_store_sync(),
       base::DoNothing());
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError",
+  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2",
                                       4, 1);
 }
 
@@ -1015,7 +1015,7 @@
       mock_processor().CreateForwardingProcessor(), mock_password_store_sync(),
       base::DoNothing());
 
-  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError",
+  histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2",
                                       5, 1);
 }
 
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc
index d346860..4a8aaf50 100644
--- a/components/pdf/renderer/pdf_accessibility_tree.cc
+++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -1227,9 +1227,12 @@
   if (features::IsPdfOcrEnabled() && render_frame) {
     content::RenderAccessibility* render_accessibility =
         GetRenderAccessibilityIfEnabled();
-    DCHECK(render_accessibility);
-    ocr_service_ = std::make_unique<PdfOcrService>(
-        render_accessibility->GetTreeIDForPluginHost(), *render_frame);
+    // PdfAccessibilityTree is created even when accessibility services are not
+    // enabled and we rely on them to use PdfOcr service.
+    if (render_accessibility) {
+      ocr_service_ = std::make_unique<PdfOcrService>(
+          render_accessibility->GetTreeIDForPluginHost(), *render_frame);
+    }
   }
 #endif  // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
 }
diff --git a/components/policy/resources/webui/status_box.html b/components/policy/resources/webui/status_box.html
index 604b80a..4853fa6 100644
--- a/components/policy/resources/webui/status_box.html
+++ b/components/policy/resources/webui/status_box.html
@@ -113,4 +113,8 @@
     <div class="label">$i18n{labelLastCloudReportSentTimestamp}</div>
     <div class="last-cloud-report-sent-timestamp"></div>
   </div>
+  <div class="status-entry" hidden>
+    <div class="label">$i18n{labelError}:</div>
+    <div class="error"></div>
+  </div>
 </fieldset>
diff --git a/components/policy/resources/webui/status_box.js b/components/policy/resources/webui/status_box.js
index 647ecb3..d407195 100644
--- a/components/policy/resources/webui/status_box.js
+++ b/components/policy/resources/webui/status_box.js
@@ -125,6 +125,11 @@
           status.lastCloudReportSentTimestamp + ' (' +
               status.timeSinceLastCloudReportSent + ')');
     }
+
+    if (status.error) {
+      this.setLabelAndShow_(
+          '.error', loadTimeData.getString('statusErrorManagedNoPolicy'));
+    }
   }
 }
 
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp
index 57195c4..fbf20e94 100644
--- a/components/policy_strings.grdp
+++ b/components/policy_strings.grdp
@@ -398,6 +398,9 @@
     Google Update
   </message>
  </if>
+  <message name="IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY" desc="Message to display when a managed device does not have a policy loaded.">
+    Managed user or device has no policy loaded.
+  </message>
   <message name="IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DOMAIN" desc="Label for the enrollment domain in the machine policy status box.">
     Enrollment domain:
   </message>
diff --git a/components/policy_strings_grdp/IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY.png.sha1
new file mode 100644
index 0000000..f37b39f
--- /dev/null
+++ b/components/policy_strings_grdp/IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY.png.sha1
@@ -0,0 +1 @@
+90916627300aacf24afe46c6b2b50554c6b6d2f1
\ No newline at end of file
diff --git a/components/power_bookmarks/core/power_bookmark_service.cc b/components/power_bookmarks/core/power_bookmark_service.cc
index 9209d7c..31ece6d 100644
--- a/components/power_bookmarks/core/power_bookmark_service.cc
+++ b/components/power_bookmarks/core/power_bookmark_service.cc
@@ -67,21 +67,27 @@
                                        SuccessCallback callback) {
   backend_.AsyncCall(&PowerBookmarkBackend::CreatePower)
       .WithArgs(std::move(power))
-      .Then(std::move(callback));
+      .Then(base::BindOnce(&PowerBookmarkService::NotifyPowersChanged,
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(callback)));
 }
 
 void PowerBookmarkService::UpdatePower(std::unique_ptr<Power> power,
                                        SuccessCallback callback) {
   backend_.AsyncCall(&PowerBookmarkBackend::UpdatePower)
       .WithArgs(std::move(power))
-      .Then(std::move(callback));
+      .Then(base::BindOnce(&PowerBookmarkService::NotifyPowersChanged,
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(callback)));
 }
 
 void PowerBookmarkService::DeletePower(const base::GUID& guid,
                                        SuccessCallback callback) {
   backend_.AsyncCall(&PowerBookmarkBackend::DeletePower)
       .WithArgs(guid)
-      .Then(std::move(callback));
+      .Then(base::BindOnce(&PowerBookmarkService::NotifyPowersChanged,
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(callback)));
 }
 
 void PowerBookmarkService::DeletePowersForURL(const GURL& url,
@@ -89,7 +95,30 @@
                                               SuccessCallback callback) {
   backend_.AsyncCall(&PowerBookmarkBackend::DeletePowersForURL)
       .WithArgs(url, power_type)
-      .Then(std::move(callback));
+      .Then(base::BindOnce(&PowerBookmarkService::NotifyPowersChanged,
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(callback)));
+}
+
+void PowerBookmarkService::NotifyPowersChanged(SuccessCallback callback,
+                                               bool success) {
+  std::move(callback).Run(success);
+
+  // If the create/update/delete call wasn't successful, then there was no
+  // functional change to the backend. In this case, skip notifying observers.
+  if (!success)
+    return;
+
+  for (auto& observer : observers_)
+    observer.OnPowersChanged();
+}
+
+void PowerBookmarkService::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void PowerBookmarkService::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
 }
 
 void PowerBookmarkService::AddDataProvider(
diff --git a/components/power_bookmarks/core/power_bookmark_service.h b/components/power_bookmarks/core/power_bookmark_service.h
index 687bc1cb..27c8666 100644
--- a/components/power_bookmarks/core/power_bookmark_service.h
+++ b/components/power_bookmarks/core/power_bookmark_service.h
@@ -33,9 +33,20 @@
     std::vector<std::unique_ptr<PowerOverview>> power_overviews)>;
 using SuccessCallback = base::OnceCallback<void(bool success)>;
 
+// Provides a public API surface for power bookmarks. The storage lives on a
+// background thread, all results from there require a callback.
+// Callbacks for the result of create/update/delete calls are wrapped so that
+// observers can be notified when any changes to the storage occur.
 class PowerBookmarkService : public KeyedService,
                              public bookmarks::BaseBookmarkModelObserver {
  public:
+  // Observer class for any changes to the underlying storage.
+  class Observer {
+   public:
+    // Called whenever there are changes to Powers.
+    virtual void OnPowersChanged() = 0;
+  };
+
   PowerBookmarkService(
       bookmarks::BookmarkModel* model,
       const base::FilePath& database_dir,
@@ -89,6 +100,14 @@
                           const PowerType& power_type,
                           SuccessCallback callback);
 
+  // Captures storage changes to forward along to observers. Returns the
+  // result of the call to `callback` and notifies observers after.
+  void NotifyPowersChanged(SuccessCallback callback, bool success);
+
+  // Registration methods for observers.
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
   // Allow features to receive notification when a bookmark node is created to
   // add extra information. The `data_provider` can be removed with the remove
   // method.
@@ -107,7 +126,10 @@
   base::SequenceBound<PowerBookmarkBackend> backend_;
   scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
 
+  base::ObserverList<Observer>::Unchecked observers_;
   std::vector<PowerBookmarkDataProvider*> data_providers_;
+
+  base::WeakPtrFactory<PowerBookmarkService> weak_ptr_factory_{this};
 };
 
 }  // namespace power_bookmarks
diff --git a/components/power_bookmarks/core/power_bookmark_service_unittest.cc b/components/power_bookmarks/core/power_bookmark_service_unittest.cc
index b9fb211..f00dc13b 100644
--- a/components/power_bookmarks/core/power_bookmark_service_unittest.cc
+++ b/components/power_bookmarks/core/power_bookmark_service_unittest.cc
@@ -77,6 +77,11 @@
                     PowerBookmarkMeta* meta));
 };
 
+class MockObserver : public PowerBookmarkService::Observer {
+ public:
+  MOCK_METHOD0(OnPowersChanged, void());
+};
+
 TEST_F(PowerBookmarkServiceTest, AddDataProvider) {
   MockDataProvider data_provider;
   service()->AddDataProvider(&data_provider);
@@ -275,4 +280,46 @@
   RunUntilIdle();
 }
 
+TEST_F(PowerBookmarkServiceTest, ObserverCalled) {
+  MockObserver obs;
+  service()->AddObserver(&obs);
+  EXPECT_CALL(obs, OnPowersChanged());
+
+  base::MockCallback<SuccessCallback> success_cb;
+  EXPECT_CALL(success_cb, Run(IsTrue()));
+
+  base::GUID guid = base::GUID::GenerateRandomV4();
+  std::unique_ptr<PowerSpecifics> power_specifics =
+      std::make_unique<PowerSpecifics>();
+  std::unique_ptr<Power> power =
+      std::make_unique<Power>(std::move(power_specifics));
+  power->set_guid(guid);
+  power->set_url(GURL("https://google.com"));
+  power->set_power_type(PowerType::POWER_TYPE_MOCK);
+  service()->CreatePower(std::move(power), success_cb.Get());
+  RunUntilIdle();
+
+  EXPECT_CALL(obs, OnPowersChanged());
+  EXPECT_CALL(success_cb, Run(IsTrue()));
+
+  power_specifics = std::make_unique<PowerSpecifics>();
+  power = std::make_unique<Power>(std::move(power_specifics));
+  power->set_url(GURL("https://google.com"));
+  power->set_power_type(PowerType::POWER_TYPE_MOCK);
+  service()->UpdatePower(std::move(power), success_cb.Get());
+  RunUntilIdle();
+
+  EXPECT_CALL(obs, OnPowersChanged());
+  EXPECT_CALL(success_cb, Run(IsTrue()));
+  service()->DeletePowersForURL(GURL("https://google.com"),
+                                PowerType::POWER_TYPE_MOCK, success_cb.Get());
+  RunUntilIdle();
+
+  service()->RemoveObserver(&obs);
+  EXPECT_CALL(obs, OnPowersChanged()).Times(0);
+  EXPECT_CALL(success_cb, Run(IsTrue()));
+
+  service()->DeletePower(guid, success_cb.Get());
+  RunUntilIdle();
+}
 }  // namespace power_bookmarks
diff --git a/components/rlz/rlz_tracker_unittest.cc b/components/rlz/rlz_tracker_unittest.cc
index 6391d529..3520988 100644
--- a/components/rlz/rlz_tracker_unittest.cc
+++ b/components/rlz/rlz_tracker_unittest.cc
@@ -1032,10 +1032,8 @@
 
 TEST_F(RlzLibTest, DoNotRecordEventUnlessShouldSendRlzPingKeyIsTrue) {
   // Verify the event is recorded when |kShouldSendRlzPingKey| is true.
-  std::string should_send_rlz_ping_value;
-  ASSERT_TRUE(statistics_provider_->GetMachineStatistic(
-      chromeos::system::kShouldSendRlzPingKey, &should_send_rlz_ping_value));
-  ASSERT_EQ(should_send_rlz_ping_value,
+  ASSERT_EQ(statistics_provider_->GetMachineStatistic(
+                chromeos::system::kShouldSendRlzPingKey),
             chromeos::system::kShouldSendRlzPingValueTrue);
   RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::ChromeOmnibox(),
                                  rlz_lib::FIRST_SEARCH);
@@ -1047,9 +1045,8 @@
   statistics_provider_->SetMachineStatistic(
       chromeos::system::kShouldSendRlzPingKey,
       chromeos::system::kShouldSendRlzPingValueFalse);
-  ASSERT_TRUE(statistics_provider_->GetMachineStatistic(
-      chromeos::system::kShouldSendRlzPingKey, &should_send_rlz_ping_value));
-  ASSERT_EQ(should_send_rlz_ping_value,
+  ASSERT_EQ(statistics_provider_->GetMachineStatistic(
+                chromeos::system::kShouldSendRlzPingKey),
             chromeos::system::kShouldSendRlzPingValueFalse);
   RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::ChromeOmnibox(),
                                  rlz_lib::FIRST_SEARCH);
@@ -1060,7 +1057,7 @@
   statistics_provider_->ClearMachineStatistic(
       chromeos::system::kShouldSendRlzPingKey);
   ASSERT_FALSE(statistics_provider_->GetMachineStatistic(
-      chromeos::system::kShouldSendRlzPingKey, &should_send_rlz_ping_value));
+      chromeos::system::kShouldSendRlzPingKey));
   RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::ChromeOmnibox(),
                                  rlz_lib::FIRST_SEARCH);
   ExpectEventRecorded(OmniboxFirstSearch(), false);
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index 7756f83..73f57cc 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -170,7 +170,7 @@
 
 BASE_FEATURE(kSafeBrowsingCsbrrWithToken,
              "SafeBrowsingCsbrrWithToken",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kSafeBrowsingDisableConsumerCsdForEnterprise,
              "SafeBrowsingDisableConsumerCsdForEnterprise",
diff --git a/components/search/start_suggest_service.cc b/components/search/start_suggest_service.cc
index 837f364..a8661f77 100644
--- a/components/search/start_suggest_service.cc
+++ b/components/search/start_suggest_service.cc
@@ -133,8 +133,11 @@
 
 GURL StartSuggestService::GetRequestURL(
     const TemplateURLRef::SearchTermsArgs& search_terms_args) {
+  const TemplateURL* default_provider =
+      template_url_service_->GetDefaultSearchProvider();
+  DCHECK(default_provider);
   const TemplateURLRef& suggestion_url_ref =
-      template_url_service_->GetDefaultSearchProvider()->suggestions_url_ref();
+      default_provider->suggestions_url_ref();
   const SearchTermsData& search_terms_data =
       template_url_service_->search_terms_data();
   DCHECK(suggestion_url_ref.SupportsReplacement(search_terms_data));
@@ -158,6 +161,7 @@
     const std::u16string& query,
     const TemplateURL* search_provider) {
   TemplateURLRef::SearchTermsArgs search_terms_args(query);
+  DCHECK(search_provider);
   const TemplateURLRef& search_url_ref = search_provider->url_ref();
   const SearchTermsData& search_terms_data =
       template_url_service_->search_terms_data();
diff --git a/components/sqlite_proto/key_value_data.h b/components/sqlite_proto/key_value_data.h
index 1dffdf8..962afc9 100644
--- a/components/sqlite_proto/key_value_data.h
+++ b/components/sqlite_proto/key_value_data.h
@@ -14,6 +14,8 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
@@ -100,6 +102,10 @@
   // Force cached updates to be immediately flushed to disk.
   void FlushDataToDisk();
 
+  // As above, but runs `on_done` when all tasks have finished flushing to disk,
+  // including any previously posted tasks.
+  void FlushDataToDisk(base::OnceClosure on_done);
+
  private:
   struct EntryCompare : private Compare {
     bool operator()(const std::pair<std::string, T>& lhs,
@@ -260,6 +266,16 @@
   deferred_updates_.clear();
 }
 
+template <typename T, typename Compare>
+void KeyValueData<T, Compare>::FlushDataToDisk(base::OnceClosure on_done) {
+  FlushDataToDisk();
+
+  // Wait for all tasks posted to the task runner before now to complete. This
+  // accounts for any previously scheduled updates as well.
+  manager_->ScheduleDBTaskWithReply(FROM_HERE, base::DoNothing(),
+                                    std::move(on_done));
+}
+
 }  // namespace sqlite_proto
 
 #endif  // COMPONENTS_SQLITE_PROTO_KEY_VALUE_DATA_H_
diff --git a/components/sqlite_proto/table_manager.cc b/components/sqlite_proto/table_manager.cc
index f9488c0..5380029 100644
--- a/components/sqlite_proto/table_manager.cc
+++ b/components/sqlite_proto/table_manager.cc
@@ -26,6 +26,16 @@
                                 std::move(task)));
 }
 
+void TableManager::ScheduleDBTaskWithReply(const base::Location& from_here,
+                                           DBTask task,
+                                           base::OnceClosure reply) {
+  GetTaskRunner()->PostTaskAndReply(
+      from_here,
+      base::BindOnce(&TableManager::ExecuteDBTaskOnDBSequence, this,
+                     std::move(task)),
+      std::move(reply));
+}
+
 void TableManager::ExecuteDBTaskOnDBSequence(DBTask task) {
   DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence());
   if (CantAccessDatabase())
diff --git a/components/sqlite_proto/table_manager.h b/components/sqlite_proto/table_manager.h
index aae1ae60..8c57d33 100644
--- a/components/sqlite_proto/table_manager.h
+++ b/components/sqlite_proto/table_manager.h
@@ -39,6 +39,10 @@
 
   virtual void ScheduleDBTask(const base::Location& from_here,
                               base::OnceCallback<void(sql::Database*)> task);
+  virtual void ScheduleDBTaskWithReply(
+      const base::Location& from_here,
+      base::OnceCallback<void(sql::Database*)> task,
+      base::OnceClosure reply);
 
   virtual void ExecuteDBTaskOnDBSequence(
       base::OnceCallback<void(sql::Database*)> task);
diff --git a/components/sync/base/BUILD.gn b/components/sync/base/BUILD.gn
index a59d63b..38f3dae 100644
--- a/components/sync/base/BUILD.gn
+++ b/components/sync/base/BUILD.gn
@@ -45,6 +45,8 @@
     "stop_source.h",
     "sync_invalidation.cc",
     "sync_invalidation.h",
+    "sync_invalidation_adapter.cc",
+    "sync_invalidation_adapter.h",
     "sync_mode.h",
     "sync_prefs.cc",
     "sync_prefs.h",
diff --git a/components/sync/base/sync_invalidation_adapter.cc b/components/sync/base/sync_invalidation_adapter.cc
new file mode 100644
index 0000000..38f794e
--- /dev/null
+++ b/components/sync/base/sync_invalidation_adapter.cc
@@ -0,0 +1,34 @@
+// 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 "components/sync/base/sync_invalidation_adapter.h"
+#include "base/check.h"
+
+namespace syncer {
+
+SyncInvalidationAdapter::SyncInvalidationAdapter(
+    const std::string& payload,
+    absl::optional<int64_t> version)
+    : payload_(payload), version_(version) {}
+
+SyncInvalidationAdapter::~SyncInvalidationAdapter() = default;
+
+bool SyncInvalidationAdapter::IsUnknownVersion() const {
+  return !version_.has_value();
+}
+
+const std::string& SyncInvalidationAdapter::GetPayload() const {
+  return payload_;
+}
+
+int64_t SyncInvalidationAdapter::GetVersion() const {
+  DCHECK(version_.has_value());
+  return version_.value();
+}
+
+void SyncInvalidationAdapter::Acknowledge() {}
+
+void SyncInvalidationAdapter::Drop() {}
+
+}  // namespace syncer
diff --git a/components/sync/base/sync_invalidation_adapter.h b/components/sync/base/sync_invalidation_adapter.h
new file mode 100644
index 0000000..f6d47e1
--- /dev/null
+++ b/components/sync/base/sync_invalidation_adapter.h
@@ -0,0 +1,37 @@
+// 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 COMPONENTS_SYNC_BASE_SYNC_INVALIDATION_ADAPTER_H_
+#define COMPONENTS_SYNC_BASE_SYNC_INVALIDATION_ADAPTER_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "components/sync/base/sync_invalidation.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace syncer {
+
+class SyncInvalidationAdapter : public SyncInvalidation {
+ public:
+  SyncInvalidationAdapter(const std::string& payload,
+                          absl::optional<int64_t> version);
+  ~SyncInvalidationAdapter() override;
+
+  // Implementation of SyncInvalidation.
+  bool IsUnknownVersion() const override;
+  const std::string& GetPayload() const override;
+  int64_t GetVersion() const override;
+  void Acknowledge() override;
+  void Drop() override;
+
+ private:
+  const std::string payload_;
+  const absl::optional<int64_t> version_;
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_BASE_SYNC_INVALIDATION_ADAPTER_H_
diff --git a/components/sync/driver/glue/sync_engine_backend.cc b/components/sync/driver/glue/sync_engine_backend.cc
index 6a583a8..30d2009 100644
--- a/components/sync/driver/glue/sync_engine_backend.cc
+++ b/components/sync/driver/glue/sync_engine_backend.cc
@@ -18,6 +18,7 @@
 #include "components/sync/base/features.h"
 #include "components/sync/base/invalidation_adapter.h"
 #include "components/sync/base/legacy_directory_deletion.h"
+#include "components/sync/base/sync_invalidation_adapter.h"
 #include "components/sync/driver/configure_context.h"
 #include "components/sync/driver/glue/sync_engine_impl.h"
 #include "components/sync/driver/model_type_controller.h"
@@ -33,7 +34,6 @@
 #include "components/sync/nigori/nigori_storage_impl.h"
 #include "components/sync/nigori/nigori_sync_bridge_impl.h"
 #include "components/sync/protocol/sync_invalidations_payload.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Helper macros to log with the syncer thread name; useful when there
 // are multiple syncers involved.
@@ -47,31 +47,6 @@
 const base::FilePath::CharType kNigoriStorageFilename[] =
     FILE_PATH_LITERAL("Nigori.bin");
 
-class SyncInvalidationAdapter : public SyncInvalidation {
- public:
-  SyncInvalidationAdapter(const std::string& payload,
-                          absl::optional<int64_t> version)
-      : payload_(payload), version_(version) {}
-  ~SyncInvalidationAdapter() override = default;
-
-  bool IsUnknownVersion() const override { return !version_.has_value(); }
-
-  const std::string& GetPayload() const override { return payload_; }
-
-  int64_t GetVersion() const override {
-    DCHECK(version_.has_value());
-    return version_.value();
-  }
-
-  void Acknowledge() override {}
-
-  void Drop() override {}
-
- private:
-  const std::string payload_;
-  const absl::optional<int64_t> version_;
-};
-
 void RecordInvalidationPerModelType(ModelType type) {
   UMA_HISTOGRAM_ENUMERATION("Sync.InvalidationPerModelType",
                             ModelTypeHistogramValue(type));
diff --git a/components/sync/engine/model_type_worker.cc b/components/sync/engine/model_type_worker.cc
index 67acccd..10de707 100644
--- a/components/sync/engine/model_type_worker.cc
+++ b/components/sync/engine/model_type_worker.cc
@@ -30,6 +30,7 @@
 #include "components/sync/base/features.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/base/model_type.h"
+#include "components/sync/base/sync_invalidation_adapter.h"
 #include "components/sync/base/time.h"
 #include "components/sync/base/unique_position.h"
 #include "components/sync/engine/bookmark_update_preprocessing.h"
@@ -234,6 +235,46 @@
   // previously persisted values.
   model_type_state_.mutable_progress_marker()->clear_gc_directive();
 
+  if (!model_type_state_.invalidations().empty()) {
+    if (base::FeatureList::IsEnabled(kSyncPersistInvalidations)) {
+      if (static_cast<size_t>(model_type_state_.invalidations_size()) >
+          kMaxPendingInvalidations) {
+        DVLOG(1) << "Cleaning invalidations in |model_type_state_| due to "
+                    "invalidations overflow.";
+        model_type_state_.clear_invalidations();
+      }
+      for (int i = 0; i < model_type_state_.invalidations_size(); ++i) {
+        pending_invalidations_.emplace_back(
+            std::make_unique<SyncInvalidationAdapter>(
+                model_type_state_.invalidations(i).hint(),
+                model_type_state_.invalidations(i).has_version()
+                    ? absl::optional<int64_t>(
+                          model_type_state_.invalidations(i).version())
+                    : absl::nullopt),
+            false);
+      }
+
+      bool is_version_order_correct = true;
+      for (size_t i = 1; i < pending_invalidations_.size(); ++i) {
+        is_version_order_correct &= (SyncInvalidation::LessThanByVersion(
+            *pending_invalidations_[i - 1].pending_invalidation,
+            *pending_invalidations_[i].pending_invalidation));
+      }
+      if (!is_version_order_correct) {
+        DVLOG(1) << "Cleaning invalidations in |model_type_state| due to "
+                    "incorrect version order.";
+        pending_invalidations_.clear();
+        model_type_state_.clear_invalidations();
+      }
+    } else {
+      // In case the feature was enabled in previous session, some invalidations
+      // might be loaded to |model_type_state_| from storage. As feature is
+      // disabled now, invalidations in |model_type_state_| and
+      // |pending_invalidations_| should be in sync.
+      model_type_state_.clear_invalidations();
+    }
+  }
+
   if (!CommitOnlyTypes().Has(GetModelType())) {
     DCHECK_EQ(type, GetModelTypeFromSpecificsFieldNumber(
                         initial_state.progress_marker().data_type_id()));
diff --git a/components/sync/engine/model_type_worker_unittest.cc b/components/sync/engine/model_type_worker_unittest.cc
index d9867b11..4dab845d 100644
--- a/components/sync/engine/model_type_worker_unittest.cc
+++ b/components/sync/engine/model_type_worker_unittest.cc
@@ -177,6 +177,26 @@
     nudge_handler()->ClearCounters();
   }
 
+  void InitializeWithInvalidations() {
+    ModelTypeState initial_state;
+    initial_state.mutable_progress_marker()->set_data_type_id(
+        GetSpecificsFieldNumberFromModelType(model_type_));
+    initial_state.mutable_progress_marker()->set_token(
+        "some_saved_progress_token");
+
+    sync_pb::ModelTypeState_Invalidation* loaded_invalidation =
+        initial_state.add_invalidations();
+
+    loaded_invalidation->set_hint("loaded_hint_1");
+    loaded_invalidation->set_version(1);
+
+    initial_state.set_initial_sync_done(true);
+
+    InitializeWithState(model_type_, initial_state);
+
+    nudge_handler()->ClearCounters();
+  }
+
   void InitializeCommitOnly(ModelType model_type) {
     mock_server_ = std::make_unique<SingleTypeMockServer>(model_type);
 
@@ -2648,6 +2668,19 @@
       syncer::PasswordNotesStateForUMA::kSetOnlyInBackupButCorrupted, 1);
 }
 
+// Verifies persisting invalidations load from the ModelTypeProcessor.
+TEST_F(ModelTypeWorkerTest, LoadInvalidations) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(kSyncPersistInvalidations);
+
+  InitializeWithInvalidations();
+
+  sync_pb::GetUpdateTriggers gu_trigger_1;
+  worker()->CollectPendingInvalidations(&gu_trigger_1);
+  ASSERT_EQ(1, gu_trigger_1.notification_hint_size());
+  EXPECT_THAT(gu_trigger_1.notification_hint(), Not(testing::IsEmpty()));
+}
+
 // Verifies StorePendingInvalidations() calls for every incoming invalidation.
 TEST_F(ModelTypeWorkerTest, StoreInvalidationsCallCount) {
   base::test::ScopedFeatureList feature;
diff --git a/components/viz/common/resources/resource_format_utils.cc b/components/viz/common/resources/resource_format_utils.cc
index 620153f..19e898b2 100644
--- a/components/viz/common/resources/resource_format_utils.cc
+++ b/components/viz/common/resources/resource_format_utils.cc
@@ -168,37 +168,6 @@
   return 0;
 }
 
-bool HasAlpha(ResourceFormat format) {
-  switch (format) {
-    case RGBA_8888:
-    case RGBA_4444:
-    case BGRA_8888:
-    case ALPHA_8:
-    case RGBA_F16:
-    case YUVA_420_TRIPLANAR:
-      return true;
-    case LUMINANCE_8:
-    case RGB_565:
-    case BGR_565:
-    case ETC1:
-    case RED_8:
-    case RG_88:
-    case LUMINANCE_F16:
-    case R16_EXT:
-    case RG16_EXT:
-    case RGBX_8888:
-    case BGRX_8888:
-    case RGBA_1010102:
-    case BGRA_1010102:
-    case YVU_420:
-    case YUV_420_BIPLANAR:
-    case P010:
-      return false;
-  }
-  NOTREACHED();
-  return false;
-}
-
 unsigned int GLDataType(ResourceFormat format) {
   DCHECK_LE(format, RESOURCE_FORMAT_MAX);
   static const GLenum format_gl_data_type[] = {
@@ -643,10 +612,6 @@
   return BitsPerPixel(format.resource_format());
 }
 
-bool HasAlpha(SharedImageFormat format) {
-  return HasAlpha(format.resource_format());
-}
-
 unsigned int GLDataType(SharedImageFormat format) {
   return GLDataType(format.resource_format());
 }
@@ -663,10 +628,6 @@
   return BufferFormat(format.resource_format());
 }
 
-bool IsResourceFormatCompressed(SharedImageFormat format) {
-  return IsResourceFormatCompressed(format.resource_format());
-}
-
 unsigned int TextureStorageFormat(SharedImageFormat format,
                                   bool use_angle_rgbx_format) {
   return TextureStorageFormat(format.resource_format(), use_angle_rgbx_format);
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h
index fe5e1bb..bddbfb5 100644
--- a/components/viz/common/resources/resource_format_utils.h
+++ b/components/viz/common/resources/resource_format_utils.h
@@ -27,7 +27,6 @@
 ResourceFormatToClosestSkColorType(bool gpu_compositing, ResourceFormat format);
 
 VIZ_RESOURCE_FORMAT_EXPORT int BitsPerPixel(ResourceFormat format);
-VIZ_RESOURCE_FORMAT_EXPORT bool HasAlpha(ResourceFormat format);
 VIZ_RESOURCE_FORMAT_EXPORT ResourceFormat
 SkColorTypeToResourceFormat(SkColorType color_type);
 
@@ -94,7 +93,6 @@
                                    SharedImageFormat format);
 
 VIZ_RESOURCE_FORMAT_EXPORT int BitsPerPixel(SharedImageFormat format);
-VIZ_RESOURCE_FORMAT_EXPORT bool HasAlpha(SharedImageFormat format);
 
 VIZ_RESOURCE_FORMAT_EXPORT unsigned int GLDataType(SharedImageFormat format);
 VIZ_RESOURCE_FORMAT_EXPORT unsigned int GLDataFormat(SharedImageFormat format);
@@ -103,8 +101,6 @@
 
 VIZ_RESOURCE_FORMAT_EXPORT gfx::BufferFormat BufferFormat(
     SharedImageFormat format);
-VIZ_RESOURCE_FORMAT_EXPORT bool IsResourceFormatCompressed(
-    SharedImageFormat format);
 
 VIZ_RESOURCE_FORMAT_EXPORT unsigned int TextureStorageFormat(
     SharedImageFormat format,
diff --git a/components/viz/common/resources/shared_image_format.cc b/components/viz/common/resources/shared_image_format.cc
index 0b961ddc..2285bad 100644
--- a/components/viz/common/resources/shared_image_format.cc
+++ b/components/viz/common/resources/shared_image_format.cc
@@ -132,6 +132,35 @@
   }
 }
 
+bool SharedImageFormat::HasAlpha() const {
+  if (is_single_plane()) {
+    switch (resource_format()) {
+      case ResourceFormat::RGBA_8888:
+      case ResourceFormat::RGBA_4444:
+      case ResourceFormat::BGRA_8888:
+      case ResourceFormat::ALPHA_8:
+      case ResourceFormat::RGBA_F16:
+      case ResourceFormat::YUVA_420_TRIPLANAR:
+        return true;
+      default:
+        return false;
+    }
+  } else if (is_multi_plane()) {
+    switch (plane_config()) {
+      case PlaneConfig::kY_UV_A:
+        return true;
+      default:
+        return false;
+    }
+  }
+  NOTREACHED();
+  return false;
+}
+
+bool SharedImageFormat::IsCompressed() const {
+  return is_single_plane() && resource_format() == ResourceFormat::ETC1;
+}
+
 bool SharedImageFormat::operator==(const SharedImageFormat& o) const {
   if (plane_type_ != o.plane_type())
     return false;
diff --git a/components/viz/common/resources/shared_image_format.h b/components/viz/common/resources/shared_image_format.h
index 6287f5c..747145e 100644
--- a/components/viz/common/resources/shared_image_format.h
+++ b/components/viz/common/resources/shared_image_format.h
@@ -103,6 +103,12 @@
 
   std::string ToString() const;
 
+  // Returns true if the format contains alpha.
+  bool HasAlpha() const;
+
+  // Returns true if the format is ETC1 compressed.
+  bool IsCompressed() const;
+
   bool operator==(const SharedImageFormat& o) const;
   bool operator!=(const SharedImageFormat& o) const;
 
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
index 8d724ed..923cd82 100644
--- a/components/viz/host/host_frame_sink_manager.cc
+++ b/components/viz/host/host_frame_sink_manager.cc
@@ -431,6 +431,17 @@
   frame_sink_manager_->UpdateDebugRendererSettings(debug_settings);
 }
 
+void HostFrameSinkManager::StartFrameCountingForTest(
+    base::TimeDelta bucket_size) {
+  frame_sink_manager_->StartFrameCountingForTest(bucket_size);  // IN-TEST
+}
+
+void HostFrameSinkManager::StopFrameCountingForTest(
+    mojom::FrameSinkManager::StopFrameCountingForTestCallback callback) {
+  frame_sink_manager_->StopFrameCountingForTest(  // IN-TEST
+      std::move(callback));
+}
+
 HostFrameSinkManager::FrameSinkData::FrameSinkData() = default;
 
 HostFrameSinkManager::FrameSinkData::FrameSinkData(FrameSinkData&& other) =
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h
index 0c8c1a6..4dc56a3 100644
--- a/components/viz/host/host_frame_sink_manager.h
+++ b/components/viz/host/host_frame_sink_manager.h
@@ -219,6 +219,13 @@
 
   void UpdateDebugRendererSettings(const DebugRendererSettings& debug_settings);
 
+  // Starts the frame counting in Viz.
+  void StartFrameCountingForTest(base::TimeDelta bucket_size);
+
+  // Ends the frame counting in Viz thread and returns data to the client.
+  void StopFrameCountingForTest(
+      mojom::FrameSinkManager::StopFrameCountingForTestCallback callback);
+
   const DebugRendererSettings& debug_renderer_settings() const {
     return debug_renderer_settings_;
   }
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index af5a1b2..fb793e9 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -149,6 +149,8 @@
     "frame_sinks/compositor_frame_sink_support.h",
     "frame_sinks/external_begin_frame_source_mojo.cc",
     "frame_sinks/external_begin_frame_source_mojo.h",
+    "frame_sinks/frame_counter.cc",
+    "frame_sinks/frame_counter.h",
     "frame_sinks/frame_sink_bundle_impl.cc",
     "frame_sinks/frame_sink_bundle_impl.h",
     "frame_sinks/frame_sink_manager_impl.cc",
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
index 6b8e0eec..6dce42f 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -29,6 +29,7 @@
 #include "components/viz/common/surfaces/video_capture_target.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/frame_counter.h"
 #include "components/viz/service/frame_sinks/frame_sink_bundle_impl.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "components/viz/service/surfaces/surface.h"
@@ -752,6 +753,11 @@
          frame_timing_details_.end());
   frame_timing_details_.emplace(frame_token, details);
 
+  if (!feedback.failed() && frame_sink_manager_->frame_counter()) {
+    frame_sink_manager_->frame_counter()->AddPresentedFrame(frame_sink_id_,
+                                                            feedback.timestamp);
+  }
+
   UpdateNeedsBeginFramesInternal();
 }
 
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
index 4f5c46b..54c9033f 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -241,6 +241,10 @@
     return current_capture_bounds_;
   }
 
+  mojom::CompositorFrameSinkType frame_sink_type() const {
+    return frame_sink_type_;
+  }
+
  private:
   friend class CompositorFrameSinkSupportTest;
   friend class DisplayTest;
diff --git a/components/viz/service/frame_sinks/frame_counter.cc b/components/viz/service/frame_sinks/frame_counter.cc
new file mode 100644
index 0000000..0745f6b0
--- /dev/null
+++ b/components/viz/service/frame_sinks/frame_counter.cc
@@ -0,0 +1,67 @@
+// 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 "components/viz/service/frame_sinks/frame_counter.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/check.h"
+#include "base/containers/contains.h"
+#include "base/time/time.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
+
+namespace viz {
+namespace {
+
+// Max number of frame count records. It is 1800s when bucket size if 1s and
+// no tests should run longer than 1800s.
+constexpr size_t kMaxFrameRecords = 1800u;
+
+}  // namespace
+
+FrameCounter::FrameCounter(base::TimeDelta bucket_size)
+    : start_time_(base::TimeTicks::Now()), bucket_size_(bucket_size) {}
+
+FrameCounter::~FrameCounter() = default;
+
+void FrameCounter::AddFrameSink(const FrameSinkId& frame_sink_id,
+                                mojom::CompositorFrameSinkType type,
+                                bool is_root) {
+  DCHECK(!base::Contains(frame_sink_data_, frame_sink_id));
+
+  auto per_sink_data = mojom::FrameCountingPerSinkData::New(
+      type, is_root, std::vector<uint16_t>());
+  per_sink_data->presented_frames.reserve(kMaxFrameRecords);
+
+  frame_sink_data_[frame_sink_id] = std::move(per_sink_data);
+}
+
+void FrameCounter::AddPresentedFrame(const FrameSinkId& frame_sink_id,
+                                     base::TimeTicks present_timestamp) {
+  auto& per_sink_data = frame_sink_data_[frame_sink_id];
+  DCHECK(!per_sink_data.is_null());
+
+  DCHECK_LE(start_time_, present_timestamp);
+  size_t bucket_index =
+      (present_timestamp - start_time_).InSeconds() / bucket_size_.InSeconds();
+  DCHECK_LT(bucket_index, kMaxFrameRecords);
+
+  auto& presented_frames = per_sink_data->presented_frames;
+  if (bucket_index >= presented_frames.size())
+    presented_frames.resize(bucket_index + 1, 0u);
+
+  ++presented_frames[bucket_index];
+}
+
+mojom::FrameCountingDataPtr FrameCounter::TakeData() {
+  mojom::FrameCountingDataPtr data = mojom::FrameCountingData::New();
+  for (auto& [sink_id, per_sink_data] : frame_sink_data_) {
+    data->per_sink_data.emplace_back(std::move(per_sink_data));
+  }
+  frame_sink_data_.clear();
+  return data;
+}
+
+}  // namespace viz
diff --git a/components/viz/service/frame_sinks/frame_counter.h b/components/viz/service/frame_sinks/frame_counter.h
new file mode 100644
index 0000000..7a33f88
--- /dev/null
+++ b/components/viz/service/frame_sinks/frame_counter.h
@@ -0,0 +1,49 @@
+// 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 COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_COUNTER_H_
+#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_COUNTER_H_
+
+#include "base/containers/flat_map.h"
+#include "base/time/time.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
+#include "components/viz/service/viz_service_export.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom-forward.h"
+#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-shared.h"
+
+namespace viz {
+
+// Counts presented frames per frame sink. Used in tests to provide fps data
+// per frame sink.
+class VIZ_SERVICE_EXPORT FrameCounter {
+ public:
+  explicit FrameCounter(base::TimeDelta bucket_size);
+  ~FrameCounter();
+
+  // Add a record for a frame sink.
+  void AddFrameSink(const FrameSinkId& frame_sink_id,
+                    mojom::CompositorFrameSinkType type,
+                    bool is_root);
+
+  // Add a presented frame for the frame sink.
+  void AddPresentedFrame(const FrameSinkId& frame_sink_id,
+                         base::TimeTicks present_timetamp);
+
+  // Takes the collected frame counts.
+  mojom::FrameCountingDataPtr TakeData();
+
+ private:
+  // Time when the frame counting is stated.
+  const base::TimeTicks start_time_;
+
+  // Bucket size of the frame count records.
+  const base::TimeDelta bucket_size_;
+
+  base::flat_map<FrameSinkId, mojom::FrameCountingPerSinkDataPtr>
+      frame_sink_data_;
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_COUNTER_H_
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index 61037ee..b55780a 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -428,6 +428,11 @@
     UpdateThrottlingRecursively(frame_sink_id,
                                 global_throttle_interval_.value());
   }
+
+  if (frame_counter_) {
+    frame_counter_->AddFrameSink(frame_sink_id, support->frame_sink_type(),
+                                 support->is_root());
+  }
 }
 
 void FrameSinkManagerImpl::UnregisterCompositorFrameSinkSupport(
@@ -822,4 +827,23 @@
   return manager;
 }
 
+void FrameSinkManagerImpl::StartFrameCountingForTest(
+    base::TimeDelta bucket_size) {
+  DCHECK(!frame_counter_.has_value());
+  frame_counter_.emplace(bucket_size);
+
+  for (auto& [sink_id, support] : support_map_) {
+    DCHECK_EQ(sink_id, support->frame_sink_id());
+    frame_counter_->AddFrameSink(sink_id, support->frame_sink_type(),
+                                 support->is_root());
+  }
+}
+
+void FrameSinkManagerImpl::StopFrameCountingForTest(
+    StopFrameCountingForTestCallback callback) {
+  DCHECK(frame_counter_.has_value());
+  std::move(callback).Run(frame_counter_->TakeData());
+  frame_counter_.reset();
+}
+
 }  // namespace viz
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
index 631c2e6..666924d 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -26,6 +26,7 @@
 #include "components/viz/common/surfaces/frame_sink_bundle_id.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_impl.h"
+#include "components/viz/service/frame_sinks/frame_counter.h"
 #include "components/viz/service/frame_sinks/frame_sink_observer.h"
 #include "components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h"
 #include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
@@ -155,6 +156,9 @@
                 base::TimeDelta interval) override;
   void StartThrottlingAllFrameSinks(base::TimeDelta interval) override;
   void StopThrottlingAllFrameSinks() override;
+  void StartFrameCountingForTest(base::TimeDelta bucket_size) override;
+  void StopFrameCountingForTest(
+      StopFrameCountingForTestCallback callback) override;
 
   void DestroyFrameSinkBundle(const FrameSinkBundleId& id);
 
@@ -267,6 +271,10 @@
   std::unique_ptr<SurfaceAnimationManager> TakeSurfaceAnimationManager(
       NavigationID navigation_id);
 
+  FrameCounter* frame_counter() {
+    return frame_counter_ ? &frame_counter_.value() : nullptr;
+  }
+
  private:
   friend class FrameSinkManagerTest;
 
@@ -447,6 +455,9 @@
   mojo::Receiver<mojom::FrameSinkManager> receiver_{this};
 
   base::ObserverList<FrameSinkObserver>::Unchecked observer_list_;
+
+  // Counts frames for test.
+  absl::optional<FrameCounter> frame_counter_;
 };
 
 }  // namespace viz
diff --git a/components/viz/test/test_frame_sink_manager.h b/components/viz/test/test_frame_sink_manager.h
index e519e04..e4652ba 100644
--- a/components/viz/test/test_frame_sink_manager.h
+++ b/components/viz/test/test_frame_sink_manager.h
@@ -75,6 +75,9 @@
                 base::TimeDelta interval) override {}
   void StartThrottlingAllFrameSinks(base::TimeDelta interval) override {}
   void StopThrottlingAllFrameSinks() override {}
+  void StartFrameCountingForTest(base::TimeDelta bucket_size) override {}
+  void StopFrameCountingForTest(
+      StopFrameCountingForTestCallback callback) override {}
 
   mojo::Receiver<mojom::FrameSinkManager> receiver_{this};
   mojo::Remote<mojom::FrameSinkManagerClient> client_;
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc
index 01657d94e..d6029d7b 100644
--- a/components/webapps/browser/banners/app_banner_manager.cc
+++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -710,30 +710,11 @@
     return;
   }
 
-  // If the page gets stored in the back-forward cache we will not trigger the
-  // pipeline again when navigating back (DidFinishLoad will not trigger). So
-  // only allow the page to enter the cache if we know for sure that no
-  // installation is needed. Note: this check must happen before calling
-  // Terminate as it might set the installable_web_app_check_result_ to kNo.
-  if (!base::FeatureList::IsEnabled(
-          blink::features::kBackForwardCacheAppBanner)) {
-    if (installable_web_app_check_result_ !=
-            InstallableWebAppCheckResult::kNo &&
-        state_ != State::INACTIVE) {
-      content::BackForwardCache::DisableForRenderFrameHost(
-          handle->GetPreviousRenderFrameHostId(),
-          back_forward_cache::DisabledReason(
-              back_forward_cache::DisabledReasonId::kAppBannerManager));
-    }
-  }
-
   if (state_ != State::COMPLETE && state_ != State::INACTIVE)
     Terminate();
   ResetCurrentPageData();
 
-  if (base::FeatureList::IsEnabled(
-          blink::features::kBackForwardCacheAppBanner) &&
-      handle->IsServedFromBackForwardCache()) {
+  if (handle->IsServedFromBackForwardCache()) {
     UpdateState(State::INACTIVE);
     RequestAppBanner(validated_url_);
   }
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc
index b211aa75..64dc4dbc8 100644
--- a/components/webapps/browser/features.cc
+++ b/components/webapps/browser/features.cc
@@ -34,7 +34,7 @@
 // Enables PWA Unique IDs for WebAPKs.
 BASE_FEATURE(kWebApkUniqueId,
              "WebApkUniqueId",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif  // BUILDFLAG(IS_ANDROID)
 
 // When the user clicks "Create Shortcut" in the dot menu, the current page is
diff --git a/content/app/content_main.cc b/content/app/content_main.cc
index 58f891f..1ea06690 100644
--- a/content/app/content_main.cc
+++ b/content/app/content_main.cc
@@ -13,6 +13,7 @@
 #include "base/debug/activity_tracker.h"
 #include "base/debug/debugger.h"
 #include "base/debug/stack_trace.h"
+#include "base/feature_list.h"
 #include "base/i18n/icu_util.h"
 #include "base/logging.h"
 #include "base/message_loop/message_pump_type.h"
@@ -199,6 +200,7 @@
 int NO_STACK_PROTECTOR
 RunContentProcess(ContentMainParams params,
                   ContentMainRunner* content_main_runner) {
+  base::FeatureList::FailOnFeatureAccessWithoutFeatureList();
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // Lacros is launched with inherited priority. Revert to normal priority
   // before spawning more processes.
diff --git a/content/browser/aggregation_service/aggregation_service_impl.cc b/content/browser/aggregation_service/aggregation_service_impl.cc
index 93f0275..7a6410c5 100644
--- a/content/browser/aggregation_service/aggregation_service_impl.cc
+++ b/content/browser/aggregation_service/aggregation_service_impl.cc
@@ -17,11 +17,13 @@
 #include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
-#include "base/task/lazy_thread_pool_task_runner.h"
 #include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "base/task/updateable_sequenced_task_runner.h"
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
@@ -43,17 +45,16 @@
 
 namespace {
 
-// The shared task runner for all aggregation service storage operations. Note
-// that different AggregationServiceImpl instances perform operations on the
-// same task runner. This prevents any potential races when a given storage
-// context is destroyed and recreated using the same backing storage. This uses
-// BLOCK_SHUTDOWN as some data deletion operations may be running when the
-// browser is closed, and we want to ensure all data is deleted correctly.
-base::LazyThreadPoolSequencedTaskRunner g_storage_task_runner =
-    LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
-        base::TaskTraits(base::TaskPriority::BEST_EFFORT,
-                         base::MayBlock(),
-                         base::TaskShutdownBehavior::BLOCK_SHUTDOWN));
+scoped_refptr<base::UpdateableSequencedTaskRunner> CreateStorageTaskRunner() {
+  // This uses BLOCK_SHUTDOWN as some data deletion operations may be running
+  // when the browser is closed, and we want to ensure all data is deleted
+  // correctly. Additionally, we use MUST_USE_FOREGROUND to avoid priority
+  // inversions if a task is already running when the priority is increased.
+  return base::ThreadPool::CreateUpdateableSequencedTaskRunner(
+      base::TaskTraits(base::TaskPriority::BEST_EFFORT, base::MayBlock(),
+                       base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
+                       base::ThreadPolicy::MUST_USE_FOREGROUND));
+}
 
 }  // namespace
 
@@ -61,13 +62,14 @@
     bool run_in_memory,
     const base::FilePath& user_data_directory,
     StoragePartitionImpl* storage_partition)
-    : storage_(
+    : storage_task_runner_(CreateStorageTaskRunner()),
+      storage_(
           // Ensure storage is constructed first (and destroyed last) so we can
           // safely pass `this` as an `AggregationServiceStorageContext` in the
           // below constructors.
           // TODO(alexmt): Pass the storage directly to avoid an extra wrapper.
           base::SequenceBound<AggregationServiceStorageSql>(
-              g_storage_task_runner.Get(),
+              storage_task_runner_,
               run_in_memory,
               user_data_directory,
               base::DefaultClock::GetInstance())),
@@ -105,8 +107,9 @@
     std::unique_ptr<AggregatableReportScheduler> scheduler,
     std::unique_ptr<AggregatableReportAssembler> assembler,
     std::unique_ptr<AggregatableReportSender> sender)
-    : storage_(base::SequenceBound<AggregationServiceStorageSql>(
-          g_storage_task_runner.Get(),
+    : storage_task_runner_(CreateStorageTaskRunner()),
+      storage_(base::SequenceBound<AggregationServiceStorageSql>(
+          storage_task_runner_,
           run_in_memory,
           user_data_directory,
           clock)),
@@ -142,18 +145,26 @@
     base::Time delete_end,
     StoragePartition::StorageKeyMatcherFunction filter,
     base::OnceClosure done) {
+  // When a clear data task is queued or running, we use a higher priority.
+  ++num_pending_clear_data_tasks_;
+  storage_task_runner_->UpdatePriority(base::TaskPriority::USER_VISIBLE);
+
   storage_.AsyncCall(&AggregationServiceStorage::ClearDataBetween)
       .WithArgs(delete_begin, delete_end, std::move(filter),
                 base::ElapsedTimer())
-      .Then(base::BindOnce(
-          [](base::OnceClosure done,
-             base::WeakPtr<AggregationServiceImpl> aggregation_service) {
-            std::move(done).Run();
+      .Then(std::move(done).Then(
+          base::BindOnce(&AggregationServiceImpl::OnClearDataComplete,
+                         weak_factory_.GetWeakPtr())));
+}
 
-            if (aggregation_service)
-              aggregation_service->NotifyRequestStorageModified();
-          },
-          std::move(done), weak_factory_.GetWeakPtr()));
+void AggregationServiceImpl::OnClearDataComplete() {
+  DCHECK_GT(num_pending_clear_data_tasks_, 0);
+  --num_pending_clear_data_tasks_;
+
+  // No more clear data tasks, so we can reset the priority.
+  if (num_pending_clear_data_tasks_ == 0)
+    storage_task_runner_->UpdatePriority(base::TaskPriority::BEST_EFFORT);
+  NotifyRequestStorageModified();
 }
 
 void AggregationServiceImpl::ScheduleReport(
diff --git a/content/browser/aggregation_service/aggregation_service_impl.h b/content/browser/aggregation_service/aggregation_service_impl.h
index e0984d4..f91cafa 100644
--- a/content/browser/aggregation_service/aggregation_service_impl.h
+++ b/content/browser/aggregation_service/aggregation_service_impl.h
@@ -12,6 +12,7 @@
 
 #include "base/callback_forward.h"
 #include "base/containers/flat_map.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/threading/sequence_bound.h"
@@ -31,6 +32,7 @@
 namespace base {
 class Clock;
 class FilePath;
+class UpdateableSequencedTaskRunner;
 }  // namespace base
 
 namespace content {
@@ -135,6 +137,7 @@
       absl::optional<AggregationServiceStorage::RequestId> request_id,
       AggregatableReport report,
       AggregatableReportSender::RequestStatus status);
+  void OnClearDataComplete();
 
   void OnGetRequestsToSendFromWebUI(
       base::OnceClosure reports_sent_callback,
@@ -148,6 +151,15 @@
 
   void NotifyRequestStorageModified();
 
+  // The task runner for all aggregation service storage operations. Updateable
+  // to allow for priority to be temporarily increased to `USER_VISIBLE` when a
+  // clear data task is queued or running. Otherwise `BEST_EFFORT` is used.
+  scoped_refptr<base::UpdateableSequencedTaskRunner> storage_task_runner_;
+
+  // How many clear data storage tasks are queued or running currently, i.e.
+  // have been posted but the reply has not been run.
+  int num_pending_clear_data_tasks_ = 0;
+
   base::SequenceBound<AggregationServiceStorage> storage_;
   std::unique_ptr<AggregatableReportScheduler> scheduler_;
   std::unique_ptr<AggregatableReportAssembler> assembler_;
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc
index 76eda9b1a..d18bdbd 100644
--- a/content/browser/back_forward_cache_features_browsertest.cc
+++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -2028,116 +2028,6 @@
       {}, FROM_HERE);
 }
 
-class MockAppBannerService : public blink::mojom::AppBannerService {
- public:
-  MockAppBannerService() = default;
-
-  MockAppBannerService(const MockAppBannerService&) = delete;
-  MockAppBannerService& operator=(const MockAppBannerService&) = delete;
-
-  ~MockAppBannerService() override = default;
-
-  void Bind(mojo::ScopedMessagePipeHandle handle) {
-    receiver_.Bind(mojo::PendingReceiver<blink::mojom::AppBannerService>(
-        std::move(handle)));
-  }
-
-  mojo::Remote<blink::mojom::AppBannerController>& controller() {
-    return controller_;
-  }
-
-  void OnBannerPromptRequested(base::OnceClosure closure, bool) {
-    std::move(closure).Run();
-  }
-
-  void SendBannerPromptRequest() {
-    blink::mojom::AppBannerController* controller_ptr = controller_.get();
-    base::RunLoop run_loop;
-    base::OnceClosure quit_closure = run_loop.QuitClosure();
-    base::OnceCallback<void(bool)> callback =
-        base::BindOnce(&MockAppBannerService::OnBannerPromptRequested,
-                       base::Unretained(this), std::move(quit_closure));
-    controller_ptr->BannerPromptRequest(
-        receiver_.BindNewPipeAndPassRemote(),
-        event_.BindNewPipeAndPassReceiver(), {"web"},
-        base::BindOnce(&MockAppBannerService::OnBannerPromptReply,
-                       base::Unretained(this), std::move(callback)));
-    run_loop.Run();
-  }
-
-  void OnBannerPromptReply(base::OnceCallback<void(bool)> callback,
-                           blink::mojom::AppBannerPromptReply reply) {
-    std::move(callback).Run(reply ==
-                            blink::mojom::AppBannerPromptReply::CANCEL);
-  }
-
-  // blink::mojom::AppBannerService:
-  void DisplayAppBanner() override {}
-
- private:
-  mojo::Receiver<blink::mojom::AppBannerService> receiver_{this};
-  mojo::Remote<blink::mojom::AppBannerEvent> event_;
-  mojo::Remote<blink::mojom::AppBannerController> controller_;
-};
-
-// The parameter to this test class is whether or not App Banner is supported
-// for BFCache.
-class AppBannerBackForwardCacheBrowserTest
-    : public BackForwardCacheBrowserTest,
-      public ::testing::WithParamInterface<bool> {
- public:
-  AppBannerBackForwardCacheBrowserTest() {
-    const base::Feature& feature = blink::features::kBackForwardCacheAppBanner;
-    if (ShouldEnabledAppBannerCaching()) {
-      EnableFeatureAndSetParams(feature, "", "");
-    } else {
-      DisableFeature(feature);
-    }
-  }
-
- protected:
-  bool ShouldEnabledAppBannerCaching() { return GetParam(); }
-};
-
-IN_PROC_BROWSER_TEST_P(AppBannerBackForwardCacheBrowserTest,
-                       TestAppBannerCaching) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-
-  // 1) Navigate to A and request a PWA app banner.
-  EXPECT_TRUE(NavigateToURL(
-      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
-
-  // Connect the MockAppBannerService mojom to the renderer's frame.
-  MockAppBannerService mock_app_banner_service;
-  web_contents()->GetPrimaryMainFrame()->GetRemoteInterfaces()->GetInterface(
-      mock_app_banner_service.controller().BindNewPipeAndPassReceiver());
-  // Send the request to the renderer's frame, wait until the request completes.
-  mock_app_banner_service.SendBannerPromptRequest();
-
-  // 2) Navigate away. Page A requested a PWA app banner, and thus not cached.
-  RenderFrameHostWrapper rfh_a(current_frame_host());
-  EXPECT_TRUE(NavigateToURL(
-      shell(), embedded_test_server()->GetURL("b.com", "/title1.html")));
-  if (!ShouldEnabledAppBannerCaching()) {
-    ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());
-  }
-
-  // 3) Go back to A.
-  ASSERT_TRUE(HistoryGoBack(web_contents()));
-  if (ShouldEnabledAppBannerCaching()) {
-    ExpectRestored(FROM_HERE);
-  } else {
-    ExpectNotRestored(
-        {NotRestoredReason::kBlocklistedFeatures},
-        {blink::scheduler::WebSchedulerTrackedFeature::kAppBanner}, {}, {}, {},
-        FROM_HERE);
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         AppBannerBackForwardCacheBrowserTest,
-                         testing::Bool());
-
 // TODO(crbug.com/1317431): WebSQL does not work on Fuchsia.
 #if BUILDFLAG(IS_FUCHSIA)
 #define MAYBE_DoesNotCacheIfWebDatabase DISABLED_DoesNotCacheIfWebDatabase
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 04bcdb98..f3f91ffb 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -2008,17 +2008,19 @@
   ASSERT_TRUE(target_infos);
   EXPECT_EQ(1u, target_infos->size());
   const base::Value& target_info_value = target_infos->front();
-  EXPECT_TRUE(target_info_value.is_dict());
-  const base::DictionaryValue& target_info =
-      base::Value::AsDictionaryValue(target_info_value);
-  std::string target_id, type, title, url;
-  EXPECT_TRUE(target_info.GetString("targetId", &target_id));
-  EXPECT_TRUE(target_info.GetString("type", &type));
-  EXPECT_TRUE(target_info.GetString("title", &title));
-  EXPECT_TRUE(target_info.GetString("url", &url));
-  EXPECT_EQ("page", type);
-  EXPECT_EQ("about:blank", title);
-  EXPECT_EQ("about:blank", url);
+  const base::Value::Dict* target_info = target_info_value.GetIfDict();
+  ASSERT_TRUE(target_info);
+  const std::string* target_id = target_info->FindString("target_id");
+  const std::string* type = target_info->FindString("type");
+  const std::string* title = target_info->FindString("title");
+  const std::string* url = target_info->FindString("url");
+  EXPECT_FALSE(target_id);
+  ASSERT_TRUE(type);
+  ASSERT_TRUE(title);
+  ASSERT_TRUE(url);
+  EXPECT_EQ("page", *type);
+  EXPECT_EQ("about:blank", *title);
+  EXPECT_EQ("about:blank", *url);
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, VirtualTimeTest) {
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index b367aff..58bc514 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1655,8 +1655,6 @@
     case WebSchedulerTrackedFeature::kOutstandingNetworkRequestXHR:
       return Page::BackForwardCacheNotRestoredReasonEnum::
           OutstandingNetworkRequestXHR;
-    case WebSchedulerTrackedFeature::kAppBanner:
-      return Page::BackForwardCacheNotRestoredReasonEnum::AppBanner;
     case WebSchedulerTrackedFeature::kPrinting:
       return Page::BackForwardCacheNotRestoredReasonEnum::Printing;
     case WebSchedulerTrackedFeature::kWebDatabase:
@@ -1752,9 +1750,6 @@
         case back_forward_cache::DisabledReasonId::kSafeBrowsingThreatDetails:
           return Page::BackForwardCacheNotRestoredReasonEnum::
               EmbedderSafeBrowsingThreatDetails;
-        case back_forward_cache::DisabledReasonId::kAppBannerManager:
-          return Page::BackForwardCacheNotRestoredReasonEnum::
-              EmbedderAppBannerManager;
         case back_forward_cache::DisabledReasonId::kDomDistillerViewerSource:
           return Page::BackForwardCacheNotRestoredReasonEnum::
               EmbedderDomDistillerViewerSource;
@@ -1892,7 +1887,6 @@
     case WebSchedulerTrackedFeature::kPrinting:
     case WebSchedulerTrackedFeature::kPictureInPicture:
     case WebSchedulerTrackedFeature::kWebLocks:
-    case WebSchedulerTrackedFeature::kAppBanner:
     case WebSchedulerTrackedFeature::kWebSocket:
     case WebSchedulerTrackedFeature::kDedicatedWorkerOrWorklet:
     case WebSchedulerTrackedFeature::kSpeechSynthesis:
diff --git a/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc b/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
index eefb7f2..3107bf3 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
@@ -40,28 +40,15 @@
   }
 
   std::vector<net::SchemefulSite> result;
-  old_sets.ForEachPublicSetEntry(
-      [&](const net::SchemefulSite& old_member,
-          const net::FirstPartySetEntry& old_entry) -> bool {
-        if (!old_config.Contains(old_member)) {
-          absl::optional<net::FirstPartySetEntry> current_entry =
-              current_sets.FindEntry(old_member, current_config);
-          // Look for the removed sites and the ones have owner changed.
-          if (!current_entry.has_value() ||
-              current_entry.value().primary() != old_entry.primary()) {
-            result.push_back(old_member);
-          }
-        }
-        return true;
-      });
 
-  old_config.ForEachCustomizationEntry(
-      [&](const net::SchemefulSite& old_member,
-          const absl::optional<net::FirstPartySetEntry>& old_entry) -> bool {
-        const absl::optional<net::FirstPartySetEntry> current_entry =
+  old_sets.ForEachEffectiveSetEntry(
+      old_config, [&](const net::SchemefulSite& old_member,
+                      const net::FirstPartySetEntry& old_entry) {
+        absl::optional<net::FirstPartySetEntry> current_entry =
             current_sets.FindEntry(old_member, current_config);
-        // Look for the ones have owner changed.
-        if (old_entry.has_value() && current_entry != old_entry) {
+        // Look for the removed sites and the ones whose primary has changed.
+        if (!current_entry.has_value() ||
+            current_entry.value().primary() != old_entry.primary()) {
           result.push_back(old_member);
         }
         return true;
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
index b978e78..bda34e17 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
@@ -315,7 +315,50 @@
 }
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest,
-       ClearSiteDataOnChangedSetsForContext_Successful) {
+       ClearSiteDataOnChangedSetsForContext_ManualSet_Successful) {
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(
+      features::kFirstPartySets,
+      {{features::kFirstPartySetsClearSiteDataOnChangedSets.name, "true"}});
+
+  net::SchemefulSite foo(GURL("https://foo.test"));
+  net::SchemefulSite associated(GURL("https://associatedsite.test"));
+  net::SchemefulSite associated2(GURL("https://associatedsite2.test"));
+
+  const std::string browser_context_id = "profile";
+
+  base::HistogramTester histogram;
+  FirstPartySetsHandlerImpl handler =
+      FirstPartySetsHandlerImpl::CreateForTesting(true, false);
+  const std::string input =
+      R"({"primary": "https://foo.test", )"
+      R"("associatedSites": ["https://associatedsite.test"]})";
+  ASSERT_TRUE(base::JSONReader::Read(input));
+
+  handler.Init(scoped_dir_.GetPath(), LocalSetDeclaration(input));
+
+  // Should not yet be recorded.
+  histogram.ExpectTotalCount(kFirstPartySetsClearSiteDataOutcomeHistogram, 0);
+  ClearSiteDataOnChangedSetsForContextAndWait(
+      handler, context(), browser_context_id,
+      net::FirstPartySetsContextConfig());
+
+  EXPECT_THAT(
+      GetPersistedGlobalSetsAndWait(handler, browser_context_id)
+          ->FindEntries({foo, associated}, net::FirstPartySetsContextConfig()),
+      UnorderedElementsAre(
+          Pair(foo, net::FirstPartySetEntry(foo, net::SiteType::kPrimary,
+                                            absl::nullopt)),
+          Pair(associated,
+               net::FirstPartySetEntry(foo, net::SiteType::kAssociated,
+                                       absl::nullopt))));
+  histogram.ExpectUniqueSample(
+      kFirstPartySetsClearSiteDataOutcomeHistogram,
+      FirstPartySetsHandlerImpl::ClearSiteDataOutcomeType::kSuccess, 1);
+}
+
+TEST_F(FirstPartySetsHandlerImplEnabledTest,
+       ClearSiteDataOnChangedSetsForContext_PublicSetsWithDiff_Successful) {
   base::test::ScopedFeatureList features;
   features.InitAndEnableFeatureWithParameters(
       features::kFirstPartySets,
diff --git a/content/browser/preloading/prefetch/prefetch_features.cc b/content/browser/preloading/prefetch/prefetch_features.cc
index ed9a72cd..4ac0c29 100644
--- a/content/browser/preloading/prefetch/prefetch_features.cc
+++ b/content/browser/preloading/prefetch/prefetch_features.cc
@@ -9,8 +9,5 @@
 BASE_FEATURE(kPrefetchUseContentRefactor,
              "PrefetchUseContentRefactor",
              base::FEATURE_DISABLED_BY_DEFAULT);
-BASE_FEATURE(kPrefetchNoVarySearch,
-             "PrefetchNoVarySearch",
-             base::FEATURE_DISABLED_BY_DEFAULT);
 
 }  // namespace content::features
diff --git a/content/browser/preloading/prefetch/prefetch_features.h b/content/browser/preloading/prefetch/prefetch_features.h
index 9543c0f..8de5f9c 100644
--- a/content/browser/preloading/prefetch/prefetch_features.h
+++ b/content/browser/preloading/prefetch/prefetch_features.h
@@ -15,11 +15,6 @@
 // chrome/browser/preloadingprefetch/prefetch_proxy/.
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrefetchUseContentRefactor);
 
-// If enabled, then navigation requests should check the match responses in the
-// prefetch cache by using the No-Vary-Search rules if No-Vary-Search header
-// is specified in prefetched responses.
-CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrefetchNoVarySearch);
-
 }  // namespace content::features
 
 #endif  // CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_FEATURES_H_
diff --git a/content/browser/preloading/prefetch/prefetch_service.cc b/content/browser/preloading/prefetch/prefetch_service.cc
index 15361d4..0e25a81 100644
--- a/content/browser/preloading/prefetch/prefetch_service.cc
+++ b/content/browser/preloading/prefetch/prefetch_service.cc
@@ -963,6 +963,8 @@
     return;
   }
 
+  head->was_in_prefetch_cache = true;
+
   prefetch_container->TakePrefetchedResponse(
       std::make_unique<PrefetchedMainframeResponseContainer>(
           isolation_info, std::move(head), std::move(body)));
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
index a5bc8e7c..766dd34 100644
--- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -12,6 +12,7 @@
 #include "content/browser/preloading/prefetch/prefetch_features.h"
 #include "content/browser/preloading/prefetch/prefetch_params.h"
 #include "content/browser/preloading/prefetch/prefetch_status.h"
+#include "content/browser/preloading/prefetch/prefetched_mainframe_response_container.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/frame_accept_header.h"
 #include "content/public/browser/prefetch_service_delegate.h"
@@ -483,6 +484,9 @@
             PrefetchStatus::kPrefetchSuccessful);
   EXPECT_TRUE(serveable_prefetch_container->HasValidPrefetchedResponse(
       base::TimeDelta::Max()));
+  EXPECT_TRUE(serveable_prefetch_container->ReleasePrefetchedResponse()
+                  ->ReleaseHead()
+                  ->was_in_prefetch_cache);
 }
 
 TEST_F(PrefetchServiceTest, NoPrefetchingPreloadingDisabled) {
diff --git a/content/browser/private_aggregation/private_aggregation_budgeter.cc b/content/browser/private_aggregation/private_aggregation_budgeter.cc
index 982e8c43..6ade459 100644
--- a/content/browser/private_aggregation/private_aggregation_budgeter.cc
+++ b/content/browser/private_aggregation/private_aggregation_budgeter.cc
@@ -339,9 +339,6 @@
       break;
   }
 
-  // TODO(alexmt): Delay `done` being run until after the database task is
-  // complete.
-
   // Treat null times as unbounded lower or upper range. This is used by
   // browsing data remover.
   if (delete_begin.is_null())
@@ -354,7 +351,9 @@
 
   if (is_all_time_covered && filter.is_null()) {
     storage_->budgets_data()->DeleteAllData();
-    std::move(done).Run();
+
+    // Runs `done` once flushing is complete.
+    storage_->budgets_data()->FlushDataToDisk(std::move(done));
     return;
   }
 
@@ -370,7 +369,9 @@
 
   if (is_all_time_covered) {
     storage_->budgets_data()->DeleteData(origins_to_delete);
-    std::move(done).Run();
+
+    // Runs `done` once flushing is complete.
+    storage_->budgets_data()->FlushDataToDisk(std::move(done));
     return;
   }
 
@@ -406,11 +407,10 @@
     storage_->budgets_data()->UpdateData(origin_key, budgets);
   }
 
-  // A no-op call to force the database to be flushed immediately instead of
-  // waiting up to `PrivateAggregationBudgetStorage::kFlushDelay`.
-  storage_->budgets_data()->DeleteData({});
-
-  std::move(done).Run();
+  // Force the database to be flushed immediately instead of waiting up to
+  // `PrivateAggregationBudgetStorage::kFlushDelay`. Runs the `done` callback
+  // once flushing is complete.
+  storage_->budgets_data()->FlushDataToDisk(std::move(done));
 }
 
 }  // namespace content
diff --git a/content/browser/private_aggregation/private_aggregation_budgeter_unittest.cc b/content/browser/private_aggregation/private_aggregation_budgeter_unittest.cc
index 99b488a..ddc5c4e 100644
--- a/content/browser/private_aggregation/private_aggregation_budgeter_unittest.cc
+++ b/content/browser/private_aggregation/private_aggregation_budgeter_unittest.cc
@@ -772,7 +772,7 @@
        MaxPendingCallsExceeded_AdditionalDataClearingCallsAllowed) {
   base::RunLoop run_loop;
   CreateBudgeter(/*exclusively_run_in_memory=*/false,
-                 /*on_done_initializing=*/run_loop.QuitClosure());
+                 /*on_done_initializing=*/base::DoNothing());
 
   PrivateAggregationBudgetKey example_key =
       PrivateAggregationBudgetKey::CreateForTesting(
@@ -800,10 +800,12 @@
   // Despite the limit being reached, data clearing requests are allowed to
   // cause the limit to be exceeded and are queued.
   bool was_callback_run = false;
-  budgeter()->ClearData(
-      base::Time::Min(), base::Time::Max(),
-      StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { was_callback_run = true; }));
+  budgeter()->ClearData(base::Time::Min(), base::Time::Max(),
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          was_callback_run = true;
+                          run_loop.Quit();
+                        }));
   EXPECT_FALSE(was_callback_run);
 
   run_loop.Run();
@@ -861,11 +863,15 @@
             ++num_queries_processed;
           }));
 
-  budgeter()->ClearData(
-      kExampleTime, kExampleTime, StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
-
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
   base::RunLoop run_loop;
+  budgeter()->ClearData(kExampleTime, kExampleTime,
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can use the full budget again
   budgeter()->ConsumeBudget(
@@ -873,7 +879,6 @@
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 4);
@@ -924,13 +929,18 @@
             ++num_queries_processed;
           }));
 
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
+  base::RunLoop run_loop;
+
   budgeter()->ClearData(
       kExampleTime,
       kExampleTime + PrivateAggregationBudgetKey::TimeWindow::kDuration,
       StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
-
-  base::RunLoop run_loop;
+      base::BindLambdaForTesting([&]() {
+        ++num_queries_processed;
+        run_loop.Quit();
+      }));
 
   // After clearing, we can use the full budget again.
   budgeter()->ConsumeBudget(
@@ -938,7 +948,6 @@
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 5);
@@ -999,10 +1008,17 @@
             ++num_queries_processed;
           }));
 
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
+  base::RunLoop run_loop;
+
   // This will only clear the `key_to_clear`'s budget.
-  budgeter()->ClearData(
-      kExampleTime, kExampleTime, StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
+  budgeter()->ClearData(kExampleTime, kExampleTime,
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can have a budget of exactly
   // (`PrivateAggregationBudgeter::kMaxBudgetPerScope` - 2) that we can use.
@@ -1010,13 +1026,11 @@
       /*budget=*/(PrivateAggregationBudgeter::kMaxBudgetPerScope - 2),
       key_after, expect_approved);
 
-  base::RunLoop run_loop;
   budgeter()->ConsumeBudget(
       /*budget=*/1, key_after,
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kInsufficientBudget);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 7);
@@ -1066,21 +1080,26 @@
   budgeter()->ConsumeBudget(
       /*budget=*/1, shared_storage_key, expect_insufficient_budget);
 
-  budgeter()->ClearData(
-      kExampleTime, kExampleTime, StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
+  base::RunLoop run_loop;
+  budgeter()->ClearData(kExampleTime, kExampleTime,
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can use the full budget again
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope, fledge_key,
       expect_approved);
-  base::RunLoop run_loop;
+
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope,
       shared_storage_key, base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 7);
@@ -1113,12 +1132,15 @@
             ++num_queries_processed;
           }));
 
-  budgeter()->ClearData(
-      base::Time::Min(), base::Time::Max(),
-      StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
-
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
   base::RunLoop run_loop;
+  budgeter()->ClearData(base::Time::Min(), base::Time::Max(),
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can use the full budget again
   budgeter()->ConsumeBudget(
@@ -1126,7 +1148,6 @@
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 4);
@@ -1159,11 +1180,15 @@
             ++num_queries_processed;
           }));
 
-  budgeter()->ClearData(
-      base::Time(), base::Time(), StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
-
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
   base::RunLoop run_loop;
+  budgeter()->ClearData(base::Time(), base::Time(),
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can use the full budget again
   budgeter()->ConsumeBudget(
@@ -1171,7 +1196,6 @@
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 4);
@@ -1204,12 +1228,15 @@
             ++num_queries_processed;
           }));
 
-  budgeter()->ClearData(
-      base::Time(), base::Time::Max(),
-      StoragePartition::StorageKeyMatcherFunction(),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
-
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
   base::RunLoop run_loop;
+  budgeter()->ClearData(base::Time(), base::Time::Max(),
+                        StoragePartition::StorageKeyMatcherFunction(),
+                        base::BindLambdaForTesting([&]() {
+                          ++num_queries_processed;
+                          run_loop.Quit();
+                        }));
 
   // After clearing, we can use the full budget again
   budgeter()->ConsumeBudget(
@@ -1217,7 +1244,6 @@
       base::BindLambdaForTesting([&](RequestResult result) {
         EXPECT_EQ(result, RequestResult::kApproved);
         ++num_queries_processed;
-        run_loop.Quit();
       }));
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 4);
@@ -1268,25 +1294,26 @@
   budgeter()->ConsumeBudget(
       /*budget=*/1, example_key_b, expect_insufficient_budget);
 
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
+  base::RunLoop run_loop;
   budgeter()->ClearData(
       kExampleTime, kExampleTime,
       base::BindLambdaForTesting([&](const blink::StorageKey& storage_key) {
         return storage_key == blink::StorageKey(kOriginA);
       }),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
+      base::BindLambdaForTesting([&]() {
+        ++num_queries_processed;
+        run_loop.Quit();
+      }));
 
   // After clearing, we can use the full budget again for the cleared origin.
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope, example_key_a,
       expect_approved);
-  base::RunLoop run_loop;
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope, example_key_b,
-      base::BindLambdaForTesting([&](RequestResult result) {
-        EXPECT_EQ(result, RequestResult::kInsufficientBudget);
-        ++num_queries_processed;
-        run_loop.Quit();
-      }));
+      expect_insufficient_budget);
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 7);
 }
@@ -1336,25 +1363,27 @@
   budgeter()->ConsumeBudget(
       /*budget=*/1, example_key_b, expect_insufficient_budget);
 
+  // `ClearData()` runs its callback after a round trip in the db task runner,
+  // so its callback is invoked last.
+  base::RunLoop run_loop;
   budgeter()->ClearData(
       base::Time::Min(), base::Time::Max(),
       base::BindLambdaForTesting([&](const blink::StorageKey& storage_key) {
         return storage_key == blink::StorageKey(kOriginA);
       }),
-      base::BindLambdaForTesting([&]() { ++num_queries_processed; }));
+      base::BindLambdaForTesting([&]() {
+        ++num_queries_processed;
+        run_loop.Quit();
+      }));
 
   // After clearing, we can use the full budget again for the cleared origin.
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope, example_key_a,
       expect_approved);
-  base::RunLoop run_loop;
+
   budgeter()->ConsumeBudget(
       /*budget=*/PrivateAggregationBudgeter::kMaxBudgetPerScope, example_key_b,
-      base::BindLambdaForTesting([&](RequestResult result) {
-        EXPECT_EQ(result, RequestResult::kInsufficientBudget);
-        ++num_queries_processed;
-        run_loop.Quit();
-      }));
+      expect_insufficient_budget);
   run_loop.Run();
   EXPECT_EQ(num_queries_processed, 7);
 }
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index 5560e5c..7ebd34dd 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -157,7 +157,6 @@
 // when actually the blocking is flag controlled and they are not registered
 // as being used if we don't want them to block.
 constexpr WebSchedulerTrackedFeatures kDisallowedFeatures(
-    WebSchedulerTrackedFeature::kAppBanner,
     WebSchedulerTrackedFeature::kBroadcastChannel,
     WebSchedulerTrackedFeature::kContainsPlugins,
     WebSchedulerTrackedFeature::kDedicatedWorkerOrWorklet,
diff --git a/content/browser/renderer_host/back_forward_cache_metrics_unittest.cc b/content/browser/renderer_host/back_forward_cache_metrics_unittest.cc
index 33c74f8..1d16c9b 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics_unittest.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics_unittest.cc
@@ -242,6 +242,7 @@
       /* WebSchedulerTrackedFeature::kWebVR =*/30,
       /* WebSchedulerTrackedFeature::kWakeLock =*/35,
       /* WebSchedulerTrackedFeature::kWebFileSystem =*/39,
+      /* WebSchedulerTrackedFeature::kAppBanner =*/42,
       /* WebSchedulerTrackedFeature::kMediaSessionImplOnServiceCreated =*/56};
 
   // Combine the result of |GetDisallowedFeatures()| and |GetAllowedFeatures()|.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index e10f7234..a8d889b 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -809,6 +809,19 @@
   kReplaceCurrentItem,
 };
 
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+// Used to log whether the call to SSLManager::DidStartResourceResponse()
+// resulted in a no-op or if the exceptions were cleared out when a good
+// certificate was seen. Matches histogram enum (SSLSubresourceResponseType).
+enum class SSLSubresourceResponseType {
+  // Includes cases when call resulted in a no-op.
+  kIgnored = 0,
+  // Includes cases when exceptions were cleared after seeing a good cert.
+  kProcessed = 1,
+  kMaxValue = kProcessed,
+};
+
 bool ValidateCSPAttribute(const std::string& value) {
   static const size_t kMaxLengthCSPAttribute = 4096;
   if (!base::IsStringASCII(value))
@@ -7876,10 +7889,14 @@
   OPTIONAL_TRACE_EVENT1("content",
                         "RenderFrameHostImpl::SubresourceResponseStarted",
                         "url", final_response_url.GetURL());
-  frame_tree_->controller().ssl_manager()->DidStartResourceResponse(
-      final_response_url, cert_status);
+  bool was_processed =
+      frame_tree_->controller().ssl_manager()->DidStartResourceResponse(
+          final_response_url, cert_status);
+  UMA_HISTOGRAM_ENUMERATION("SSL.Experimental.SubresourceResponse",
+                            was_processed
+                                ? SSLSubresourceResponseType::kProcessed
+                                : SSLSubresourceResponseType::kIgnored);
 }
-
 void RenderFrameHostImpl::ResourceLoadComplete(
     blink::mojom::ResourceLoadInfoPtr resource_load_info) {
   GlobalRequestID global_request_id;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index edeebb8..4d9ebcaa 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3107,17 +3107,12 @@
   GetRendererInterface()->SetIsCrossOriginIsolated(
       process_lock.GetWebExposedIsolationInfo().is_isolated());
 
-  bool isolated_apps_developer_mode_allowed =
-      GetContentClient()->browser()->IsIsolatedWebAppsDeveloperModeAllowed(
-          GetBrowserContext());
-
   bool is_isolated_context_allowed_by_embedder =
       GetContentClient()->browser()->IsIsolatedContextAllowedForUrl(
           GetBrowserContext(), process_lock.lock_url());
 
   GetRendererInterface()->SetIsIsolatedContext(
-      (isolated_apps_developer_mode_allowed &&
-       process_lock.GetWebExposedIsolationInfo().is_isolated_application()) ||
+      process_lock.GetWebExposedIsolationInfo().is_isolated_application() ||
       is_isolated_context_allowed_by_embedder);
 
   if (!process_lock.IsASiteOrOrigin())
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 3f20c20..cc32d194 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -5506,8 +5506,7 @@
 // the main frame (given that the child did not consume the wheel).
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || \
     BUILDFLAG(IS_FUCHSIA)
-// Flaky on Windows: https://crbug.com/947193
-// Flaky on Fuchsia: crbug.com/1382621
+// TODO(crbug.com/947193): Flaky on multiple platforms.
 #define MAYBE_TouchpadPinchOverOOPIF DISABLED_TouchpadPinchOverOOPIF
 #else
 #define MAYBE_TouchpadPinchOverOOPIF TouchpadPinchOverOOPIF
@@ -5618,8 +5617,7 @@
 // synthetic wheel event to the child.
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
     BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
-// Flaky on mac, linux and win. crbug.com/947193
-// Flaky on Fuchsia: crbug.com/138262
+// TODO(crbug.com/947193): Flaky on multiple platforms.
 #define MAYBE_TouchpadDoubleTapZoomOverOOPIF \
   DISABLED_TouchpadDoubleTapZoomOverOOPIF
 #else
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index f712630..ac365cf 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -15,6 +15,7 @@
 #include "base/trace_event/optional_trace_event.h"
 #include "content/browser/devtools/devtools_instrumentation.h"
 #include "content/browser/navigation_or_document_handle.h"
+#include "content/browser/navigation_subresource_loader_params.h"
 #include "content/browser/renderer_host/navigation_entry_impl.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/ssl/ssl_error_handler.h"
@@ -363,22 +364,22 @@
   OnCertErrorInternal(std::move(handler));
 }
 
-void SSLManager::DidStartResourceResponse(
+bool SSLManager::DidStartResourceResponse(
     const url::SchemeHostPort& final_response_url,
     bool has_certificate_errors) {
   const std::string& scheme = final_response_url.scheme();
   const std::string& host = final_response_url.host();
 
-  if (!GURL::SchemeIsCryptographic(scheme) || has_certificate_errors)
-    return;
-
+  if (!GURL::SchemeIsCryptographic(scheme) || has_certificate_errors) {
+    return false;
+  }
   // If the scheme is https: or wss and the cert did not have any errors, revoke
   // any previous decisions that have occurred.
   if (!ssl_host_state_delegate_ ||
       !ssl_host_state_delegate_->HasAllowException(
           host,
           controller_->frame_tree().GetMainFrame()->GetStoragePartition())) {
-    return;
+    return false;
   }
 
   // If there's no certificate error, a good certificate has been seen, so
@@ -386,6 +387,7 @@
   // certificates. This intentionally does not apply to cached resources
   // (see https://crbug.com/634553 for an explanation).
   ssl_host_state_delegate_->RevokeUserAllowExceptions(host);
+  return true;
 }
 
 void SSLManager::OnCertErrorInternal(std::unique_ptr<SSLErrorHandler> handler) {
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 092340b3..61ec340 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -68,7 +68,13 @@
   NavigationControllerImpl* controller() { return controller_; }
 
   void DidCommitProvisionalLoad(const LoadCommittedDetails& details);
-  void DidStartResourceResponse(const url::SchemeHostPort& final_response_url,
+
+  // TODO(crbug.com/1385424): Revert function DidStartResourceResponse to return
+  // void after expiry of histogram SSL.Experimental.SubresourceResponse.
+  // Return true when a good certificate is seen and any exceptions that were
+  // made by the user for bad certificates are cleared out, returns false
+  // otherwise without processing anything.
+  bool DidStartResourceResponse(const url::SchemeHostPort& final_response_url,
                                 bool has_certificate_errors);
 
   // The following methods are called when a page includes insecure
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 1dad5d4..bdc6a64a 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -2642,7 +2642,11 @@
       (remove_mask_ & REMOVE_DATA_MASK_PRIVATE_AGGREGATION_INTERNAL)) {
     private_aggregation_manager->ClearBudgetData(
         begin, end, generic_filter,
-        CreateTaskCompletionClosure(TracingDataType::kPrivateAggregation));
+
+        // Wrapping the callback ensures that the callback is still run in the
+        // case that the storage partition is deleted before the task is posted.
+        mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+            CreateTaskCompletionClosure(TracingDataType::kPrivateAggregation)));
   }
 
   // TODO(crbug.com/1340250): The Plugin Private File System is removed, but
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index 3679660..892b54c 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -561,8 +561,11 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 void TracingControllerImpl::OnMachineStatisticsLoaded() {
-  chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic(
-      chromeos::system::kHardwareClassKey, &hardware_class_);
+  if (const absl::optional<base::StringPiece> hardware_class =
+          chromeos::system::StatisticsProvider::GetInstance()
+              ->GetMachineStatistic(chromeos::system::kHardwareClassKey)) {
+    hardware_class_ = std::string(hardware_class.value());
+  }
   are_statistics_loaded_ = true;
 }
 #endif
diff --git a/content/browser/webrtc/webrtc_internals_browsertest.cc b/content/browser/webrtc/webrtc_internals_browsertest.cc
index 07c2f64..77739fd 100644
--- a/content/browser/webrtc/webrtc_internals_browsertest.cc
+++ b/content/browser/webrtc/webrtc_internals_browsertest.cc
@@ -251,27 +251,28 @@
 
     EXPECT_EQ(base::Value::Type::LIST, value_requests->type());
 
-    base::ListValue* list_request =
-        static_cast<base::ListValue*>(value_requests.get());
-    EXPECT_EQ(requests.size(), list_request->GetList().size());
+    const base::Value::List& list_request = value_requests->GetList();
+    EXPECT_EQ(requests.size(), list_request.size());
 
     for (size_t i = 0; i < requests.size(); ++i) {
-      const base::Value& value = list_request->GetList()[i];
+      const base::Value& value = list_request[i];
       ASSERT_TRUE(value.is_dict());
       absl::optional<int> rid = value.FindIntKey("rid");
       absl::optional<int> pid = value.FindIntKey("pid");
-      std::string origin, audio, video;
       ASSERT_TRUE(rid);
       ASSERT_TRUE(pid);
-      const base::DictionaryValue& dict = base::Value::AsDictionaryValue(value);
-      ASSERT_TRUE(dict.GetString("origin", &origin));
-      ASSERT_TRUE(dict.GetString("audio", &audio));
-      ASSERT_TRUE(dict.GetString("video", &video));
+      const base::Value::Dict& dict = value.GetDict();
+      const std::string* origin = dict.FindString("origin");
+      const std::string* audio = dict.FindString("audio");
+      const std::string* video = dict.FindString("video");
+      ASSERT_TRUE(origin);
+      ASSERT_TRUE(audio);
+      ASSERT_TRUE(video);
       EXPECT_EQ(requests[i].rid, *rid);
       EXPECT_EQ(requests[i].pid, *pid);
-      EXPECT_EQ(requests[i].origin, origin);
-      EXPECT_EQ(requests[i].audio_constraints, audio);
-      EXPECT_EQ(requests[i].video_constraints, video);
+      EXPECT_EQ(requests[i].origin, *origin);
+      EXPECT_EQ(requests[i].audio_constraints, *audio);
+      EXPECT_EQ(requests[i].video_constraints, *video);
     }
 
     bool user_media_tab_existed = false;
@@ -487,22 +488,16 @@
                        const string& report_id,
                        const StatsUnit& stats) {
     EXPECT_NE((base::Value*)nullptr, dump);
-    EXPECT_EQ(base::Value::Type::DICTIONARY, dump->type());
+    EXPECT_EQ(base::Value::Type::DICT, dump->type());
 
-    base::DictionaryValue* dict_dump =
-        static_cast<base::DictionaryValue*>(dump);
-    base::Value* value = nullptr;
-    dict_dump->Get(pc.getIdString(), &value);
-    base::DictionaryValue* pc_dump = static_cast<base::DictionaryValue*>(value);
+    const base::Value::Dict& dict_dump = dump->GetDict();
+    const base::Value::Dict* pc_dump = dict_dump.FindDict(pc.getIdString());
+    ASSERT_TRUE(pc_dump);
 
     // Verifies there is one data series per stats name.
-    value = nullptr;
-    pc_dump->Get("stats", &value);
-    EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());
-
-    base::DictionaryValue* dataSeries =
-        static_cast<base::DictionaryValue*>(value);
-    EXPECT_EQ(stats.values.size(), dataSeries->DictSize());
+    const base::Value::Dict* data_series_dump = pc_dump->FindDict("stats");
+    ASSERT_TRUE(data_series_dump);
+    EXPECT_EQ(stats.values.size(), data_series_dump->size());
   }
 };
 
diff --git a/content/common/common_param_traits_unittest.cc b/content/common/common_param_traits_unittest.cc
index a214ec7..0dea6853 100644
--- a/content/common/common_param_traits_unittest.cc
+++ b/content/common/common_param_traits_unittest.cc
@@ -86,28 +86,28 @@
   EXPECT_FALSE(IPC::ParamTraits<SkBitmap>::Read(&bad_msg, &iter, &bad_output));
 }
 
-TEST(IPCMessageTest, DictionaryValue) {
-  base::DictionaryValue input;
-  input.SetKey("null", base::Value());
-  input.SetBoolean("bool", true);
-  input.GetDict().Set("int", 42);
+TEST(IPCMessageTest, ValueDict) {
+  base::Value::Dict input;
+  input.Set("null", base::Value());
+  input.Set("bool", true);
+  input.Set("int", 42);
 
-  base::DictionaryValue subdict;
-  subdict.SetString("str", "forty two");
-  subdict.SetBoolean("bool", false);
+  base::Value::Dict subdict;
+  subdict.Set("str", "forty two");
+  subdict.Set("bool", false);
 
-  base::ListValue sublist;
+  base::Value::List sublist;
   sublist.Append(42.42);
   sublist.Append("forty");
   sublist.Append("two");
-  subdict.SetKey("list", std::move(sublist));
+  subdict.Set("list", std::move(sublist));
 
-  input.SetKey("dict", std::move(subdict));
+  input.Set("dict", std::move(subdict));
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
   IPC::WriteParam(&msg, input);
 
-  base::DictionaryValue output;
+  base::Value::Dict output;
   base::PickleIterator iter(msg);
   EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
 
diff --git a/content/common/webid/identity_url_loader_throttle.cc b/content/common/webid/identity_url_loader_throttle.cc
index febdb80..5db57fa 100644
--- a/content/common/webid/identity_url_loader_throttle.cc
+++ b/content/common/webid/identity_url_loader_throttle.cc
@@ -50,6 +50,8 @@
 
 IdentityUrlLoaderThrottle::~IdentityUrlLoaderThrottle() = default;
 
+void IdentityUrlLoaderThrottle::DetachFromCurrentSequence() {}
+
 void IdentityUrlLoaderThrottle::WillStartRequest(
     network::ResourceRequest* request,
     bool* defer) {
diff --git a/content/common/webid/identity_url_loader_throttle.h b/content/common/webid/identity_url_loader_throttle.h
index 134d4fc..0a82af38 100644
--- a/content/common/webid/identity_url_loader_throttle.h
+++ b/content/common/webid/identity_url_loader_throttle.h
@@ -27,6 +27,7 @@
       delete;
 
   // URLLoaderThrottle implementation:
+  void DetachFromCurrentSequence() override;
   void WillStartRequest(network::ResourceRequest* request,
                         bool* defer) override;
   void WillProcessResponse(const GURL& response_url,
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 560e66d4..2a4a2183 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -337,11 +337,6 @@
   return false;
 }
 
-bool ContentBrowserClient::IsIsolatedWebAppsDeveloperModeAllowed(
-    BrowserContext* context) {
-  return true;
-}
-
 bool ContentBrowserClient::IsGetDisplayMediaSetSelectAllScreensAllowed(
     content::BrowserContext* context,
     const url::Origin& origin) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index bdb4632..ffb1fc98 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -642,12 +642,6 @@
   virtual bool IsIsolatedContextAllowedForUrl(BrowserContext* browser_context,
                                               const GURL& lock_url);
 
-  // Checks whether isolated apps developer mode is allowed by the
-  // AllowIsolatedWebAppsDeveloperMode policy (chrome-only, the respective
-  // override can be found in ChromeContentBrowserClient). Returns true by
-  // default.
-  virtual bool IsIsolatedWebAppsDeveloperModeAllowed(BrowserContext* context);
-
   // Check if applications whose origin is |origin| are allowed to perform
   // all-screens-auto-selection, which allows automatic capturing of all
   // screens with the getDisplayMediaSet API.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index a37c274..04938b883 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -1192,7 +1192,7 @@
 // Enable memory protection for code JITed for WebAssembly.
 BASE_FEATURE(kWebAssemblyCodeProtection,
              "WebAssemblyCodeProtection",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 
 #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(ARCH_CPU_X86_64)
 // Use memory protection keys in userspace (PKU) (if available) to protect code
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 1940183..f39060a 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -117,8 +117,7 @@
 
 RenderAccessibilityImpl::RenderAccessibilityImpl(
     RenderAccessibilityManager* const render_accessibility_manager,
-    RenderFrameImpl* const render_frame,
-    ui::AXMode mode)
+    RenderFrameImpl* const render_frame)
     : RenderFrameObserver(render_frame),
       render_accessibility_manager_(render_accessibility_manager),
       render_frame_(render_frame),
@@ -126,8 +125,7 @@
       event_schedule_status_(EventScheduleStatus::kNotWaiting),
       reset_token_(0),
       ukm_timer_(std::make_unique<base::ElapsedTimer>()),
-      last_ukm_source_id_(ukm::kInvalidSourceId),
-      accessibility_mode_(mode) {
+      last_ukm_source_id_(ukm::kInvalidSourceId) {
   mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> recorder;
   content::RenderThread::Get()->BindHostReceiver(
       recorder.InitWithNewPipeAndPassReceiver());
@@ -135,19 +133,11 @@
   WebView* web_view = render_frame_->GetWebView();
   WebSettings* settings = web_view->GetSettings();
 
-  SetAccessibilityCrashKey(mode);
 #if BUILDFLAG(IS_ANDROID)
   // Password values are only passed through on Android.
   settings->SetAccessibilityPasswordValuesEnabled(true);
 #endif
 
-#if !BUILDFLAG(IS_ANDROID)
-  // Inline text boxes can be enabled globally on all except Android.
-  // On Android they can be requested for just a specific node.
-  if (mode.has_mode(ui::AXMode::kInlineTextBoxes))
-    settings->SetInlineTextBoxAccessibilityEnabled(true);
-#endif
-
 #if BUILDFLAG(IS_MAC)
   // aria-modal currently prunes the accessibility tree on Mac only.
   settings->SetAriaModalPrunesAXTree(true);
@@ -176,18 +166,6 @@
   if (disable_ax_menu_list)
     settings->SetUseAXMenuList(false);
 
-  const WebDocument& document = GetMainDocument();
-  if (!document.IsNull()) {
-    ax_context_ = std::make_unique<WebAXContext>(document, mode);
-    StartOrStopLabelingImages(ui::AXMode(), mode);
-
-    // It's possible that the webview has already loaded a webpage without
-    // accessibility being enabled. Initialize the browser's cached
-    // accessibility tree by firing a layout complete for the document.
-    // Ensure that this occurs after initial layout is actually complete.
-    ScheduleSendPendingAccessibilityEvents();
-  }
-
   image_annotation_debugging_ =
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           ::switches::kEnableExperimentalAccessibilityLabelsDebugging);
@@ -197,8 +175,8 @@
 
 void RenderAccessibilityImpl::DidCreateNewDocument() {
   const WebDocument& document = GetMainDocument();
-  if (!document.IsNull())
-    ax_context_ = std::make_unique<WebAXContext>(document, accessibility_mode_);
+  DCHECK(!document.IsNull());
+  ax_context_ = std::make_unique<WebAXContext>(document, accessibility_mode_);
 }
 
 void RenderAccessibilityImpl::DidCommitProvisionalLoad(
@@ -228,52 +206,71 @@
 
 void RenderAccessibilityImpl::AccessibilityModeChanged(const ui::AXMode& mode) {
   ui::AXMode old_mode = accessibility_mode_;
-  if (old_mode == mode)
-    return;
-  accessibility_mode_ = mode;
+  DCHECK(!mode.is_mode_off())
+      << "Should not be reached when turning a11y off; rather, the "
+         "RenderAccessibilityImpl should be destroyed.";
 
-  // TODO(aleventhal): DCHECK(!mode.is_mode_off()), because this object
-  // should be deleted before that mode is set.
-  if (mode.is_mode_off()) {
-    ax_context_ = nullptr;
-    return;
-  } else if (ax_context_) {
-    ax_context_->SetAXMode(mode);
-  } else {
+  if (old_mode == mode) {
+    DCHECK(ax_context_);
     return;
   }
 
-  DCHECK(ax_context_);
-  DCHECK_EQ(accessibility_mode_, ax_context_->GetAXMode());
+  accessibility_mode_ = mode;
+
+  bool was_on = !old_mode.is_mode_off();
+
+  DCHECK_EQ(was_on, !!ax_context_);
 
   SetAccessibilityCrashKey(mode);
 
+  // Initialize features based on the accessibility mode.
 #if !BUILDFLAG(IS_ANDROID)
   // Inline text boxes can be enabled globally on all except Android.
   // On Android they can be requested for just a specific node.
   WebView* web_view = render_frame_->GetWebView();
-  if (web_view) {
-    WebSettings* settings = web_view->GetSettings();
-    if (settings) {
-      if (mode.has_mode(ui::AXMode::kInlineTextBoxes)) {
-        settings->SetInlineTextBoxAccessibilityEnabled(true);
-        ax_context_->UpdateAXForAllDocuments();
-        ComputeRoot().LoadInlineTextBoxes();
-      } else {
-        settings->SetInlineTextBoxAccessibilityEnabled(false);
-      }
+  DCHECK(web_view);
+  WebSettings* settings = web_view->GetSettings();
+  DCHECK(settings);
+  if (mode.has_mode(ui::AXMode::kInlineTextBoxes)) {
+    settings->SetInlineTextBoxAccessibilityEnabled(true);
+    // If accessibility was already on, update it to load inline text boxes.
+    // Otherwise, just build the tree naturally.
+    if (was_on) {
+      ax_context_->UpdateAXForAllDocuments();
+      ComputeRoot().LoadInlineTextBoxes();
     }
+  } else {
+    settings->SetInlineTextBoxAccessibilityEnabled(false);
   }
 #endif  // !BUILDFLAG(IS_ANDROID)
+  StartOrStopLabelingImages(old_mode, mode);
 
-  ax_context_->ResetSerializer();
-  const WebDocument& document = GetMainDocument();
-  if (!document.IsNull()) {
-    StartOrStopLabelingImages(old_mode, mode);
+  if (ax_context_)
+    ax_context_->SetAXMode(mode);
+  else
+    DidCreateNewDocument();
 
-    needs_initial_ax_tree_root_ = true;
-    event_schedule_mode_ = EventScheduleMode::kProcessEventsImmediately;
-    ScheduleSendPendingAccessibilityEvents();
+  DCHECK(ax_context_);
+  DCHECK_EQ(accessibility_mode_, ax_context_->GetAXMode());
+
+  if (was_on) {
+    // When the accessibility mode changes, all state contained in the
+    // serializer, which prevents previously serialized data from being
+    // reserialized, is now out-of-date.
+    ax_context_->ResetSerializer();
+  }
+
+  // Fire a load complete event so that any ATs present can treat the page as
+  // fresh and newly loaded.
+  FireLoadCompleteIfLoaded();
+}
+
+void RenderAccessibilityImpl::FireLoadCompleteIfLoaded() {
+  if (GetMainDocument().GetFrame()->GetEmbeddingToken()) {
+    DCHECK(ax_context_);
+    ax_context_->UpdateAXForAllDocuments();
+    ax_context_->FireLoadCompleteIfLoaded();
+    ax_context_->UpdateAXForAllDocuments();
   }
 }
 
@@ -287,6 +284,7 @@
     blink::mojom::RenderAccessibility::HitTestCallback callback) {
   const WebDocument& document = GetMainDocument();
   DCHECK(!document.IsNull());
+  DCHECK(ax_context_);
   ax_context_->UpdateAXForAllDocuments();
 
   WebAXObject ax_object;
@@ -474,22 +472,12 @@
 }
 
 void RenderAccessibilityImpl::Reset(int32_t reset_token) {
+  DCHECK(ax_context_);
+  DCHECK(!accessibility_mode_.is_mode_off());
   reset_token_ = reset_token;
-  if (ax_context_) {
-    ax_context_->ResetSerializer();
-    ax_context_->ClearDirtyObjectsAndPendingEvents();
-  }
-
-  const WebDocument& document = GetMainDocument();
-  if (!document.IsNull()) {
-    // Tree-only mode gets used by the automation extension API which requires a
-    // load complete event to invoke listener callbacks.
-    // SendPendingAccessibilityEvents() will fire the load complete event
-    // if the page is loaded.
-    needs_initial_ax_tree_root_ = true;
-    event_schedule_mode_ = EventScheduleMode::kProcessEventsImmediately;
-    ScheduleSendPendingAccessibilityEvents();
-  }
+  ax_context_->ResetSerializer();
+  ax_context_->ClearDirtyObjectsAndPendingEvents();
+  FireLoadCompleteIfLoaded();
 }
 
 void RenderAccessibilityImpl::MarkWebAXObjectDirty(
@@ -522,9 +510,9 @@
 }
 
 void RenderAccessibilityImpl::HandleAXEvent(const ui::AXEvent& event) {
+  DCHECK(ax_context_);
   const WebDocument& document = GetMainDocument();
-  if (document.IsNull())
-    return;
+  DCHECK(!document.IsNull());
 
   auto obj = WebAXObject::FromWebDocumentByID(document, event.id);
   if (obj.IsDetached())
@@ -540,7 +528,7 @@
     obj.InvalidateSerializerSubtree();
 #endif
 
-  if (!ax_context_ || !ax_context_->AddPendingEvent(event)) {
+  if (!ax_context_->AddPendingEvent(event)) {
     DCHECK(ax_context_);
     return;
   }
@@ -1030,6 +1018,8 @@
   // Serialize all dirty objects in the list at this point in time, stopping
   // either when the queue is empty, or the number of remaining objects to
   // serialize has been reached.
+  DCHECK(ax_context_);
+  DCHECK(!accessibility_mode_.is_mode_off());
   ax_context_->SerializeDirtyObjectsAndEvents(
       !!plugin_tree_source_, updates, events, had_end_of_test_event,
       had_load_complete_messages, need_to_send_location_changes);
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h
index 123d387..003b063 100644
--- a/content/renderer/accessibility/render_accessibility_impl.h
+++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -80,10 +80,11 @@
 class CONTENT_EXPORT RenderAccessibilityImpl : public RenderAccessibility,
                                                public RenderFrameObserver {
  public:
+  // A call to AccessibilityModeChanged() is required after construction to
+  // start accessibility.
   RenderAccessibilityImpl(
       RenderAccessibilityManager* const render_accessibility_manager,
-      RenderFrameImpl* const render_frame,
-      ui::AXMode mode);
+      RenderFrameImpl* const render_frame);
 
   RenderAccessibilityImpl(const RenderAccessibilityImpl&) = delete;
   RenderAccessibilityImpl& operator=(const RenderAccessibilityImpl&) = delete;
@@ -186,6 +187,9 @@
   void AddPluginTreeToUpdate(ui::AXTreeUpdate* update,
                              bool invalidate_plugin_subtree);
 
+  // If the document is loaded, fire a load complete event.
+  void FireLoadCompleteIfLoaded();
+
   // Creates and takes ownership of an instance of the class that automatically
   // labels images for accessibility.
   void CreateAXImageAnnotator();
diff --git a/content/renderer/accessibility/render_accessibility_manager.cc b/content/renderer/accessibility/render_accessibility_manager.cc
index 312ddcb4..4db08b83 100644
--- a/content/renderer/accessibility/render_accessibility_manager.cc
+++ b/content/renderer/accessibility/render_accessibility_manager.cc
@@ -55,8 +55,8 @@
 
   if (new_mode.has_mode(ui::AXMode::kWebContents) &&
       !old_mode.has_mode(ui::AXMode::kWebContents)) {
-    render_accessibility_ = std::make_unique<RenderAccessibilityImpl>(
-        this, render_frame_, new_mode);
+    render_accessibility_ =
+        std::make_unique<RenderAccessibilityImpl>(this, render_frame_);
   } else if (!new_mode.has_mode(ui::AXMode::kWebContents) &&
              old_mode.has_mode(ui::AXMode::kWebContents)) {
     render_accessibility_.reset();
diff --git a/content/renderer/v8_value_converter_impl_unittest.cc b/content/renderer/v8_value_converter_impl_unittest.cc
index 358e0cc..eb7c1ce 100644
--- a/content/renderer/v8_value_converter_impl_unittest.cc
+++ b/content/renderer/v8_value_converter_impl_unittest.cc
@@ -84,13 +84,13 @@
 
   void TearDown() override { context_.Reset(); }
 
-  std::string GetString(base::DictionaryValue* value, const std::string& key) {
-    std::string temp;
-    if (!value->GetString(key, &temp)) {
+  std::string GetString(base::Value::Dict* value, const std::string& key) {
+    std::string* temp = value->FindString(key);
+    if (!temp) {
       ADD_FAILURE();
       return std::string();
     }
-    return temp;
+    return *temp;
   }
 
   std::string GetString(v8::Local<v8::Object> value, const std::string& key) {
@@ -149,9 +149,9 @@
     return temp.As<v8::Int32>()->Value();
   }
 
-  bool IsNull(base::DictionaryValue* value, const std::string& key) {
-    base::Value* child = nullptr;
-    if (!value->Get(key, &child)) {
+  bool IsNull(base::Value::Dict* value, const std::string& key) {
+    base::Value* child = value->Find(key);
+    if (!child) {
       ADD_FAILURE();
       return false;
     }
@@ -452,17 +452,19 @@
 
   // Converting from v8 value should replace the foo property with null.
   V8ValueConverterImpl converter;
-  std::unique_ptr<base::DictionaryValue> converted(
-      base::DictionaryValue::From(converter.FromV8Value(object, context)));
-  ASSERT_TRUE(converted.get());
+  std::unique_ptr<base::Value> base_value =
+      converter.FromV8Value(object, context);
+  base::Value::Dict* converted = base_value->GetIfDict();
+  ASSERT_TRUE(converted);
+
   // http://code.google.com/p/v8/issues/detail?id=1342
-  // EXPECT_EQ(2u, converted->size());
-  // EXPECT_TRUE(IsNull(converted.get(), "foo"));
-  EXPECT_EQ(1u, converted->DictSize());
-  EXPECT_EQ("bar", GetString(converted.get(), "bar"));
+  // EXPECT_EQ(2u, converted);
+  // EXPECT_TRUE(IsNull(*converted, "foo"));
+  EXPECT_EQ(1u, converted->size());
+  EXPECT_EQ("bar", GetString(converted, "bar"));
 
   // Converting to v8 value should not trigger the setter.
-  converted->SetString("foo", "foo");
+  converted->Set("foo", "foo");
   v8::Local<v8::Object> copy =
       converter.ToV8Value(*converted, context).As<v8::Object>();
   EXPECT_FALSE(copy.IsEmpty());
@@ -533,9 +535,9 @@
                 std::unique_ptr<base::Value>());
   TestWeirdType(converter, v8::Date::New(context, 1000).ToLocalChecked(),
                 base::Value::Type::DICTIONARY,
-                std::unique_ptr<base::Value>(new base::DictionaryValue()));
+                std::make_unique<base::Value>(base::Value::Type::DICT));
   TestWeirdType(converter, regex, base::Value::Type::DICTIONARY,
-                std::unique_ptr<base::Value>(new base::DictionaryValue()));
+                std::make_unique<base::Value>(base::Value::Type::DICT));
 
   converter.SetDateAllowed(true);
   TestWeirdType(converter, v8::Date::New(context, 1000).ToLocalChecked(),
@@ -563,10 +565,11 @@
   v8::Local<v8::Object> object = CompileRun<v8::Object>(context, source);
 
   V8ValueConverterImpl converter;
-  std::unique_ptr<base::DictionaryValue> result(
-      base::DictionaryValue::From(converter.FromV8Value(object, context)));
-  ASSERT_TRUE(result.get());
-  EXPECT_EQ(0u, result->DictSize());
+  std::unique_ptr<base::Value> base_value =
+      converter.FromV8Value(object, context);
+  base::Value::Dict* result = base_value->GetIfDict();
+  ASSERT_TRUE(result);
+  EXPECT_TRUE(result->empty());
 }
 
 TEST_F(V8ValueConverterImplTest, ObjectPrototypeSetter) {
@@ -723,11 +726,11 @@
 
   V8ValueConverterImpl converter;
   converter.SetStripNullFromObjects(true);
-
-  std::unique_ptr<base::DictionaryValue> result(
-      base::DictionaryValue::From(converter.FromV8Value(object, context)));
-  ASSERT_TRUE(result.get());
-  EXPECT_EQ(0u, result->DictSize());
+  std::unique_ptr<base::Value> base_value =
+      converter.FromV8Value(object, context);
+  base::Value::Dict* result = base_value->GetIfDict();
+  ASSERT_TRUE(result);
+  EXPECT_TRUE(result->empty());
 }
 
 TEST_F(V8ValueConverterImplTest, RecursiveObjects) {
@@ -757,11 +760,12 @@
             object)
       .Check();
 
-  std::unique_ptr<base::DictionaryValue> object_result(
-      base::DictionaryValue::From(converter.FromV8Value(object, context)));
-  ASSERT_TRUE(object_result.get());
-  EXPECT_EQ(2u, object_result->DictSize());
-  EXPECT_TRUE(IsNull(object_result.get(), "obj"));
+  std::unique_ptr<base::Value> base_value =
+      converter.FromV8Value(object, context);
+  base::Value::Dict* object_result = base_value->GetIfDict();
+  ASSERT_TRUE(object_result);
+  EXPECT_EQ(2u, object_result->size());
+  EXPECT_TRUE(IsNull(object_result, "obj"));
 
   v8::Local<v8::Array> array = v8::Array::New(isolate_).As<v8::Array>();
   ASSERT_FALSE(array.IsEmpty());
@@ -961,15 +965,15 @@
       .Check();
 
   // The first repetition should be trimmed and replaced by a null value.
-  base::DictionaryValue expected_dictionary;
-  expected_dictionary.SetKey(key, base::Value());
+  base::Value::Dict expected_dictionary;
+  expected_dictionary.Set(key, base::Value());
 
   // The actual result.
-  std::unique_ptr<base::Value> actual_dictionary(
-      converter.FromV8Value(recursive_object, context));
-  ASSERT_TRUE(actual_dictionary.get());
-
-  EXPECT_TRUE(expected_dictionary == *actual_dictionary);
+  std::unique_ptr<base::Value> base_value =
+      converter.FromV8Value(recursive_object, context);
+  base::Value::Dict* actual_dictionary = base_value->GetIfDict();
+  ASSERT_TRUE(actual_dictionary);
+  EXPECT_EQ(expected_dictionary, *actual_dictionary);
 }
 
 // Tests that reused object values with no cycles do not get nullified.
@@ -993,21 +997,22 @@
     v8::Local<v8::Object> object = CompileRun<v8::Object>(context, source);
 
     // The actual result.
-    std::unique_ptr<base::DictionaryValue> result(
-        base::DictionaryValue::From(converter.FromV8Value(object, context)));
-    ASSERT_TRUE(result.get());
-    EXPECT_EQ(2u, result->DictSize());
+    std::unique_ptr<base::Value> base_value =
+        converter.FromV8Value(object, context);
+    base::Value::Dict* result = base_value->GetIfDict();
+    ASSERT_TRUE(result);
+    EXPECT_EQ(2u, result->size());
 
     {
-      base::DictionaryValue* one_dict = nullptr;
       const char key1[] = "one";
-      ASSERT_TRUE(result->GetDictionary(key1, &one_dict));
+      base::Value::Dict* one_dict = result->FindDict(key1);
+      ASSERT_TRUE(one_dict);
       EXPECT_EQ("another same value", GetString(one_dict, "key"));
     }
     {
-      base::DictionaryValue* two_dict = nullptr;
       const char key2[] = "two";
-      ASSERT_TRUE(result->GetDictionary(key2, &two_dict));
+      base::Value::Dict* two_dict = result->FindDict(key2);
+      ASSERT_TRUE(two_dict);
       EXPECT_EQ("another same value", GetString(two_dict, "key"));
     }
   }
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 4a585ac..04914d25 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -198,6 +198,7 @@
       "//base:base_java_test_support",
       "//components/crash/android:java",
       "//components/crash/core/app:chrome_crashpad_handler_named_as_so",
+      "//components/metrics:metrics_java",
       "//content/public/android:content_java",
       "//content/public/test/android:android_test_message_pump_support_java",
       "//media/capture/video/android:capture_java",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index c6e2672..55d79b4 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1124,6 +1124,7 @@
       "//base:base_java_test_support",
       "//base:jni_java",
       "//components/download/internal/common:internal_java",
+      "//components/metrics:metrics_java",
       "//components/viz/service:service_java",
       "//content/public/android:content_java",
       "//content/public/test/android:content_java_test_support",
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc
index 1844cd51..97afd0b2 100644
--- a/content/test/attribution_simulator_input_parser.cc
+++ b/content/test/attribution_simulator_input_parser.cc
@@ -21,11 +21,6 @@
 #include "base/types/expected.h"
 #include "base/types/optional_util.h"
 #include "base/values.h"
-#include "components/attribution_reporting/aggregatable_trigger_data.h"
-#include "components/attribution_reporting/aggregatable_values.h"
-#include "components/attribution_reporting/constants.h"
-#include "components/attribution_reporting/event_trigger_data.h"
-#include "components/attribution_reporting/filters.h"
 #include "components/attribution_reporting/source_registration_error.mojom.h"
 #include "components/attribution_reporting/suitable_origin.h"
 #include "components/attribution_reporting/trigger_registration.h"
@@ -132,18 +127,12 @@
 
   template <typename T>
   void ParseList(T&& values,
-                 base::RepeatingCallback<void(decltype(values))> callback,
-                 size_t max_size = 0) {
+                 base::RepeatingCallback<void(decltype(values))> callback) {
     if (!values.is_list()) {
       *Error() << "must be a list";
       return;
     }
 
-    if (max_size > 0 && values.GetList().size() > max_size) {
-      *Error() << "too many elements";
-      return;
-    }
-
     size_t index = 0;
     for (auto&& value : values.GetList()) {
       auto index_context = PushContext(index);
@@ -288,86 +277,30 @@
     absl::optional<SuitableOrigin> destination_origin =
         ParseOrigin(trigger_dict, "destination_origin");
 
-    absl::optional<uint64_t> debug_key;
-    attribution_reporting::Filters filters;
-    attribution_reporting::Filters not_filters;
-    std::vector<attribution_reporting::EventTriggerData> event_triggers;
-    std::vector<attribution_reporting::AggregatableTriggerData>
-        aggregatable_trigger_data;
-    attribution_reporting::AggregatableValues aggregatable_values;
-    absl::optional<uint64_t> aggregatable_dedup_key;
-    bool debug_reporting;
-
-    if (!ParseAttributionEvent(
-            trigger_dict,
-            "Attribution-Reporting-Register-Trigger",
-            base::BindLambdaForTesting(
-                [&](const base::Value::Dict& dict) {
-                  debug_key = ParseOptionalUint64(dict, "debug_key");
-                  filters = ParseFilters(dict, "filters");
-                  not_filters = ParseFilters(dict, "not_filters");
-                  event_triggers = ParseEventTriggers(dict);
-
-                  aggregatable_trigger_data =
-                      ParseAggregatableTriggerData(dict);
-
-                  aggregatable_values = ParseAggregatableValues(dict);
-
-                  aggregatable_dedup_key = ParseOptionalUint64(
-                      dict, "aggregatable_deduplication_key");
-
-                  debug_reporting = ParseDebugReporting(dict);
-                }))) {
-      return;
-    }
-
     if (has_error())
       return;
 
-    events_.emplace_back(
-        AttributionTriggerAndTime{
-            .trigger = AttributionTrigger(
-                attribution_reporting::TriggerRegistration(
-                    std::move(*reporting_origin), std::move(filters),
-                    std::move(not_filters), debug_key, aggregatable_dedup_key,
-                    *attribution_reporting::EventTriggerDataList::Create(
-                        std::move(event_triggers)),
-                    *attribution_reporting::AggregatableTriggerDataList::Create(
-                        std::move(aggregatable_trigger_data)),
-                    std::move(aggregatable_values), debug_reporting),
-                std::move(*destination_origin),
-                /*is_within_fenced_frame=*/false),
-            .time = trigger_time,
-        },
-        std::move(trigger));
-  }
+    ParseAttributionEvent(
+        trigger_dict, "Attribution-Reporting-Register-Trigger",
+        base::BindLambdaForTesting([&](const base::Value::Dict& dict) {
+          auto trigger_registration =
+              attribution_reporting::TriggerRegistration::Parse(
+                  dict.Clone(), std::move(*reporting_origin));
+          if (!trigger_registration.has_value()) {
+            *Error() << trigger_registration.error();
+            return;
+          }
 
-  std::vector<attribution_reporting::EventTriggerData> ParseEventTriggers(
-      const base::Value::Dict& cfg) {
-    std::vector<attribution_reporting::EventTriggerData> event_triggers;
-
-    static constexpr char kKey[] = "event_trigger_data";
-
-    const base::Value* values = cfg.Find(kKey);
-    if (!values)
-      return event_triggers;
-
-    auto context = PushContext(kKey);
-    ParseList(*values,
-              base::BindLambdaForTesting([&](const base::Value& event_trigger) {
-                base::Value event_trigger_copy = event_trigger.Clone();
-                auto data = attribution_reporting::EventTriggerData::FromJSON(
-                    event_trigger_copy);
-                if (!data.has_value()) {
-                  *Error() << data.error();
-                  return;
-                }
-
-                event_triggers.emplace_back(std::move(*data));
-              }),
-              /*max_size=*/attribution_reporting::kMaxEventTriggerData);
-
-    return event_triggers;
+          events_.emplace_back(
+              AttributionTriggerAndTime{
+                  .trigger =
+                      AttributionTrigger(std::move(*trigger_registration),
+                                         std::move(*destination_origin),
+                                         /*is_within_fenced_frame=*/false),
+                  .time = trigger_time,
+              },
+              std::move(trigger));
+        }));
   }
 
   GURL ParseURL(const base::Value::Dict& dict, base::StringPiece key) const {
@@ -408,55 +341,6 @@
     return base::Time();
   }
 
-  uint64_t ParseUint64(const std::string* s, base::StringPiece key) {
-    auto context = PushContext(key);
-
-    uint64_t value = 0;
-
-    if (!s || !base::StringToUint64(*s, &value))
-      *Error() << "must be a uint64 formatted as a base-10 string";
-
-    return value;
-  }
-
-  int64_t ParseInt64(const std::string* s, base::StringPiece key) {
-    auto context = PushContext(key);
-
-    int64_t value = 0;
-
-    if (!s || !base::StringToInt64(*s, &value))
-      *Error() << "must be an int64 formatted as a base-10 string";
-
-    return value;
-  }
-
-  absl::optional<uint64_t> ParseOptionalUint64(const base::Value::Dict& dict,
-                                               base::StringPiece key) {
-    const base::Value* value = dict.Find(key);
-    if (!value)
-      return absl::nullopt;
-
-    return ParseUint64(value->GetIfString(), key);
-  }
-
-  bool ParseDebugReporting(const base::Value::Dict& dict) {
-    static constexpr char kKey[] = "debug_reporting";
-
-    auto context = PushContext(kKey);
-
-    const base::Value* value = dict.Find(kKey);
-    if (!value)
-      return false;
-
-    absl::optional<bool> bool_value = value->GetIfBool();
-    if (!bool_value) {
-      *Error() << "must be a boolean";
-      return false;
-    }
-
-    return *bool_value;
-  }
-
   absl::optional<AttributionSourceType> ParseSourceType(
       const base::Value::Dict& dict) {
     static constexpr char kKey[] = "source_type";
@@ -502,71 +386,6 @@
     return true;
   }
 
-  attribution_reporting::Filters ParseFilters(const base::Value::Dict& dict,
-                                              base::StringPiece key) {
-    auto context = PushContext(key);
-
-    absl::optional<base::Value> value =
-        dict.Find(key) ? absl::make_optional(dict.Find(key)->Clone())
-                       : absl::nullopt;
-
-    auto filters =
-        attribution_reporting::Filters::FromJSON(base::OptionalToPtr(value));
-    if (filters.has_value())
-      return *filters;
-
-    *Error() << filters.error();
-    return attribution_reporting::Filters();
-  }
-
-  std::vector<attribution_reporting::AggregatableTriggerData>
-  ParseAggregatableTriggerData(const base::Value::Dict& dict) {
-    static constexpr char kKey[] = "aggregatable_trigger_data";
-
-    std::vector<attribution_reporting::AggregatableTriggerData>
-        aggregatable_triggers;
-
-    const base::Value* values = dict.Find(kKey);
-    if (!values)
-      return aggregatable_triggers;
-
-    auto context = PushContext(kKey);
-    ParseList(
-        *values,
-        base::BindLambdaForTesting(
-            [&](const base::Value& aggregatable_trigger) {
-              base::Value aggregatable_trigger_copy =
-                  aggregatable_trigger.Clone();
-              auto trigger_data =
-                  attribution_reporting::AggregatableTriggerData::FromJSON(
-                      aggregatable_trigger_copy);
-              if (!trigger_data.has_value()) {
-                *Error() << trigger_data.error();
-                return;
-              }
-
-              aggregatable_triggers.push_back(std::move(*trigger_data));
-            }),
-        attribution_reporting::kMaxAggregatableTriggerDataPerTrigger);
-
-    return aggregatable_triggers;
-  }
-
-  attribution_reporting::AggregatableValues ParseAggregatableValues(
-      const base::Value::Dict& dict) {
-    static constexpr char kKey[] = "aggregatable_values";
-
-    auto context = PushContext(kKey);
-
-    auto aggregatable_values =
-        attribution_reporting::AggregatableValues::FromJSON(dict.Find(kKey));
-    if (aggregatable_values.has_value())
-      return *aggregatable_values;
-
-    *Error() << aggregatable_values.error();
-    return attribution_reporting::AggregatableValues();
-  }
-
   bool EnsureDictionary(const base::Value& value) {
     if (!value.is_dict()) {
       *Error() << "must be a dictionary";
diff --git a/content/test/attribution_simulator_input_parser_unittest.cc b/content/test/attribution_simulator_input_parser_unittest.cc
index bc705c8f..7160352 100644
--- a/content/test/attribution_simulator_input_parser_unittest.cc
+++ b/content/test/attribution_simulator_input_parser_unittest.cc
@@ -607,7 +607,7 @@
   };
 
   static constexpr char kError[] =
-      R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"]: too many elements)";
+      R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataListTooLong)";
 
   for (const auto test_case : kTestCases) {
     base::Value::List list;
@@ -619,6 +619,9 @@
 
     base::Value::Dict dict;
     dict.Set("Attribution-Reporting-Register-Trigger", std::move(trigger));
+    dict.Set("timestamp", "1643235576000");
+    dict.Set("destination_origin", "https://a.d1.test");
+    dict.Set("reporting_origin", "https://a.r.test");
 
     base::Value::List triggers;
     triggers.Append(std::move(dict));
@@ -649,7 +652,7 @@
   };
 
   static constexpr char kError[] =
-      R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["event_trigger_data"]: too many elements)";
+      R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kEventTriggerDataListTooLong)";
 
   for (const auto test_case : kTestCases) {
     base::Value::List list;
@@ -661,6 +664,9 @@
 
     base::Value::Dict dict;
     dict.Set("Attribution-Reporting-Register-Trigger", std::move(trigger));
+    dict.Set("timestamp", "1643235576000");
+    dict.Set("destination_origin", "https://a.d1.test");
+    dict.Set("reporting_origin", "https://a.r.test");
 
     base::Value::List triggers;
     triggers.Append(std::move(dict));
@@ -913,25 +919,38 @@
     },
     {
         R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: must be present)",
-        R"json({"triggers": [{}]})json",
+        R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "destination_origin": "https://a.d1.test",
+          "reporting_origin": "https://a.r.test"
+        }]})json",
     },
     {
         R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: must be a dictionary)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "destination_origin": "https://a.d1.test",
+          "reporting_origin": "https://a.r.test",
           "Attribution-Reporting-Register-Trigger": ""
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["filters"]: kFiltersWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kFiltersWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "destination_origin": "https://a.d1.test",
+          "reporting_origin": "https://a.r.test",
           "Attribution-Reporting-Register-Trigger": {
             "filters": ""
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["not_filters"]: kFiltersListWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kFiltersListWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "destination_origin": "https://a.d1.test",
+          "reporting_origin": "https://a.r.test",
           "Attribution-Reporting-Register-Trigger": {
             "not_filters": {
               "a": "x"
@@ -940,45 +959,45 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["event_trigger_data"]: must be a list)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kEventTriggerDataListWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "event_trigger_data": 1
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"]: must be a list)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataListWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": 5
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: kAggregatableTriggerDataWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": [ 5 ]
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: kAggregatableTriggerDataSourceKeysMissing)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataSourceKeysMissing)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": [{
               "key_piece": "0x123"
             }]
@@ -986,12 +1005,12 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: kAggregatableTriggerDataSourceKeysWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataSourceKeysWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": [{
               "key_piece": "0x123",
               "source_keys": "a"
@@ -1000,12 +1019,12 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: kAggregatableTriggerDataSourceKeysKeyWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataSourceKeysKeyWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": [{
               "key_piece": "0x123",
               "source_keys": [ 5 ]
@@ -1014,12 +1033,12 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: kAggregatableTriggerDataKeyPieceWrongFormat)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableTriggerDataKeyPieceWrongFormat)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_trigger_data": [{
               "source_keys": [ "a" ],
               "key_piece": "0xG"
@@ -1028,23 +1047,23 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_values"]: kAggregatableValuesWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableValuesWrongType)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_values": 5
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_values"]: kAggregatableValuesValueOutOfRange)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kAggregatableValuesValueOutOfRange)",
         R"json({"triggers": [{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "aggregatable_values": {
               "a": -5
             }
@@ -1052,33 +1071,17 @@
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["event_trigger_data"][0]: kEventTriggerDataWrongType)",
+        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: kEventTriggerDataWrongType)",
         R"json({"triggers":[{
+          "timestamp": "1643235576000",
+          "reporting_origin": "https://a.r.test",
+          "destination_origin": " https://a.d1.test",
           "Attribution-Reporting-Register-Trigger": {
-            "timestamp": "1643235576000",
-            "reporting_origin": "https://a.r.test",
-            "destination_origin": " https://a.d1.test",
             "event_trigger_data":[true]
           }
         }]})json",
     },
     {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_deduplication_key"]: must be a uint64 formatted)",
-        R"json({"triggers":[{
-          "Attribution-Reporting-Register-Trigger": {
-            "aggregatable_deduplication_key": 123
-          }
-        }]})json",
-    },
-    {
-        R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["debug_reporting"]: must be a boolean)",
-        R"json({"triggers":[{
-          "Attribution-Reporting-Register-Trigger": {
-            "debug_reporting": 123
-          }
-        }]})json",
-    },
-    {
         R"(["cookies"][0]["timestamp"]: must be an integer number of milliseconds)",
         R"json({"cookies": [{}]})json",
     },
diff --git a/content/test/data/attribution_reporting/interop/aggregatable_report_window.json b/content/test/data/attribution_reporting/interop/aggregatable_report_window.json
new file mode 100644
index 0000000..c6a05b5
--- /dev/null
+++ b/content/test/data/attribution_reporting/interop/aggregatable_report_window.json
@@ -0,0 +1,183 @@
+{
+  "description": "Aggregatable report not created if report window has passed",
+  "input": {
+    "sources": [
+      {
+        "timestamp": "1643235573000",
+        "registration_request": {
+          "source_origin": "https://source.test",
+          "attribution_src_url": "https://reporter.test/register-source",
+          "source_type": "navigation"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-source",
+          "response": {
+            "Attribution-Reporting-Register-Source": {
+              "destination": "https://destination.test",
+              "source_event_id": "123",
+              "aggregatable_report_window": "86400",
+              "aggregation_keys": {
+                "a": "0x159"
+              }
+            }
+          }
+        }]
+      }
+    ],
+    "triggers": [
+      // Should result in an event-level report and an aggregatable report.
+      {
+        "timestamp": "1643235574000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "1"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 123
+              }
+            }
+          }
+        }]
+      },
+      // Should result in an event-level report and an aggregatable report.
+      {
+        "timestamp": "1643321973000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "2"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 456
+              }
+            }
+          }
+        }]
+      },
+      // Should result in an event-level report, but not aggregatable report as
+      // aggregatable report window has passed.
+      {
+        "timestamp": "1643321974000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "3"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 789
+              }
+            }
+          }
+        }]
+      }
+    ]
+  },
+  "output": {
+    "event_level_results": [
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "randomized_trigger_rate": 0.0024,
+          "source_event_id": "123",
+          "source_type": "navigation",
+          "trigger_data": "1"
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution",
+        "report_time": "1643411973000"
+      },
+      {
+        "payload": {
+           "attribution_destination": "https://destination.test",
+           "randomized_trigger_rate": 0.0024,
+           "source_event_id": "123",
+           "source_type": "navigation",
+           "trigger_data": "2"
+        },
+        "report_time": "1643411973000",
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution"
+     },
+     {
+      "payload": {
+         "attribution_destination": "https://destination.test",
+         "randomized_trigger_rate": 0.0024,
+         "source_event_id": "123",
+         "source_type": "navigation",
+         "trigger_data": "3"
+      },
+      "report_time": "1643411973000",
+      "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution"
+   }
+    ],
+    "aggregatable_results": [
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "histograms": [
+            {
+              "key": "0x559",
+              "value": 123
+            }
+          ]
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution",
+        "report_time": "1643239174000"
+      },
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "histograms": [
+            {
+              "key": "0x559",
+              "value": 456
+            }
+          ]
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution",
+        "report_time": "1643325573000"
+      }
+    ]
+  }
+}
diff --git a/content/test/data/attribution_reporting/interop/event_report_window.json b/content/test/data/attribution_reporting/interop/event_report_window.json
new file mode 100644
index 0000000..b1a16a6f
--- /dev/null
+++ b/content/test/data/attribution_reporting/interop/event_report_window.json
@@ -0,0 +1,181 @@
+{
+  "description": "Event-level report not created if report window has passed",
+  "input": {
+    "sources": [
+      {
+        "timestamp": "1643235573000",
+        "registration_request": {
+          "source_origin": "https://source.test",
+          "attribution_src_url": "https://reporter.test/register-source",
+          "source_type": "navigation"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-source",
+          "response": {
+            "Attribution-Reporting-Register-Source": {
+              "destination": "https://destination.test",
+              "source_event_id": "123",
+              "event_report_window": "86400",
+              "aggregation_keys": {
+                "a": "0x159"
+              }
+            }
+          }
+        }]
+      }
+    ],
+    "triggers": [
+      // Should result in an event-level report and an aggregatable report.
+      {
+        "timestamp": "1643235574000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "1"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 123
+              }
+            }
+          }
+        }]
+      },
+      // Should result in an event-level report and an aggregatable report.
+      {
+        "timestamp": "1643321973000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "2"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 456
+              }
+            }
+          }
+        }]
+      },
+      // Should result in an aggregatable report, but not event-level report as
+      // event report window has passed.
+      {
+        "timestamp": "1643321974000",
+        "registration_request": {
+          "attribution_src_url": "https://reporter.test/register-trigger",
+          "destination_origin": "https://destination.test"
+        },
+        "responses": [{
+          "url": "https://reporter.test/register-trigger",
+          "response": {
+            "Attribution-Reporting-Register-Trigger": {
+              "event_trigger_data": [
+                {
+                  "trigger_data": "3"
+                }
+              ],
+              "aggregatable_trigger_data": [
+                {
+                  "source_keys": ["a"],
+                  "key_piece": "0x400"
+                }
+              ],
+              "aggregatable_values": {
+                "a": 789
+              }
+            }
+          }
+        }]
+      }
+    ]
+  },
+  "output": {
+    "event_level_results": [
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "randomized_trigger_rate": 0.0024,
+          "source_event_id": "123",
+          "source_type": "navigation",
+          "trigger_data": "1"
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution",
+        "report_time": "1643325573000"
+      },
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "randomized_trigger_rate": 0.0024,
+          "source_event_id": "123",
+          "source_type": "navigation",
+          "trigger_data": "2"
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution",
+        "report_time": "1643325573000"
+      }
+    ],
+    "aggregatable_results": [
+      {
+        "payload": {
+          "attribution_destination": "https://destination.test",
+          "histograms": [
+            {
+              "key": "0x559",
+              "value": 123
+            }
+          ]
+        },
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution",
+        "report_time": "1643239174000"
+      },
+      {
+        "payload": {
+           "attribution_destination": "https://destination.test",
+           "histograms": [ {
+              "key": "0x559",
+              "value": 456
+           } ]
+        },
+        "report_time": "1643325573000",
+        "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution"
+     },
+     {
+      "payload": {
+         "attribution_destination": "https://destination.test",
+         "histograms": [ {
+            "key": "0x559",
+            "value": 789
+         } ]
+      },
+      "report_time": "1643325574000",
+      "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution"
+   }
+    ]
+  }
+}
diff --git a/device/BUILD.gn b/device/BUILD.gn
index 4911430..e42444e1 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -64,7 +64,6 @@
 
   if (is_mac) {
     sources += [
-      "bluetooth/bluetooth_adapter_mac_metrics_unittest.mm",
       "bluetooth/bluetooth_adapter_mac_unittest.mm",
       "bluetooth/bluetooth_low_energy_advertisement_manager_mac_unittest.mm",
       "bluetooth/test/bluetooth_test_mac.h",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 65317e8..0b526044 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -207,8 +207,6 @@
     sources += [
       "bluetooth_adapter_mac.h",
       "bluetooth_adapter_mac.mm",
-      "bluetooth_adapter_mac_metrics.h",
-      "bluetooth_adapter_mac_metrics.mm",
       "bluetooth_advertisement_mac.h",
       "bluetooth_advertisement_mac.mm",
       "bluetooth_channel_mac.h",
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 64499041..2b5ae4f 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -31,7 +31,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/device_event_log/device_event_log.h"
-#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
 #include "device/bluetooth/bluetooth_advertisement_mac.h"
 #include "device/bluetooth/bluetooth_classic_device_mac.h"
 #include "device/bluetooth/bluetooth_common.h"
@@ -857,7 +856,6 @@
     [low_energy_central_manager_ cancelPeripheralConnection:peripheral];
     return;
   }
-  RecordDidFailToConnectPeripheralResult(error);
   BluetoothDevice::ConnectErrorCode error_code =
       BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN;
   if (error) {
diff --git a/device/bluetooth/bluetooth_adapter_mac_metrics.h b/device/bluetooth/bluetooth_adapter_mac_metrics.h
deleted file mode 100644
index 4b64c64..0000000
--- a/device/bluetooth/bluetooth_adapter_mac_metrics.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_MAC_METRICS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_MAC_METRICS_H_
-
-@class NSError;
-
-enum class MacOSBluetoothOperationsResult : int {
-  UNKNOWN_ERROR_DOMAIN = -2,
-  NO_ERROR = -1,
-  CBATT_ERROR_SUCCESS = 0,
-  CBATT_ERROR_INVALID_HANDLE = 1,
-  CBATT_ERROR_READ_NOT_PERMITTED = 2,
-  CBATT_ERROR_WRITE_NOT_PERMITTED = 3,
-  CBATT_ERROR_INVALID_PDU = 4,
-  CBATT_ERROR_INSUFFICIENT_AUTHENTICATION = 5,
-  CBATT_ERROR_REQUEST_NOT_SUPPORTED = 6,
-  CBATT_ERROR_INVALID_OFFSET = 7,
-  CBATT_ERROR_INSUFFICIENT_AUTHORIZATION = 8,
-  CBATT_ERROR_PREPARE_QUEUE_FULL = 9,
-  CBATT_ERROR_ATTRIBUTE_NOT_FOUND = 10,
-  CBATT_ERROR_ATTRIBUTE_NOT_LONG = 11,
-  CBATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE = 12,
-  CBATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH = 13,
-  CBATT_ERROR_UNLIKELY_ERROR = 14,
-  CBATT_ERROR_INSUFFICIENT_ENCRYPTION = 15,
-  CBATT_ERROR_UNSUPPORTED_GROUP_TYPE = 16,
-  CBATT_ERROR_INSUFFICIENT_RESOURCES = 17,
-  CBATT_ERROR_UNKNOWN_ERROR_CODE = 999,
-  CBERROR_UNKNOWN = 1000,
-  CBERROR_INVALID_PARAMETERS = 1001,
-  CBERROR_INVALID_HANDLE = 1002,
-  CBERROR_NOT_CONNECTED = 1003,
-  CBERROR_OUT_OF_SPACE = 1004,
-  CBERROR_OPERATION_CANCELLED = 1005,
-  CBERROR_CONNECTION_TIMEOUT = 1006,
-  CBERROR_PERIPHERAL_DISCONNECTED = 1007,
-  CBERROR_UUID_NOT_ALLOWED = 1008,
-  CBERROR_ALREADY_ADVERTISING = 1009,
-  CBERROR_CONNECTION_FAILED = 1010,
-  CBERROR_CONNECTION_LIMIT_REACHED = 1011,
-  CBERROR_UNKNOWN_DEVICE = 1012,
-  CBERROR_UNKNOWN_ERROR_CODE = 1999,
-  MAX,
-};
-
-void RecordDidFailToConnectPeripheralResult(NSError* error);
-void RecordDidDisconnectPeripheralResult(NSError* error);
-void RecordDidDiscoverPrimaryServicesResult(NSError* error);
-void RecordDidDiscoverCharacteristicsResult(NSError* error);
-void RecordDidUpdateValueResult(NSError* error);
-void RecordDidWriteValueResult(NSError* error);
-void RecordDidUpdateNotificationStateResult(NSError* error);
-void RecordDidDiscoverDescriptorsResult(NSError* error);
-void RecordDidUpdateValueForDescriptorResult(NSError* error);
-void RecordDidWriteValueForDescriptorResult(NSError* error);
-
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_MAC_METRICS_H_
diff --git a/device/bluetooth/bluetooth_adapter_mac_metrics.mm b/device/bluetooth/bluetooth_adapter_mac_metrics.mm
deleted file mode 100644
index d4982af..0000000
--- a/device/bluetooth/bluetooth_adapter_mac_metrics.mm
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
-
-#import <CoreBluetooth/CoreBluetooth.h>
-#import <Foundation/Foundation.h>
-
-#include "base/mac/mac_util.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/notreached.h"
-
-namespace {
-
-MacOSBluetoothOperationsResult GetMacOSOperationResultFromNSError(
-    NSError* error) {
-  if (!error)
-    return MacOSBluetoothOperationsResult::NO_ERROR;
-  NSString* error_domain = [error domain];
-  NSInteger error_code = [error code];
-  if ([error_domain isEqualToString:CBErrorDomain]) {
-    switch (error_code) {
-      case CBErrorUnknown:
-        return MacOSBluetoothOperationsResult::CBERROR_UNKNOWN;
-      case CBErrorInvalidParameters:
-        return MacOSBluetoothOperationsResult::CBERROR_INVALID_PARAMETERS;
-      case CBErrorInvalidHandle:
-        return MacOSBluetoothOperationsResult::CBERROR_INVALID_HANDLE;
-      case CBErrorNotConnected:
-        return MacOSBluetoothOperationsResult::CBERROR_NOT_CONNECTED;
-      case CBErrorOutOfSpace:
-        return MacOSBluetoothOperationsResult::CBERROR_OUT_OF_SPACE;
-      case CBErrorOperationCancelled:
-        return MacOSBluetoothOperationsResult::CBERROR_OPERATION_CANCELLED;
-      case CBErrorConnectionTimeout:
-        return MacOSBluetoothOperationsResult::CBERROR_CONNECTION_TIMEOUT;
-      case CBErrorPeripheralDisconnected:
-        return MacOSBluetoothOperationsResult::CBERROR_PERIPHERAL_DISCONNECTED;
-      case CBErrorUUIDNotAllowed:
-        return MacOSBluetoothOperationsResult::CBERROR_UUID_NOT_ALLOWED;
-      case CBErrorAlreadyAdvertising:
-        return MacOSBluetoothOperationsResult::CBERROR_ALREADY_ADVERTISING;
-      case CBErrorConnectionFailed:
-        return MacOSBluetoothOperationsResult::CBERROR_CONNECTION_FAILED;
-      case CBErrorConnectionLimitReached:
-        return MacOSBluetoothOperationsResult::CBERROR_CONNECTION_LIMIT_REACHED;
-      case CBErrorUnknownDevice:
-        return MacOSBluetoothOperationsResult::CBERROR_UNKNOWN_DEVICE;
-      default:
-        NOTREACHED();
-    }
-    return MacOSBluetoothOperationsResult::CBATT_ERROR_UNKNOWN_ERROR_CODE;
-  } else if ([error_domain isEqualToString:CBATTErrorDomain]) {
-    switch (static_cast<CBATTError>(error_code)) {
-      case CBATTErrorSuccess:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_SUCCESS;
-      case CBATTErrorInvalidHandle:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_INVALID_HANDLE;
-      case CBATTErrorReadNotPermitted:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_READ_NOT_PERMITTED;
-      case CBATTErrorWriteNotPermitted:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_WRITE_NOT_PERMITTED;
-      case CBATTErrorInvalidPdu:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_INVALID_PDU;
-      case CBATTErrorInsufficientAuthentication:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INSUFFICIENT_AUTHENTICATION;
-      case CBATTErrorRequestNotSupported:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_REQUEST_NOT_SUPPORTED;
-      case CBATTErrorInvalidOffset:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_INVALID_OFFSET;
-      case CBATTErrorInsufficientAuthorization:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INSUFFICIENT_AUTHORIZATION;
-      case CBATTErrorPrepareQueueFull:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_PREPARE_QUEUE_FULL;
-      case CBATTErrorAttributeNotFound:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_ATTRIBUTE_NOT_FOUND;
-      case CBATTErrorAttributeNotLong:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_ATTRIBUTE_NOT_LONG;
-      case CBATTErrorInsufficientEncryptionKeySize:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE;
-      case CBATTErrorInvalidAttributeValueLength:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH;
-      case CBATTErrorUnlikelyError:
-        return MacOSBluetoothOperationsResult::CBATT_ERROR_UNLIKELY_ERROR;
-      case CBATTErrorInsufficientEncryption:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INSUFFICIENT_ENCRYPTION;
-      case CBATTErrorUnsupportedGroupType:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_UNSUPPORTED_GROUP_TYPE;
-      case CBATTErrorInsufficientResources:
-        return MacOSBluetoothOperationsResult::
-            CBATT_ERROR_INSUFFICIENT_RESOURCES;
-    }
-    return MacOSBluetoothOperationsResult::CBERROR_UNKNOWN_ERROR_CODE;
-  }
-  // TODO(crbug.com/755667): Needs to create an histogram to record unknown
-  // error domains.
-  return MacOSBluetoothOperationsResult::UNKNOWN_ERROR_DOMAIN;
-}
-
-}  // namespace
-
-void RecordDidFailToConnectPeripheralResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse(
-      "Bluetooth.MacOS.Errors.DidFailToConnectToPeripheral",
-      static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidDisconnectPeripheralResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidDisconnectPeripheral",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidDiscoverPrimaryServicesResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidDiscoverPrimaryServices",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidDiscoverCharacteristicsResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidDiscoverCharacteristics",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidUpdateValueResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidUpdateValue",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidWriteValueResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidWriteValue",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidUpdateNotificationStateResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidUpdateNotificationState",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidDiscoverDescriptorsResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidDiscoverDescriptors",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidUpdateValueForDescriptorResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidUpdateValueForDescriptor",
-                           static_cast<int>(histogram_macos_error));
-}
-
-void RecordDidWriteValueForDescriptorResult(NSError* error) {
-  MacOSBluetoothOperationsResult histogram_macos_error =
-      GetMacOSOperationResultFromNSError(error);
-  base::UmaHistogramSparse("Bluetooth.MacOS.Errors.DidWriteValueForDescriptor",
-                           static_cast<int>(histogram_macos_error));
-}
diff --git a/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm b/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm
deleted file mode 100644
index 5b7f2ee1..0000000
--- a/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm
+++ /dev/null
@@ -1,175 +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 "base/logging.h"
-#include "base/memory/raw_ptr.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "device/bluetooth/test/bluetooth_test_mac.h"
-
-namespace device {
-
-class BluetoothAdapterMacMetricsTest : public BluetoothTest {
- public:
-  void FakeDeviceBoilerPlate() {
-    if (!PlatformSupportsLowEnergy()) {
-      LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
-      return;
-    }
-    InitWithFakeAdapter();
-    StartLowEnergyDiscoverySession();
-    device_ = SimulateLowEnergyDevice(3);
-  }
-
-  void FakeServiceBoilerPlate() {
-    ASSERT_NO_FATAL_FAILURE(FakeDeviceBoilerPlate());
-
-    device_->CreateGattConnection(
-        GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
-    SimulateGattConnection(device_);
-    base::RunLoop().RunUntilIdle();
-    SimulateGattServicesDiscovered(
-        device_, std::vector<std::string>({kTestUUIDGenericAccess}));
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(1u, device_->GetGattServices().size());
-    service_ = device_->GetGattServices()[0];
-  }
-
-  void FakeCharacteristicBoilerplate(int property = 0) {
-    ASSERT_NO_FATAL_FAILURE(FakeServiceBoilerPlate());
-
-    SimulateGattCharacteristic(service_, kTestUUIDDeviceName, property);
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(1u, service_->GetCharacteristics().size());
-    characteristic_ = service_->GetCharacteristics()[0];
-  }
-
-  raw_ptr<BluetoothDevice> device_ = nullptr;
-  raw_ptr<BluetoothRemoteGattService> service_ = nullptr;
-  raw_ptr<BluetoothRemoteGattCharacteristic> characteristic_ = nullptr;
-};
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidFailToConnectToPeripheralError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeDeviceBoilerPlate());
-  SimulateGattConnectionError(device_, BluetoothDevice::ERROR_FAILED);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidFailToConnectToPeripheral", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidDisconnectPeripheral) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeDeviceBoilerPlate());
-  SimulateGattDisconnectionError(device_);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidDisconnectPeripheral", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidDiscoverPrimaryServicesError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeDeviceBoilerPlate());
-  SimulateGattConnection(device_);
-  SimulateDidDiscoverServicesMacWithError(device_);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidDiscoverPrimaryServices", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidDiscoverCharacteristicsError) {
-  ASSERT_NO_FATAL_FAILURE(FakeServiceBoilerPlate());
-  base::HistogramTester histogram_tester;
-  SimulateDidDiscoverCharacteristicsWithErrorMac(service_);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidDiscoverCharacteristics", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidUpdateValueError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
-
-  SimulateGattCharacteristicReadError(
-      characteristic_, BluetoothGattService::GattErrorCode::kFailed);
-  histogram_tester.ExpectTotalCount("Bluetooth.MacOS.Errors.DidUpdateValue", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidWriteValueError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
-
-  SimulateGattCharacteristicWriteError(
-      characteristic_, BluetoothGattService::GattErrorCode::kFailed);
-  histogram_tester.ExpectTotalCount("Bluetooth.MacOS.Errors.DidWriteValue", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidUpdateNotificationStateError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_NOTIFY));
-  SimulateGattDescriptor(
-      characteristic_,
-      BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid()
-          .canonical_value());
-  base::RunLoop().RunUntilIdle();
-  ASSERT_EQ(1u, characteristic_->GetDescriptors().size());
-  characteristic_->StartNotifySession(GetNotifyCallback(Call::NOT_EXPECTED),
-                                      GetGattErrorCallback(Call::EXPECTED));
-  ExpectedChangeNotifyValueAttempts(1);
-  ExpectedNotifyValue(NotifyValueState::NOTIFY);
-  SimulateGattNotifySessionStartError(
-      characteristic_, BluetoothGattService::GattErrorCode::kFailed);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidUpdateNotificationState", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidDiscoverDescriptorsError) {
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
-  base::HistogramTester histogram_tester;
-  SimulateDidDiscoverDescriptorsWithErrorMac(characteristic_);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidDiscoverDescriptors", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidUpdateValueForDescriptorError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
-  SimulateGattDescriptor(
-      characteristic_,
-      BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid()
-          .canonical_value());
-  EXPECT_EQ(1u, characteristic_->GetDescriptors().size());
-  BluetoothRemoteGattDescriptor* descriptor =
-      characteristic_->GetDescriptors()[0];
-  descriptor->ReadRemoteDescriptor(
-      GetReadValueCallback(Call::EXPECTED, Result::FAILURE));
-  SimulateGattDescriptorUpdateError(
-      descriptor, BluetoothGattService::GattErrorCode::kFailed);
-  base::RunLoop().RunUntilIdle();
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidUpdateValueForDescriptor", 1);
-}
-
-TEST_F(BluetoothAdapterMacMetricsTest, DidWriteValueForDescriptorError) {
-  base::HistogramTester histogram_tester;
-  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
-      BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
-  SimulateGattDescriptor(
-      characteristic_,
-      BluetoothRemoteGattDescriptor::ClientCharacteristicConfigurationUuid()
-          .canonical_value());
-  EXPECT_EQ(1u, characteristic_->GetDescriptors().size());
-  BluetoothRemoteGattDescriptor* descriptor =
-      characteristic_->GetDescriptors()[0];
-  std::vector<uint8_t> empty_vector;
-  descriptor->WriteRemoteDescriptor(empty_vector,
-                                    GetCallback(Call::NOT_EXPECTED),
-                                    GetGattErrorCallback(Call::EXPECTED));
-  SimulateGattDescriptorWriteError(
-      descriptor, BluetoothGattService::GattErrorCode::kFailed);
-  histogram_tester.ExpectTotalCount(
-      "Bluetooth.MacOS.Errors.DidWriteValueForDescriptor", 1);
-}
-
-}  // namespace device
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm
index 30758052..f869e6f 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.mm
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -15,7 +15,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/sys_string_conversions.h"
 #include "device/bluetooth/bluetooth_adapter_mac.h"
-#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
@@ -222,7 +221,6 @@
     discovery_pending_count_ = 0;
     return;
   }
-  RecordDidDiscoverPrimaryServicesResult(error);
   if (error) {
     // TODO(http://crbug.com/609320): Need to pass the error.
     // TODO(http://crbug.com/609844): Decide what to do if discover failed
@@ -269,7 +267,6 @@
 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics(
     CBService* cb_service,
     NSError* error) {
-  RecordDidDiscoverCharacteristicsResult(error);
   if (error) {
     // TODO(http://crbug.com/609320): Need to pass the error.
     // TODO(http://crbug.com/609844): Decide what to do if discover failed
@@ -349,7 +346,6 @@
 void BluetoothLowEnergyDeviceMac::DidDiscoverDescriptors(
     CBCharacteristic* cb_characteristic,
     NSError* error) {
-  RecordDidDiscoverDescriptorsResult(error);
   if (error) {
     // TODO(http://crbug.com/609320): Need to pass the error.
     // TODO(http://crbug.com/609844): Decide what to do if discover failed
@@ -511,7 +507,6 @@
 void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral(NSError* error) {
   connected_ = false;
   DVLOG(1) << *this << ": Disconnected from peripheral.";
-  RecordDidDisconnectPeripheralResult(error);
   if (error) {
     DVLOG(1) << *this
              << ": Bluetooth error: " << BluetoothAdapterMac::String(error);
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm
index e45cdb5b..aa072c8c 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm
@@ -10,7 +10,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "device/bluetooth/bluetooth_adapter_mac.h"
-#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
 #include "device/bluetooth/bluetooth_device_mac.h"
 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
@@ -271,7 +270,6 @@
   CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected);
   // This method is called when the characteristic is read and when a
   // notification is received.
-  RecordDidUpdateValueResult(error);
   if (HasPendingRead()) {
     ValueCallback read_callback =
         std::move(read_characteristic_value_callback_);
@@ -312,7 +310,6 @@
 }
 
 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) {
-  RecordDidWriteValueResult(error);
   // We could have called cancelPeripheralConnection, which causes
   // [CBPeripheral state] to be CBPeripheralStateDisconnected, before or during
   // a write without response callback so we flush all pending writes.
@@ -365,7 +362,6 @@
     DVLOG(1) << *this << ": No pending notification update for characteristic.";
     return;
   }
-  RecordDidUpdateNotificationStateResult(error);
   if (error) {
     BluetoothGattService::GattErrorCode error_code =
         BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
index 4f4a6539..f9dc4fe5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
@@ -9,7 +9,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #import "device/bluetooth/bluetooth_adapter_mac.h"
-#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
 #import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
 
 using base::mac::ObjCCast;
@@ -135,7 +134,6 @@
     DVLOG(1) << *this << ": Value updated, no read in progress.";
     return;
   }
-  RecordDidUpdateValueForDescriptorResult(error);
   if (error) {
     BluetoothGattService::GattErrorCode error_code =
         BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
@@ -160,7 +158,6 @@
   }
   std::pair<base::OnceClosure, ErrorCallback> callbacks;
   callbacks.swap(write_value_callbacks_);
-  RecordDidWriteValueForDescriptorResult(error);
   if (error) {
     BluetoothGattService::GattErrorCode error_code =
         BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
diff --git a/docs/security/faq.md b/docs/security/faq.md
index 58f19db..af93f95 100644
--- a/docs/security/faq.md
+++ b/docs/security/faq.md
@@ -514,12 +514,11 @@
 
 When the browser needs to show trustworthy information, such as the bubble
 resulting from a click on the lock icon, it does so by making the bubble overlap
-chrome. In the case of the lock bubble, it is a small triangular bump in the
-border of the bubble that overlays the chrome. This visual detail can't be
-imitated by the page itself since the page is confined to the viewport.
+chrome. This visual detail can't be imitated by the page itself since the page
+is confined to the viewport.
 
-<a name="TOC-Why-does-Chrome-show-a-green-lock-even-if-my-HTTPS-connection-is-being-proxied-"></a>
-### Why does Chrome show a green lock, even if my HTTPS connection is being proxied?
+<a name="TOC-Why-does-Chrome-show-a-lock-even-if-my-HTTPS-connection-is-being-proxied-"></a>
+### Why does Chrome show a lock, even if my HTTPS connection is being proxied?
 
 Some types of software intercept HTTPS connections. Examples include anti-virus
 software, corporate network monitoring tools, and school censorship software. In
@@ -559,13 +558,13 @@
 ### How does key pinning interact with local proxies and filters?
 
 To enable certificate chain validation, Chrome has access to two stores of trust
-anchors (i.e. certificates that are empowered as issuers). One trust anchor
-store is the system or public trust anchor store, and the other other is the
-local or private trust anchor store. The public store is provided as part of
-the operating system, and intended to authenticate public internet servers. The
-private store contains certificates installed by the user or the administrator
-of the client machine. Private intranet servers should authenticate themselves
-with certificates issued by a private trust anchor.
+anchors (i.e., certificates that are empowered as issuers). One trust anchor
+store is for authenticating public internet servers, and depending on the 
+version of Chrome being used and the platform it is running on, the
+[Chrome Root Store](https://chromium.googlesource.com/chromium/src/+/main/net/data/ssl/chrome_root_store/faq.md#what-is-the-chrome-root-store)
+might be in use. The private store contains certificates installed by the user
+or the administrator of the client machine. Private intranet servers should
+authenticate themselves with certificates issued by a private trust anchor.
 
 Chrome’s key pinning feature is a strong form of web site authentication that
 requires a web server’s certificate chain not only to be valid and to chain to a
@@ -580,9 +579,10 @@
 Chrome does not perform pin validation when the certificate chain chains up to a
 private trust anchor. A key result of this policy is that private trust anchors
 can be used to proxy (or
-[MITM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)) connections, even
-to pinned sites. “Data loss prevention” appliances, firewalls, content filters,
-and malware can use this feature to defeat the protections of key pinning.
+[MITM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)) connections,
+even to pinned sites. “Data loss prevention” appliances, firewalls, content
+filters, and malware can use this feature to defeat the protections of key
+pinning.
 
 We deem this acceptable because the proxy or MITM can only be effective if the
 client machine has already been configured to trust the proxy’s issuing
@@ -673,40 +673,40 @@
 <a name="TOC-What-s-the-story-with-certificate-revocation-"></a>
 ### What's the story with certificate revocation?
 
-Chrome's primary mechanism for checking the revocation status of HTTPS
-certificates is
-[CRLsets](https://dev.chromium.org/Home/chromium-security/crlsets).
+Chrome's primary mechanism for checking certificate revocation status is
+[CRLsets](https://dev.chromium.org/Home/chromium-security/crlsets). 
+Additionally, by default, [stapled Online Certificate Status Protocol (OCSP)
+responses](https://en.wikipedia.org/wiki/OCSP_stapling) are honored.
 
-Chrome also supports Online Certificate Status Protocol (OCSP). However, the
-effectiveness of OCSP is is essentially 0 unless the client fails hard (refuses
-to connect) if it cannot get a live, valid OCSP response. No browser has OCSP
-set to hard-fail by default, for good reasons explained by Adam Langley (see
-[https://www.imperialviolet.org/2014/04/29/revocationagain.html](https://www.imperialviolet.org/2014/04/29/revocationagain.html) and
-[https://www.imperialviolet.org/2014/04/19/revchecking.html](https://www.imperialviolet.org/2014/04/19/revchecking.html)).
+"Online" certificate revocation status checks using Certificate Revocation
+List (CRL) or OCSP URLs included in certificates are disabled by default. This
+is because unless a client, like Chrome, refuses to connect to a website if it
+cannot get a valid response, online checks offer limited security value. 
 
-Stapled OCSP with the Must Staple option (hard-fail if a valid OCSP response is
-not stapled to the certificate) is a much better solution to the revocation
-problem than non-stapled OCSP. CAs and browsers are working toward that solution
-(see the
-[Internet-Draft](https://tools.ietf.org/html/draft-hallambaker-tlssecuritypolicy-03)).
+Unfortunately, there are many widely-prevalent causes for why a client
+might be unable to get a valid certificate revocation status response to
+include:
+* timeouts (e.g., an OCSP responder is online but does not respond within an
+  acceptable time limit), 
+* availability issues (e.g., the OCSP responder is offline), 
+* invalid responses (e.g., a "stale" or malformed status response), and 
+* local network attacks misrouting traffic or blocking responses. 
 
-Additionally, non-stapled OCSP poses a privacy problem: in order to check the
-status of a certificate, the client must query an OCSP responder for the status
-of the certificate, thus exposing a user's HTTPS browsing history to the
-responder (a third party).
+Additional concern with OCSP checks are related to privacy. OCSP 
+requests reveal details of individuals' browsing history to the operator of the
+OCSP responder (i.e., a third party). These details can be exposed accidentally
+(e.g., via data breach of logs) or intentionally (e.g., via subpoena). Chrome
+used to perform revocation checks for Extended Validation certificates, but that
+behavior was disabled in 2022 for [privacy reasons](https://groups.google.com/a/mozilla.org/g/dev-security-policy/c/S6A14e_X-T0/m/T4WxWgajAAAJ).
 
-That said, you can use enterprise policies to [enable soft-fail
-OCSP](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnableOnlineRevocationChecks)
-and hard-fail OCSP for [local trust
-anchors](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=RequireOnlineRevocationChecksForLocalAnchors).
+For more discussion on challenges with certificate revocation status checking,
+explained by Adam Langley, see [https://www.imperialviolet.org/2014/04/29/revocationagain.html](https://www.imperialviolet.org/2014/04/29/revocationagain.html)
+and [https://www.imperialviolet.org/2014/04/19/revchecking.html](https://www.imperialviolet.org/2014/04/19/revchecking.html).
 
-Chrome performs online checking for [Extended
-Validation](https://cabforum.org/about-ev-ssl/) certificates if it does not
-already have a non-expired CRLSet entry covering the domain. If Chrome does not
-get a response, it simply downgrades the security indicator to Domain Validated.
-
-See also [Issue 361820](https://crbug.com/361820) for more discussion of the
-user-facing UX.
+The following enterprise policies can be used to change the default revocation
+checking behavior in Chrome, though these may be removed in the future:
+* [enable soft-fail OCSP](https://chromeenterprise.google/policies/#EnableOnlineRevocationChecks)
+* [hard-fail for local trust anchors](https://chromeenterprise.google/policies/#RequireOnlineRevocationChecksForLocalAnchors).
 
 ## Passwords & Local Data
 
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 7cc68648..f870bde2 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1795,6 +1795,8 @@
   AUTOTESTPRIVATE_GETLAUNCHERSSEARCHBOXSTATE = 1732,
   OS_DIAGNOSTICS_RUNSENSITIVESENSORROUTINE = 1733,
   OS_DIAGNOSTICS_RUNNVMESELFTESTROUTINE = 1734,
+  AUTOTESTPRIVATE_STARTFRAMECOUNTING = 1735,
+  AUTOTESTPRIVATE_STOPFRAMECOUNTING = 1736,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index f0a9441..80454b02 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -156,6 +156,8 @@
     "gles2_cmd_validation.h",
     "gles2_cmd_validation_autogen.h",
     "gles2_cmd_validation_implementation_autogen.h",
+    "gles2_external_framebuffer.cc",
+    "gles2_external_framebuffer.h",
     "gles2_query_manager.cc",
     "gles2_query_manager.h",
     "gpu_command_buffer_memory_tracker.cc",
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 187c57a..7ac1fc8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -61,6 +61,7 @@
 #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h"
 #include "gpu/command_buffer/service/gles2_cmd_srgb_converter.h"
 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
+#include "gpu/command_buffer/service/gles2_external_framebuffer.h"
 #include "gpu/command_buffer/service/gles2_query_manager.h"
 #include "gpu/command_buffer/service/gpu_fence_manager.h"
 #include "gpu/command_buffer/service/gpu_state_tracer.h"
@@ -673,6 +674,11 @@
   void ReleaseSurface() override;
   void TakeFrontBuffer(const Mailbox& mailbox) override;
   void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
+  void SetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                        int samples,
+                                        bool preserve,
+                                        bool needs_depth,
+                                        bool needs_stencil) override;
   bool ResizeOffscreenFramebuffer(const gfx::Size& size) override;
   bool MakeCurrent() override;
   gl::GLApi* api() const { return state_.api(); }
@@ -2571,6 +2577,8 @@
   std::unique_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
   std::unique_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
 
+  std::unique_ptr<GLES2ExternalFramebuffer> external_default_framebuffer_;
+
   // The format of the texture or renderbuffer backing the offscreen
   // framebuffer. Also the format of the texture backing the saved offscreen
   // framebuffer.
@@ -5285,6 +5293,11 @@
     iter->OnDecoderWillDestroy(have_context);
   abstract_textures_.clear();
 
+  if (external_default_framebuffer_) {
+    external_default_framebuffer_->Destroy(have_context);
+    external_default_framebuffer_.reset();
+  }
+
   ReleaseAllBackTextures(have_context);
   if (have_context) {
     if (copy_tex_image_blit_.get()) {
@@ -5509,6 +5522,24 @@
   surface_ = nullptr;
 }
 
+void GLES2DecoderImpl::SetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                                        int samples,
+                                                        bool preserve,
+                                                        bool needs_depth,
+                                                        bool needs_stencil) {
+  if (!external_default_framebuffer_) {
+    external_default_framebuffer_ = std::make_unique<GLES2ExternalFramebuffer>(
+        /*passthrough=*/false, *group_->feature_info(),
+        group_->shared_image_representation_factory());
+  }
+
+  if (!external_default_framebuffer_->AttachSharedImage(
+          mailbox, samples, preserve, needs_depth, needs_stencil)) {
+    return;
+  }
+  RestoreCurrentFramebufferBindings();
+}
+
 void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) {
   if (offscreen_single_buffer_) {
     mailbox_manager()->ProduceTexture(
@@ -6220,6 +6251,10 @@
 }
 
 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
+  if (external_default_framebuffer_ &&
+      external_default_framebuffer_->IsSharedImageAttached())
+    return external_default_framebuffer_->GetFramebufferId();
+
   return (offscreen_target_frame_buffer_.get())
              ? offscreen_target_frame_buffer_->id()
              : (surface_.get() ? surface_->GetBackingFramebufferObject() : 0);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index dc7f727..980808b9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -159,6 +159,14 @@
   virtual void TakeFrontBuffer(const Mailbox& mailbox) = 0;
   virtual void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) = 0;
 
+  // This is intended only for use with NaCL swapchain, replacing
+  // TakeFrontBuffer/ReturnFrontBuffer flow.
+  virtual void SetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                                int samples,
+                                                bool preserve,
+                                                bool needs_depth,
+                                                bool needs_stencil) = 0;
+
   // Resize an offscreen frame buffer.
   virtual bool ResizeOffscreenFramebuffer(const gfx::Size& size) = 0;
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index ed334b7..2dbe588 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -58,6 +58,12 @@
   MOCK_METHOD0(ReleaseSurface, void());
   MOCK_METHOD1(TakeFrontBuffer, void(const Mailbox& mailbox));
   MOCK_METHOD2(ReturnFrontBuffer, void(const Mailbox& mailbox, bool is_lost));
+  MOCK_METHOD5(SetDefaultFramebufferSharedImage,
+               void(const Mailbox& mailbox,
+                    int samples,
+                    bool preserve,
+                    bool needs_depth,
+                    bool needs_stencil));
   MOCK_METHOD0(GetSavedBackTextureCountForTest, size_t());
   MOCK_METHOD0(GetCreatedBackTextureCountForTest, size_t());
   MOCK_METHOD1(ResizeOffscreenFramebuffer, bool(const gfx::Size& size));
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 424437c9..447f106 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -18,6 +18,7 @@
 #include "gpu/command_buffer/service/decoder_client.h"
 #include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/command_buffer/service/gles2_external_framebuffer.h"
 #include "gpu/command_buffer/service/gpu_fence_manager.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
 #include "gpu/command_buffer/service/image_factory.h"
@@ -804,7 +805,6 @@
       emulated_back_buffer_(nullptr),
       offscreen_single_buffer_(false),
       offscreen_target_buffer_preserved_(false),
-      create_color_buffer_count_for_test_(0),
       bound_draw_framebuffer_(0),
       bound_read_framebuffer_(0),
       gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
@@ -1382,6 +1382,11 @@
     emulated_front_buffer_.reset();
   }
 
+  if (external_default_framebuffer_) {
+    external_default_framebuffer_->Destroy(have_context);
+    external_default_framebuffer_.reset();
+  }
+
   for (auto& in_use_color_texture : in_use_color_textures_) {
     in_use_color_texture->Destroy(have_context);
   }
@@ -1462,6 +1467,61 @@
   surface_ = nullptr;
 }
 
+void GLES2DecoderPassthroughImpl::SetDefaultFramebufferSharedImage(
+    const Mailbox& mailbox,
+    int samples,
+    bool preserve,
+    bool needs_depth,
+    bool needs_stencil) {
+  if (!offscreen_)
+    return;
+
+  if (!external_default_framebuffer_) {
+    external_default_framebuffer_ = std::make_unique<GLES2ExternalFramebuffer>(
+        /*passthrough=*/true, *group_->feature_info(),
+        group_->shared_image_representation_factory());
+  }
+
+  if (!external_default_framebuffer_->AttachSharedImage(
+          mailbox, samples, preserve, needs_depth, needs_stencil)) {
+    return;
+  }
+
+  GLuint default_framebuffer_id;
+  if (external_default_framebuffer_->IsSharedImageAttached()) {
+    default_framebuffer_id = external_default_framebuffer_->GetFramebufferId();
+  } else {
+    default_framebuffer_id = emulated_back_buffer_->framebuffer_service_id;
+  }
+
+  framebuffer_id_map_.RemoveClientID(0);
+  framebuffer_id_map_.SetIDMapping(0, default_framebuffer_id);
+
+  // Note, there is member variable `supports_separate_fbo_bindings_` that is
+  // used across this class, but it's never initialized with the real value
+  // (defaults to false) which is likely a bug. To avoid any code changes
+  // outside of the feature flag we don't use it here.
+  const bool supports_separate_fbo_bindings =
+      feature_info_->feature_flags().chromium_framebuffer_multisample ||
+      feature_info_->IsWebGL2OrES3Context();
+
+  if (supports_separate_fbo_bindings) {
+    if (bound_draw_framebuffer_ == 0) {
+      api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER,
+                                    default_framebuffer_id);
+    }
+    if (bound_read_framebuffer_ == 0) {
+      api()->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER,
+                                    default_framebuffer_id);
+    }
+  } else {
+    DCHECK_EQ(bound_draw_framebuffer_, bound_read_framebuffer_);
+    if (bound_draw_framebuffer_ == 0) {
+      api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, default_framebuffer_id);
+    }
+  }
+}
+
 void GLES2DecoderPassthroughImpl::TakeFrontBuffer(const Mailbox& mailbox) {
   if (offscreen_single_buffer_) {
     DCHECK(emulated_back_buffer_->color_texture != nullptr);
@@ -2989,7 +3049,7 @@
 
 bool GLES2DecoderPassthroughImpl::IsEmulatedFramebufferBound(
     GLenum target) const {
-  if (!emulated_back_buffer_) {
+  if (!emulated_back_buffer_ && !external_default_framebuffer_) {
     return false;
   }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index e46b8ae..dec68505 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -51,6 +51,7 @@
 class GPUTracer;
 class MultiDrawManager;
 class PassthroughAbstractTextureImpl;
+class GLES2ExternalFramebuffer;
 
 struct MappedBuffer {
   GLsizeiptr size;
@@ -188,6 +189,12 @@
 
   void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
 
+  void SetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                        int samples,
+                                        bool preserve,
+                                        bool needs_depth,
+                                        bool needs_stencil) override;
+
   // Resize an offscreen frame buffer.
   bool ResizeOffscreenFramebuffer(const gfx::Size& size) override;
 
@@ -851,7 +858,8 @@
   bool offscreen_target_buffer_preserved_;
   std::vector<std::unique_ptr<EmulatedColorBuffer>> in_use_color_textures_;
   std::vector<std::unique_ptr<EmulatedColorBuffer>> available_color_textures_;
-  size_t create_color_buffer_count_for_test_;
+  size_t create_color_buffer_count_for_test_ = 0;
+  std::unique_ptr<GLES2ExternalFramebuffer> external_default_framebuffer_;
 
   // Maximum 2D resource sizes for limiting offscreen framebuffer sizes
   GLint max_renderbuffer_size_ = 0;
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer.cc b/gpu/command_buffer/service/gles2_external_framebuffer.cc
new file mode 100644
index 0000000..8aa459a1
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_external_framebuffer.cc
@@ -0,0 +1,563 @@
+// 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 "gpu/command_buffer/service/gles2_external_framebuffer.h"
+
+#include "gpu/command_buffer/service/feature_info.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gl/scoped_binders.h"
+#include "ui/gl/scoped_restore_texture.h"
+
+namespace gpu::gles2 {
+namespace {
+class ScopedRestoreRenderbuffer {
+ public:
+  explicit ScopedRestoreRenderbuffer(gl::GLApi* api) : api_(api) {
+    api_->glGetIntegervFn(GL_RENDERBUFFER_BINDING, &renderbuffer_);
+  }
+
+  ~ScopedRestoreRenderbuffer() {
+    api_->glBindRenderbufferEXTFn(GL_RENDERBUFFER, renderbuffer_);
+  }
+
+ private:
+  const raw_ptr<gl::GLApi> api_;
+  GLint renderbuffer_ = 0;
+};
+
+class ScopedRestoreWindowRectangles {
+ public:
+  explicit ScopedRestoreWindowRectangles(gl::GLApi* api) : api_(api) {
+    api_->glGetIntegervFn(GL_WINDOW_RECTANGLE_MODE_EXT, &mode_);
+
+    GLint num_windows = 0;
+    api_->glGetIntegervFn(GL_NUM_WINDOW_RECTANGLES_EXT, &num_windows);
+
+    windows_.resize(4 * num_windows);
+    for (int i = 0; i < num_windows; ++i) {
+      glGetIntegeri_v(GL_WINDOW_RECTANGLE_EXT, i, &windows_[i * 4]);
+    }
+  }
+
+  ~ScopedRestoreWindowRectangles() {
+    api_->glWindowRectanglesEXTFn(mode_, windows_.size() / 4, windows_.data());
+  }
+
+ private:
+  const raw_ptr<gl::GLApi> api_;
+  GLint mode_ = GL_EXCLUSIVE_EXT;
+  std::vector<GLint> windows_;
+};
+
+class ScopedRestoreWriteMasks {
+ public:
+  explicit ScopedRestoreWriteMasks(gl::GLApi* api) : api_(api) {
+    api_->glGetIntegervFn(GL_STENCIL_WRITEMASK, &stencil_front_mask_);
+    api_->glGetIntegervFn(GL_STENCIL_BACK_WRITEMASK, &stencil_back_mask_);
+    api_->glGetBooleanvFn(GL_DEPTH_WRITEMASK, &depth_mask_);
+    api_->glGetBooleanvFn(GL_COLOR_WRITEMASK, color_mask_);
+  }
+
+  ~ScopedRestoreWriteMasks() {
+    api_->glColorMaskFn(color_mask_[0], color_mask_[1], color_mask_[2],
+                        color_mask_[3]);
+    api_->glDepthMaskFn(depth_mask_);
+    api_->glStencilMaskSeparateFn(GL_FRONT, stencil_front_mask_);
+    api_->glStencilMaskSeparateFn(GL_BACK, stencil_back_mask_);
+  }
+
+ private:
+  const raw_ptr<gl::GLApi> api_;
+  GLboolean color_mask_[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
+  GLboolean depth_mask_ = GL_TRUE;
+  GLint stencil_front_mask_ = 0xFF;
+  GLint stencil_back_mask_ = 0xFF;
+};
+
+class ScopedRestoreClearValues {
+ public:
+  explicit ScopedRestoreClearValues(gl::GLApi* api) : api_(api) {
+    api_->glGetFloatvFn(GL_COLOR_CLEAR_VALUE, clear_color_);
+    api_->glGetFloatvFn(GL_DEPTH_CLEAR_VALUE, &clear_depth_);
+    api_->glGetIntegervFn(GL_STENCIL_CLEAR_VALUE, &clear_stencil_);
+  }
+  ~ScopedRestoreClearValues() {
+    api_->glClearColorFn(clear_color_[0], clear_color_[1], clear_color_[2],
+                         clear_color_[3]);
+    api_->glClearDepthFn(clear_depth_);
+    api_->glClearStencilFn(clear_stencil_);
+  }
+
+ private:
+  const raw_ptr<gl::GLApi> api_;
+  GLfloat clear_color_[4] = {};
+  GLfloat clear_depth_ = 0.0f;
+  GLint clear_stencil_ = 0;
+};
+
+class ScopedRestoreFramebuffer {
+ public:
+  ScopedRestoreFramebuffer(gl::GLApi* api, bool supports_separate_fbo_bindings)
+      : api_(api),
+        supports_separate_fbo_bindings_(supports_separate_fbo_bindings) {
+    if (supports_separate_fbo_bindings_) {
+      api_->glGetIntegervFn(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer_);
+      api_->glGetIntegervFn(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer_);
+    } else {
+      api_->glGetIntegervFn(GL_FRAMEBUFFER_BINDING, &draw_framebuffer_);
+    }
+  }
+
+  ~ScopedRestoreFramebuffer() {
+    if (supports_separate_fbo_bindings_) {
+      api_->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, draw_framebuffer_);
+      api_->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER, read_framebuffer_);
+    } else {
+      api_->glBindFramebufferEXTFn(GL_FRAMEBUFFER, draw_framebuffer_);
+    }
+  }
+
+ private:
+  const raw_ptr<gl::GLApi> api_;
+  const bool supports_separate_fbo_bindings_;
+  GLint draw_framebuffer_ = 0;
+  GLint read_framebuffer_ = 0;
+};
+}  // namespace
+
+class GLES2ExternalFramebuffer::Attachment {
+ public:
+  static std::unique_ptr<Attachment> CreateTexture(const gfx::Size& size,
+                                                   GLenum format) {
+    gl::GLApi* const api = gl::g_current_gl_context;
+    gl::ScopedRestoreTexture scoped_restore(api, GL_TEXTURE_2D);
+
+    // Don't use sized formats for textures
+    GLenum texture_format;
+    switch (format) {
+      case GL_RGBA8:
+        texture_format = GL_RGBA;
+        break;
+      case GL_RGB8:
+        texture_format = GL_RGB;
+        break;
+      default:
+        texture_format = GL_RGBA;
+        NOTREACHED();
+    }
+
+    GLuint texture;
+    api->glGenTexturesFn(1, &texture);
+    api->glBindTextureFn(GL_TEXTURE_2D, texture);
+    api->glTexImage2DFn(GL_TEXTURE_2D, 0, texture_format, size.width(),
+                        size.height(), 0, texture_format, GL_UNSIGNED_BYTE,
+                        nullptr);
+
+    return std::make_unique<Attachment>(size, /*samples_count=*/0, format,
+                                        /*texture=*/texture,
+                                        /*renderbuffer=*/0);
+  }
+
+  static std::unique_ptr<Attachment> CreateRenderbuffer(const gfx::Size& size,
+                                                        int samples_count,
+                                                        GLenum format) {
+    gl::GLApi* const api = gl::g_current_gl_context;
+    ScopedRestoreRenderbuffer rb_restore(api);
+
+    GLuint renderbuffer;
+    api->glGenRenderbuffersEXTFn(1, &renderbuffer);
+    api->glBindRenderbufferEXTFn(GL_RENDERBUFFER, renderbuffer);
+
+    if (samples_count > 0) {
+      api->glRenderbufferStorageMultisampleFn(
+          GL_RENDERBUFFER, samples_count, format, size.width(), size.height());
+    } else {
+      api->glRenderbufferStorageEXTFn(GL_RENDERBUFFER, format, size.width(),
+                                      size.height());
+    }
+
+    return std::make_unique<Attachment>(size, samples_count, format,
+                                        /*texture=*/0,
+                                        /*renderbuffer=*/renderbuffer);
+  }
+
+  Attachment(const gfx::Size& size,
+             int samples_count,
+             GLenum format,
+             GLuint texture,
+             GLuint renderbuffer)
+      : size_(size),
+        samples_count_(samples_count),
+        format_(format),
+        texture_(texture),
+        renderbuffer_(renderbuffer) {
+    DCHECK_NE(!!texture, !!renderbuffer);
+    DCHECK(!size.IsEmpty());
+    DCHECK(format);
+  }
+
+  Attachment(const Attachment&) = delete;
+  Attachment(Attachment&&) = delete;
+
+  Attachment& operator=(const Attachment&) = delete;
+  Attachment& operator=(Attachment&&) = delete;
+
+  ~Attachment() {
+    // No need to do anything if context was lost.
+    if (context_lost_)
+      return;
+
+    DCHECK_EQ(attach_point_, 0u);
+    if (texture_)
+      glDeleteTextures(1, &texture_);
+    else if (renderbuffer_)
+      glDeleteRenderbuffersEXT(1, &renderbuffer_);
+  }
+
+  void Attach(GLenum attachment) {
+    DCHECK_EQ(attach_point_, 0u);
+    attach_point_ = attachment;
+
+    if (texture_)
+      AttachImpl(attach_point_, /*is_texture=*/true, texture_);
+    else
+      AttachImpl(attach_point_, /*is_texture=*/false, renderbuffer_);
+  }
+
+  void Detach() {
+    DCHECK_NE(attach_point_, 0u);
+
+    if (texture_)
+      AttachImpl(attach_point_, /*is_texture=*/true, 0);
+    else
+      AttachImpl(attach_point_, /*is_texture=*/false, 0);
+    attach_point_ = 0;
+  }
+
+  bool NeedsResolve() { return samples_count_ > 0; }
+
+  bool Compatible(const gfx::Size size, int samples_count, GLenum format) {
+    return size_ == size && samples_count_ == samples_count &&
+           format_ == format;
+  }
+
+  void OnContextLost() { context_lost_ = true; }
+
+ private:
+  void AttachImpl(GLenum attachment, bool is_texture, GLuint object) {
+    if (is_texture) {
+      glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                GL_TEXTURE_2D, object, 0);
+    } else {
+      if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                     GL_RENDERBUFFER, object);
+        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                     GL_RENDERBUFFER, object);
+      } else {
+        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, attachment,
+                                     GL_RENDERBUFFER, object);
+      }
+    }
+  }
+
+  GLenum attach_point_ = 0;
+  bool context_lost_ = false;
+
+  const gfx::Size size_;
+  const int samples_count_;
+  const GLenum format_;
+  const GLuint texture_;
+  const GLuint renderbuffer_;
+};
+
+GLES2ExternalFramebuffer::GLES2ExternalFramebuffer(
+    bool passthrough,
+    const FeatureInfo& feature_info,
+    SharedImageRepresentationFactory* shared_image_representation_factory)
+    : passthrough_(passthrough),
+      shared_image_representation_factory_(
+          shared_image_representation_factory) {
+  const bool multisampled_framebuffers_supported =
+      feature_info.feature_flags().chromium_framebuffer_multisample;
+  const bool rgb8_supported = feature_info.feature_flags().oes_rgb8_rgba8;
+  // The only available default render buffer formats in GLES2 have very
+  // little precision.  Don't enable multisampling unless 8-bit render
+  // buffer formats are available--instead fall back to 8-bit textures.
+
+  if (multisampled_framebuffers_supported && rgb8_supported) {
+    glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count_);
+  }
+
+  packed_depth_stencil_ = feature_info.feature_flags().packed_depth24_stencil8;
+  supports_separate_fbo_bindings_ = multisampled_framebuffers_supported ||
+                                    feature_info.IsWebGL2OrES3Context();
+  supports_window_rectangles_ =
+      feature_info.feature_flags().ext_window_rectangles;
+
+  glGenFramebuffersEXT(1, &fbo_);
+}
+
+GLES2ExternalFramebuffer::~GLES2ExternalFramebuffer() {
+  DCHECK_EQ(fbo_, 0u);
+  DCHECK(attachments_.empty());
+}
+
+void GLES2ExternalFramebuffer::Destroy(bool have_context) {
+  if (!have_context) {
+    for (auto& attachment : attachments_)
+      attachment.second->OnContextLost();
+
+    if (shared_image_representation_)
+      shared_image_representation_->OnContextLost();
+  } else {
+    gl::GLApi* const api = gl::g_current_gl_context;
+    ScopedRestoreFramebuffer scoped_fbo_reset(api,
+                                              supports_separate_fbo_bindings_);
+    api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo_);
+    for (auto& attachment : attachments_)
+      attachment.second->Detach();
+  }
+
+  scoped_access_.reset();
+  shared_image_representation_.reset();
+
+  attachments_.clear();
+
+  if (have_context)
+    glDeleteFramebuffersEXT(1, &fbo_);
+  fbo_ = 0;
+}
+
+bool GLES2ExternalFramebuffer::AttachSharedImage(const Mailbox& mailbox,
+                                                 int samples,
+                                                 bool preserve,
+                                                 bool need_depth,
+                                                 bool need_stencil) {
+  ResolveAndDetach();
+
+  if (mailbox.IsZero())
+    return true;
+
+  if (passthrough_) {
+    shared_image_representation_ =
+        shared_image_representation_factory_->ProduceGLTexturePassthrough(
+            mailbox);
+  } else {
+    shared_image_representation_ =
+        shared_image_representation_factory_->ProduceGLTexture(mailbox);
+  }
+
+  if (!shared_image_representation_) {
+    LOG(ERROR) << "Can't produce representation";
+    return false;
+  }
+
+  if (!shared_image_representation_->format().is_single_plane() ||
+      (shared_image_representation_->format().resource_format() !=
+           viz::ResourceFormat::RGBA_8888 &&
+       shared_image_representation_->format().resource_format() !=
+           viz::ResourceFormat::RGBX_8888)) {
+    LOG(ERROR) << "Unsupported format";
+    return false;
+  }
+
+  scoped_access_ = shared_image_representation_->BeginScopedAccess(
+      GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM,
+      GLTextureImageRepresentationBase::AllowUnclearedAccess::kYes);
+
+  if (!scoped_access_) {
+    LOG(ERROR) << "Can't BeginAccess";
+    return false;
+  }
+
+  samples = std::min(samples, max_sample_count_);
+  const bool can_attach_directly = !samples && !preserve;
+
+  GLenum clear_flags = 0;
+  const auto& size = shared_image_representation_->size();
+
+  gl::GLApi* const api = gl::g_current_gl_context;
+  ScopedRestoreFramebuffer scoped_fbo_reset(api,
+                                            supports_separate_fbo_bindings_);
+  api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo_);
+
+  if (can_attach_directly) {
+    glFramebufferTexture2DEXT(
+        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+        shared_image_representation_->GetTextureBase()->service_id(), 0);
+    if (!shared_image_representation_->IsCleared())
+      clear_flags |= GL_COLOR_BUFFER_BIT;
+  } else {
+    const bool has_alpha = shared_image_representation_->format() ==
+                           viz::SharedImageFormat::kRGBA_8888;
+    if (UpdateAttachment(GL_COLOR_ATTACHMENT0, size, samples,
+                         has_alpha ? GL_RGBA8 : GL_RGB8)) {
+      clear_flags |= GL_COLOR_BUFFER_BIT;
+    }
+  }
+
+  // If GL_DEPTH24_STENCIL8 is supported, we prefer it.
+  if (packed_depth_stencil_) {
+    if (UpdateAttachment(
+            GL_DEPTH_STENCIL_ATTACHMENT, size, samples,
+            (need_depth || need_stencil) ? GL_DEPTH24_STENCIL8 : GL_NONE)) {
+      clear_flags |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
+    }
+  } else {
+    if (UpdateAttachment(GL_DEPTH_ATTACHMENT, size, samples,
+                         need_depth ? GL_DEPTH_COMPONENT16 : GL_NONE)) {
+      clear_flags |= GL_DEPTH_BUFFER_BIT;
+    }
+    if (UpdateAttachment(GL_STENCIL_ATTACHMENT, size, samples,
+                         need_stencil ? GL_STENCIL_INDEX8 : GL_NONE)) {
+      clear_flags |= GL_STENCIL_BUFFER_BIT;
+    }
+  }
+
+  GLenum status = api->glCheckFramebufferStatusEXTFn(GL_FRAMEBUFFER);
+  LOG_IF(DFATAL, status != GL_FRAMEBUFFER_COMPLETE)
+      << "Framebuffer incomplete: " << status;
+
+  if (clear_flags) {
+    gl::ScopedCapability scoped_scissor(GL_SCISSOR_TEST, GL_FALSE);
+
+    absl::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
+    if (supports_window_rectangles_) {
+      window_rectangles_restore.emplace(api);
+      api->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
+    }
+
+    ScopedRestoreWriteMasks write_mask_restore(api);
+    api->glColorMaskFn(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    api->glDepthMaskFn(GL_TRUE);
+    api->glStencilMaskSeparateFn(GL_FRONT, 0xFF);
+    api->glStencilMaskSeparateFn(GL_BACK, 0xFF);
+
+    ScopedRestoreClearValues clear_values_restore(api);
+    api->glClearColorFn(0, 0, 0, 0);
+    api->glClearDepthFn(0.0f);
+    api->glClearStencilFn(0);
+
+    api->glClearFn(clear_flags);
+
+    // If we attached SharedImage directly and did clear color attachment, mark
+    // it as cleared.
+    if (attachments_.find(GL_COLOR_ATTACHMENT0) == attachments_.end() &&
+        (clear_flags & GL_COLOR_BUFFER_BIT))
+      shared_image_representation_->SetCleared();
+  }
+
+  return true;
+}
+
+bool GLES2ExternalFramebuffer::UpdateAttachment(GLenum attachment,
+                                                const gfx::Size& size,
+                                                int samples,
+                                                GLenum format) {
+  if (auto old_attachment = attachments_.find(attachment);
+      old_attachment != attachments_.end()) {
+    if (old_attachment->second->Compatible(size, samples, format))
+      return false;
+    old_attachment->second->Detach();
+    attachments_.erase(attachment);
+  }
+
+  if (format) {
+    attachments_[attachment] =
+        CreateAttachment(attachment, size, samples, format);
+    attachments_[attachment]->Attach(attachment);
+    return true;
+  }
+  return false;
+}
+
+std::unique_ptr<GLES2ExternalFramebuffer::Attachment>
+GLES2ExternalFramebuffer::CreateAttachment(GLenum attachment,
+                                           const gfx::Size& size,
+                                           int samples,
+                                           GLenum format) {
+  if (attachment == GL_COLOR_ATTACHMENT0 && samples == 0) {
+    return Attachment::CreateTexture(size, format);
+  }
+
+  return Attachment::CreateRenderbuffer(size, samples, format);
+}
+
+void GLES2ExternalFramebuffer::ResolveAndDetach() {
+  if (!scoped_access_) {
+    DCHECK(!shared_image_representation_);
+    return;
+  }
+
+  gl::GLApi* const api = gl::g_current_gl_context;
+  ScopedRestoreFramebuffer scoped_fbo_reset(api,
+                                            supports_separate_fbo_bindings_);
+
+  if (auto color_attachment = attachments_.find(GL_COLOR_ATTACHMENT0);
+      color_attachment != attachments_.end()) {
+    const auto& size = shared_image_representation_->size();
+
+    // If we have separate attachment, we need to blit/resolve it to shared
+    // image.
+    if (color_attachment->second->NeedsResolve()) {
+      DCHECK(supports_separate_fbo_bindings_);
+
+      gl::ScopedCapability scoped_scissor(GL_SCISSOR_TEST, GL_FALSE);
+      ScopedRestoreWriteMasks write_mask_restore(api);
+      api->glColorMaskFn(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+      absl::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
+      if (supports_window_rectangles_) {
+        window_rectangles_restore.emplace(api);
+        api->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
+      }
+
+      api->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER, fbo_);
+
+      GLuint temp_fbo;
+      api->glGenFramebuffersEXTFn(1, &temp_fbo);
+      api->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, temp_fbo);
+      api->glFramebufferTexture2DEXTFn(
+          GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+          shared_image_representation_->GetTextureBase()->service_id(), 0);
+
+      api->glBlitFramebufferFn(0, 0, size.width(), size.height(), 0, 0,
+                               size.width(), size.height(), GL_COLOR_BUFFER_BIT,
+                               GL_NEAREST);
+
+      api->glDeleteFramebuffersEXTFn(1, &temp_fbo);
+    } else {
+      api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo_);
+      gl::ScopedRestoreTexture texture(api, GL_TEXTURE_2D);
+      api->glBindTextureFn(
+          GL_TEXTURE_2D,
+          shared_image_representation_->GetTextureBase()->service_id());
+
+      api->glCopyTexSubImage2DFn(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.width(),
+                                 size.height());
+    }
+    // We did resolved to SharedImage, so we can mark it as cleared here.
+    shared_image_representation_->SetCleared();
+  } else {
+    // Detach color attachment if we were attached directly.
+    api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo_);
+    api->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                     GL_TEXTURE_2D, 0, 0);
+  }
+  scoped_access_.reset();
+  shared_image_representation_.reset();
+}
+
+GLuint GLES2ExternalFramebuffer::GetFramebufferId() {
+  return fbo_;
+}
+
+bool GLES2ExternalFramebuffer::IsSharedImageAttached() {
+  return !!scoped_access_;
+}
+
+}  // namespace gpu::gles2
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer.h b/gpu/command_buffer/service/gles2_external_framebuffer.h
new file mode 100644
index 0000000..bf59100
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_external_framebuffer.h
@@ -0,0 +1,86 @@
+// 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 GPU_COMMAND_BUFFER_SERVICE_GLES2_EXTERNAL_FRAMEBUFFER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GLES2_EXTERNAL_FRAMEBUFFER_H_
+
+#include <memory>
+
+#include "base/containers/flat_map.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/gpu_gles2_export.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace gpu {
+class SharedImageRepresentationFactory;
+}
+
+namespace gpu::gles2 {
+class FeatureInfo;
+
+// Encapsulates FrameBuffer Object and corresponding attachments for use as
+// default framebuffer from command decoders. Only user of default emulated
+// framebuffer is NaCL and hopefully will be deleted at some point.
+class GPU_GLES2_EXPORT GLES2ExternalFramebuffer {
+ public:
+  GLES2ExternalFramebuffer(
+      bool passthrough,
+      const FeatureInfo& feature_info,
+      SharedImageRepresentationFactory* shared_image_representation_factory);
+  ~GLES2ExternalFramebuffer();
+
+  // Attaches new SharedImage (if mailbox is not zero) to the framebuffer and
+  // resolves and detaches previously attached image if any.
+  bool AttachSharedImage(const Mailbox& mailbox,
+                         int samples_count,
+                         bool preserve,
+                         bool need_depth,
+                         bool need_stencil);
+
+  // If the framebuffer is multisampled, resolves the framebuffer into current
+  // SharedImage. If we preserve contents, blits preserved buffer to the shared
+  // image. Detaches shared image from the framebuffer.
+  void ResolveAndDetach();
+
+  GLuint GetFramebufferId();
+  bool IsSharedImageAttached();
+  void Destroy(bool have_context);
+
+ private:
+  class Attachment;
+
+  bool UpdateAttachment(GLenum attachment,
+                        const gfx::Size& size,
+                        int samples,
+                        GLenum format);
+  std::unique_ptr<Attachment> CreateAttachment(GLenum attachment,
+                                               const gfx::Size& size,
+                                               int samples,
+                                               GLenum format);
+
+  // Caps
+  const bool passthrough_;
+  GLint max_sample_count_ = 0;
+  bool packed_depth_stencil_ = false;
+  bool supports_separate_fbo_bindings_ = false;
+  bool supports_window_rectangles_ = false;
+
+  // Main frame buffer
+  GLuint fbo_ = 0;
+
+  base::flat_map<GLenum, std::unique_ptr<Attachment>> attachments_;
+
+  const raw_ptr<SharedImageRepresentationFactory>
+      shared_image_representation_factory_;
+
+  std::unique_ptr<GLTextureImageRepresentationBase>
+      shared_image_representation_;
+  std::unique_ptr<GLTextureImageRepresentationBase::ScopedAccess>
+      scoped_access_;
+};
+
+}  // namespace gpu::gles2
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_EXTERNAL_FRAMEBUFFER_H_
diff --git a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
index d8e55a2..5c42f3d 100644
--- a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
@@ -603,7 +603,7 @@
     bool is_thread_safe,
     base::span<const uint8_t> pixel_data) {
   DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable());
-  DCHECK(!viz::IsResourceFormatCompressed(format));
+  DCHECK(!format.IsCompressed());
 
   if (!ValidateUsage(usage, size, format)) {
     return nullptr;
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
index 34a51b6..b6b0d73 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -198,7 +198,7 @@
   if (usage() & kUsageNeedsColorAttachment) {
     vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
-    if (viz::IsResourceFormatCompressed(format())) {
+    if (format().IsCompressed()) {
       DLOG(ERROR) << "ETC1 format cannot be used as color attachment.";
       return false;
     }
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
index 9443eb6..49ca9f8 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
@@ -234,6 +234,7 @@
   dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
   DCHECK(dxgi_factory);
 
+  auto si_format = viz::SharedImageFormat::SinglePlane(format);
   DXGI_SWAP_CHAIN_DESC1 desc = {};
   desc.Width = size.width();
   desc.Height = size.height();
@@ -245,8 +246,8 @@
   desc.Scaling = DXGI_SCALING_STRETCH;
   desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
   desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
-  desc.AlphaMode = viz::HasAlpha(format) ? DXGI_ALPHA_MODE_PREMULTIPLIED
-                                         : DXGI_ALPHA_MODE_IGNORE;
+  desc.AlphaMode = si_format.HasAlpha() ? DXGI_ALPHA_MODE_PREMULTIPLIED
+                                        : DXGI_ALPHA_MODE_IGNORE;
 
   Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain;
 
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
index f8db3498..ec0a709 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
@@ -189,7 +189,7 @@
   if (usage & kUsageNeedsColorAttachment) {
     vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
-    if (viz::IsResourceFormatCompressed(format)) {
+    if (format.IsCompressed()) {
       DLOG(ERROR) << "ETC1 format cannot be used as color attachment.";
       return nullptr;
     }
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
index 02ff404..7abd588 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
@@ -246,8 +246,7 @@
   for (int i = 0; i <= viz::RESOURCE_FORMAT_MAX; ++i) {
     auto format = viz::SharedImageFormat::SinglePlane(
         static_cast<viz::ResourceFormat>(i));
-    if (!viz::GLSupportsFormat(format) ||
-        viz::IsResourceFormatCompressed(format))
+    if (!viz::GLSupportsFormat(format) || format.IsCompressed())
       continue;
     int storage_format = viz::TextureStorageFormat(
         format, feature_info->feature_flags().angle_rgbx_internal_format);
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc
index 2e2f78e..b4163c44 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc
@@ -1029,8 +1029,7 @@
   for (int i = 0; i <= viz::RESOURCE_FORMAT_MAX; ++i) {
     auto format = viz::SharedImageFormat::SinglePlane(
         static_cast<viz::ResourceFormat>(i));
-    if (!viz::GLSupportsFormat(format) ||
-        viz::IsResourceFormatCompressed(format))
+    if (!viz::GLSupportsFormat(format) || format.IsCompressed())
       continue;
     int storage_format = viz::TextureStorageFormat(
         format, feature_info->feature_flags().angle_rgbx_internal_format);
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
index 93eb0f3..12bc8caf 100644
--- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
@@ -232,7 +232,7 @@
       return false;
     context_state_->set_need_context_state_reset(true);
 
-    DCHECK(!viz::IsResourceFormatCompressed(format()));
+    DCHECK(!format().IsCompressed());
     auto mipmap = usage() & SHARED_IMAGE_USAGE_MIPMAP ? GrMipMapped::kYes
                                                       : GrMipMapped::kNo;
     const std::string label = "WrappedSkImageBackingFactory_Initialize" +
@@ -280,7 +280,7 @@
       return false;
     context_state_->set_need_context_state_reset(true);
 
-    if (viz::IsResourceFormatCompressed(format())) {
+    if (format().IsCompressed()) {
       backend_texture_ =
           context_state_->gr_context()->createCompressedBackendTexture(
               size().width(), size().height(), SkImage::kETC1_CompressionType,
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h
index e43d2c82..73ec072 100644
--- a/gpu/ipc/service/command_buffer_stub.h
+++ b/gpu/ipc/service/command_buffer_stub.h
@@ -228,6 +228,11 @@
 
   virtual void OnTakeFrontBuffer(const Mailbox& mailbox) {}
   virtual void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) {}
+  virtual void OnSetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                                  int samples_count,
+                                                  bool preserve,
+                                                  bool needs_depth,
+                                                  bool needs_stencil) {}
 
   std::unique_ptr<MemoryTracker> CreateMemoryTracker() const;
 
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc
index c7cbcfd..33e48e90 100644
--- a/gpu/ipc/service/gles2_command_buffer_stub.cc
+++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -43,6 +43,7 @@
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/gpu_fence.h"
 #include "ui/gfx/gpu_fence_handle.h"
+#include "ui/gfx/switches.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_implementation.h"
@@ -71,7 +72,9 @@
                         sequence_id,
                         stream_id,
                         route_id),
-      gles2_decoder_(nullptr) {}
+      gles2_decoder_(nullptr),
+      use_shared_images_swapchain_for_ppapi_(
+          features::UseSharedImagesSwapChainForPPAPI()) {}
 
 GLES2CommandBufferStub::~GLES2CommandBufferStub() = default;
 
@@ -466,6 +469,20 @@
   gles2_decoder_->ReturnFrontBuffer(mailbox, is_lost);
 }
 
+void GLES2CommandBufferStub::OnSetDefaultFramebufferSharedImage(
+    const Mailbox& mailbox,
+    int samples_count,
+    bool preserve,
+    bool needs_depth,
+    bool needs_stencil) {
+  if (!use_shared_images_swapchain_for_ppapi_)
+    return;
+
+  // No need to pull texture updates.
+  gles2_decoder_->SetDefaultFramebufferSharedImage(
+      mailbox, samples_count, preserve, needs_depth, needs_stencil);
+}
+
 void GLES2CommandBufferStub::CreateGpuFenceFromHandle(
     uint32_t gpu_fence_id,
     gfx::GpuFenceHandle handle) {
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h
index aba896c..ad8bc99 100644
--- a/gpu/ipc/service/gles2_command_buffer_stub.h
+++ b/gpu/ipc/service/gles2_command_buffer_stub.h
@@ -59,6 +59,12 @@
   // CommandBufferStub overrides:
   void OnTakeFrontBuffer(const Mailbox& mailbox) override;
   void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
+  void OnSetDefaultFramebufferSharedImage(const Mailbox& mailbox,
+                                          int samples_count,
+                                          bool preserve,
+                                          bool needs_depth,
+                                          bool needs_stencil) override;
+
   void CreateGpuFenceFromHandle(uint32_t id,
                                 gfx::GpuFenceHandle handle) override;
   void GetGpuFenceHandle(uint32_t gpu_fence_id,
@@ -73,6 +79,8 @@
   // unnecessary casts. Owned by parent class.
   raw_ptr<gles2::GLES2Decoder> gles2_decoder_;
 
+  const bool use_shared_images_swapchain_for_ppapi_;
+
   base::WeakPtrFactory<GLES2CommandBufferStub> weak_ptr_factory_{this};
 };
 
diff --git a/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame-expected.txt b/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame-expected.txt
new file mode 100644
index 0000000..14351981
--- /dev/null
+++ b/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame-expected.txt
@@ -0,0 +1,4 @@
+Tests that virtual time works with storage.
+Request to http://test.com/index.html, type: Document
+Request to http://test2.com/frame1.html, type: Document
+Request to http://test2.com/frame2.html, type: Document
\ No newline at end of file
diff --git a/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame.js b/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame.js
new file mode 100644
index 0000000..b96520e
--- /dev/null
+++ b/headless/test/data/protocol/emulation/virtual-time-local-storage-detached-frame.js
@@ -0,0 +1,65 @@
+// 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.
+
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startBlank(
+      `Tests that virtual time works with storage.`);
+
+  const FetchHelper = await testRunner.loadScriptAbsolute(
+      '../fetch/resources/fetch-test.js');
+  const helper = new FetchHelper(testRunner, dp);
+  await helper.enable();
+
+  helper.onceRequest('http://test.com/index.html').fulfill(
+      FetchHelper.makeContentResponse(`
+          <html>
+          <body>
+          <script>
+            function createFrame(url, id) {
+              const frame = document.createElement('iframe');
+              frame.id = id;
+              frame.src = url;
+              return new Promise(resolve => {
+                frame.onload = resolve;
+                document.body.appendChild(frame);
+              })
+            }
+            window.addEventListener('message', () => {
+              document.getElementById('frame1').remove();
+              document.getElementById('frame2').contentWindow.postMessage('doit', 'http://test2.com');
+            });
+            Promise.all([
+              createFrame('http://test2.com/frame1.html', 'frame1'),
+              createFrame('http://test2.com/frame2.html', 'frame2')
+            ]).then(() => {
+              frames[0].postMessage('doit', 'http://test2.com');
+            });
+          </script>
+          </body>
+          </html>`)
+  );
+
+  const frameSource = `
+    <html><body><script>
+    window.addEventListener('message', async (event) => {
+      localStorage.setItem('foo', 'bar');
+      event.source.postMessage('done', event.origin);
+    });
+    </script></body></html>`;
+  helper.onceRequest('http://test2.com/frame1.html').fulfill(
+    FetchHelper.makeContentResponse(frameSource)
+  );
+  helper.onceRequest('http://test2.com/frame2.html').fulfill(
+    FetchHelper.makeContentResponse(frameSource)
+  );
+
+  await dp.Emulation.setVirtualTimePolicy({policy: 'pause'});
+  await dp.Page.navigate({url: 'http://test.com/index.html'});
+  dp.Emulation.setVirtualTimePolicy({
+    policy: 'pauseIfNetworkFetchesPending',
+    budget: 5000,
+    maxVirtualTimeTaskStarvationCount: 10000});
+  await dp.Emulation.onceVirtualTimeBudgetExpired();
+  testRunner.completeTest();
+})
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index d542df8..8760f28 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -49,15 +49,20 @@
                                   "MAP *.test 127.0.0.1");
   HeadlessDevTooledBrowserTest::SetUpCommandLine(command_line);
 
-  // Make sure the navigations spawn new processes. We run test harness
-  // in one process (harness.test) and tests in another.
-  command_line->AppendSwitch(::switches::kSitePerProcess);
-
+  if (RequiresSitePerProcess()) {
+    // Make sure the navigations spawn new processes. We run test harness
+    // in one process (harness.test) and tests in another.
+    command_line->AppendSwitch(::switches::kSitePerProcess);
+  }
   // Make sure proxy related tests are not affected by a platform specific
   // system proxy configuration service.
   command_line->AppendSwitch(switches::kNoSystemProxyConfigService);
 }
 
+bool HeadlessProtocolBrowserTest::RequiresSitePerProcess() {
+  return true;
+}
+
 base::Value::Dict HeadlessProtocolBrowserTest::GetPageUrlExtraParams() {
   return base::Value::Dict();
 }
@@ -368,4 +373,36 @@
 HEADLESS_PROTOCOL_TEST_WITH_PROXY(BrowserSetProxyConfig,
                                   "sanity/browser-set-proxy-config.js")
 
+// TODO(crbug.com/1086872): The whole test suite is flaky on Mac ASAN.
+#if (BUILDFLAG(IS_MAC) && defined(ADDRESS_SANITIZER))
+#define HEADLESS_PROTOCOL_TEST_WITHOUT_SITE_ISOLATION(TEST_NAME, SCRIPT_NAME) \
+  IN_PROC_BROWSER_TEST_F(HeadlessProtocolBrowserTestWithoutSiteIsolation,     \
+                         DISABLED_##TEST_NAME) {                              \
+    test_folder_ = "/protocol/";                                              \
+    script_name_ = SCRIPT_NAME;                                               \
+    RunTest();                                                                \
+  }
+#else
+#define HEADLESS_PROTOCOL_TEST_WITHOUT_SITE_ISOLATION(TEST_NAME, SCRIPT_NAME) \
+  IN_PROC_BROWSER_TEST_F(HeadlessProtocolBrowserTestWithoutSiteIsolation,     \
+                         TEST_NAME) {                                         \
+    test_folder_ = "/protocol/";                                              \
+    script_name_ = SCRIPT_NAME;                                               \
+    RunTest();                                                                \
+  }
+#endif
+
+class HeadlessProtocolBrowserTestWithoutSiteIsolation
+    : public HeadlessProtocolBrowserTest {
+ public:
+  HeadlessProtocolBrowserTestWithoutSiteIsolation() = default;
+
+ protected:
+  bool RequiresSitePerProcess() override { return false; }
+};
+
+HEADLESS_PROTOCOL_TEST_WITHOUT_SITE_ISOLATION(
+    VirtualTimeLocalStorageDetachedFrame,
+    "emulation/virtual-time-local-storage-detached-frame.js")
+
 }  // namespace headless
diff --git a/headless/test/headless_protocol_browsertest.h b/headless/test/headless_protocol_browsertest.h
index febccb85..38049cb 100644
--- a/headless/test/headless_protocol_browsertest.h
+++ b/headless/test/headless_protocol_browsertest.h
@@ -28,6 +28,8 @@
 
   virtual base::Value::Dict GetPageUrlExtraParams();
 
+  virtual bool RequiresSitePerProcess();
+
  private:
   // HeadlessWebContentsObserver implementation.
   void RunDevTooledTest() override;
diff --git a/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json b/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
index c071f526..e7db11f7 100644
--- a/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
+++ b/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
@@ -94,10 +94,6 @@
         {
           "builder": "win10_chromium_x64_rel_ng",
           "group": "tryserver.chromium.win"
-        },
-        {
-          "builder": "win10_chromium_x64_rel_ng-reclient",
-          "group": "tryserver.chromium.win"
         }
       ]
     }
diff --git a/infra/config/generated/builders/ci/Win x64 Builder/properties.json b/infra/config/generated/builders/ci/Win x64 Builder/properties.json
index 0b23cdc..7470540 100644
--- a/infra/config/generated/builders/ci/Win x64 Builder/properties.json
+++ b/infra/config/generated/builders/ci/Win x64 Builder/properties.json
@@ -167,10 +167,6 @@
           "group": "tryserver.chromium.win"
         },
         {
-          "builder": "win10_chromium_x64_rel_ng-reclient",
-          "group": "tryserver.chromium.win"
-        },
-        {
           "builder": "win11-x64-fyi-rel",
           "group": "tryserver.chromium.win"
         },
diff --git a/infra/config/generated/builders/ci/Win10 Tests x64/properties.json b/infra/config/generated/builders/ci/Win10 Tests x64/properties.json
index 26ee95a5..9ed75877 100644
--- a/infra/config/generated/builders/ci/Win10 Tests x64/properties.json
+++ b/infra/config/generated/builders/ci/Win10 Tests x64/properties.json
@@ -87,10 +87,6 @@
         {
           "builder": "win10_chromium_x64_rel_ng",
           "group": "tryserver.chromium.win"
-        },
-        {
-          "builder": "win10_chromium_x64_rel_ng-reclient",
-          "group": "tryserver.chromium.win"
         }
       ]
     }
diff --git "a/infra/config/generated/builders/ci/Win10 x64 Release \050NVIDIA\051/properties.json" "b/infra/config/generated/builders/ci/Win10 x64 Release \050NVIDIA\051/properties.json"
index ae95372..b8ae011 100644
--- "a/infra/config/generated/builders/ci/Win10 x64 Release \050NVIDIA\051/properties.json"
+++ "b/infra/config/generated/builders/ci/Win10 x64 Release \050NVIDIA\051/properties.json"
@@ -87,10 +87,6 @@
         {
           "builder": "win10_chromium_x64_rel_ng",
           "group": "tryserver.chromium.win"
-        },
-        {
-          "builder": "win10_chromium_x64_rel_ng-reclient",
-          "group": "tryserver.chromium.win"
         }
       ]
     }
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
index 7fca0247..d24d55bf 100644
--- a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
+++ b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
@@ -50,6 +50,10 @@
           "group": "tryserver.chromium.chromiumos"
         },
         {
+          "builder": "linux-chromeos-rel-reclient",
+          "group": "tryserver.chromium.chromiumos"
+        },
+        {
           "builder": "linux-chromeos-rel-rts",
           "group": "tryserver.chromium.chromiumos"
         }
diff --git a/infra/config/generated/builders/try/android_compile_dbg/properties.json b/infra/config/generated/builders/try/android_compile_dbg/properties.json
index 03b546f..09fca69b 100644
--- a/infra/config/generated/builders/try/android_compile_dbg/properties.json
+++ b/infra/config/generated/builders/try/android_compile_dbg/properties.json
@@ -90,7 +90,7 @@
   },
   "$build/reclient": {
     "instance": "rbe-chromium-untrusted",
-    "jobs": 150,
+    "jobs": 300,
     "metrics_project": "chromium-reclient-metrics"
   },
   "$recipe_engine/resultdb/test_presentation": {
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-reclient-compilator/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-reclient-compilator/properties.json
new file mode 100644
index 0000000..c18b9f4
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-chromeos-rel-reclient-compilator/properties.json
@@ -0,0 +1,72 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ],
+      "is_compile_only": true
+    }
+  },
+  "$build/code_coverage": {
+    "coverage_test_types": [
+      "unit",
+      "overall"
+    ],
+    "use_clang_coverage": true
+  },
+  "$build/goma": {
+    "enable_ats": true,
+    "rpc_extra_params": "?prod",
+    "server_host": "goma.chromium.org"
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "jobs": 300,
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.chromiumos",
+  "recipe": "chromium/compilator"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-reclient/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-reclient/properties.json
new file mode 100644
index 0000000..bfd612b
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-chromeos-rel-reclient/properties.json
@@ -0,0 +1,66 @@
+{
+  "$build/chromium_orchestrator": {
+    "compilator": "linux-chromeos-rel-reclient-compilator",
+    "compilator_watcher_git_revision": "7809a690bbd935bcb3b4d922e24cabe168aaabc8"
+  },
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ],
+      "is_compile_only": true
+    }
+  },
+  "$build/code_coverage": {
+    "coverage_test_types": [
+      "unit",
+      "overall"
+    ],
+    "use_clang_coverage": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.chromiumos",
+  "recipe": "chromium/orchestrator"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient-compilator/properties.json b/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient-compilator/properties.json
deleted file mode 100644
index 8ddecec..0000000
--- a/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient-compilator/properties.json
+++ /dev/null
@@ -1,186 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "GPU Win x64 Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-gpu-archive",
-              "builder_group": "chromium.gpu",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win x64 Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-win-archive",
-              "builder_group": "chromium.win",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win10 Tests x64",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-win-archive",
-              "builder_group": "chromium.win",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Win x64 Builder",
-                "project": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win10 x64 Release (NVIDIA)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-gpu-archive",
-              "builder_group": "chromium.gpu",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "GPU Win x64 Builder",
-                "project": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "GPU Win x64 Builder",
-          "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "Win x64 Builder",
-          "project": "chromium"
-        }
-      ],
-      "builder_ids_in_scope_for_testing": [
-        {
-          "bucket": "ci",
-          "builder": "Win10 Tests x64",
-          "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "Win10 x64 Release (NVIDIA)",
-          "project": "chromium"
-        }
-      ],
-      "is_compile_only": true,
-      "rts_config": {
-        "condition": "QUICK_RUN_ONLY"
-      }
-    }
-  },
-  "$build/code_coverage": {
-    "coverage_test_types": [
-      "unit",
-      "overall"
-    ],
-    "use_clang_coverage": true
-  },
-  "$build/flakiness": {
-    "check_for_flakiness": true
-  },
-  "$build/goma": {
-    "enable_ats": false,
-    "jobs": 300,
-    "rpc_extra_params": "?prod",
-    "server_host": "goma.chromium.org"
-  },
-  "$build/reclient": {
-    "instance": "rbe-chromium-untrusted",
-    "jobs": 300,
-    "metrics_project": "chromium-reclient-metrics"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "tryserver.chromium.win",
-  "recipe": "chromium/compilator"
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient/properties.json b/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient/properties.json
deleted file mode 100644
index 1033640..0000000
--- a/infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient/properties.json
+++ /dev/null
@@ -1,179 +0,0 @@
-{
-  "$build/chromium_orchestrator": {
-    "compilator": "win10_chromium_x64_rel_ng-reclient-compilator",
-    "compilator_watcher_git_revision": "7809a690bbd935bcb3b4d922e24cabe168aaabc8"
-  },
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "GPU Win x64 Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-gpu-archive",
-              "builder_group": "chromium.gpu",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win x64 Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-win-archive",
-              "builder_group": "chromium.win",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win10 Tests x64",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-win-archive",
-              "builder_group": "chromium.win",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Win x64 Builder",
-                "project": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win10 x64 Release (NVIDIA)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-gpu-archive",
-              "builder_group": "chromium.gpu",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "GPU Win x64 Builder",
-                "project": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "GPU Win x64 Builder",
-          "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "Win x64 Builder",
-          "project": "chromium"
-        }
-      ],
-      "builder_ids_in_scope_for_testing": [
-        {
-          "bucket": "ci",
-          "builder": "Win10 Tests x64",
-          "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "Win10 x64 Release (NVIDIA)",
-          "project": "chromium"
-        }
-      ],
-      "is_compile_only": true,
-      "rts_config": {
-        "condition": "QUICK_RUN_ONLY"
-      }
-    }
-  },
-  "$build/code_coverage": {
-    "coverage_test_types": [
-      "unit",
-      "overall"
-    ],
-    "use_clang_coverage": true
-  },
-  "$build/flakiness": {
-    "check_for_flakiness": true
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "tryserver.chromium.win",
-  "recipe": "chromium/orchestrator"
-}
\ No newline at end of file
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md
index 7d79073..5261124 100644
--- a/infra/config/generated/cq-builders.md
+++ b/infra/config/generated/cq-builders.md
@@ -497,6 +497,9 @@
 * [linux-1mbu-compile-fyi-rel](https://ci.chromium.org/p/chromium/builders/try/linux-1mbu-compile-fyi-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-1mbu-compile-fyi-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-1mbu-compile-fyi-rel""))
   * Experiment percentage: 5.0
 
+* [linux-chromeos-rel-reclient](https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-reclient) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-chromeos-rel-reclient"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-chromeos-rel-reclient""))
+  * Experiment percentage: 3.0
+
 * [linux-chromeos-rel-rts](https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-rts) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-chromeos-rel-rts"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-chromeos-rel-rts""))
   * Experiment percentage: 5.0
 
@@ -506,6 +509,3 @@
 * [mac12-arm64-rel](https://ci.chromium.org/p/chromium/builders/try/mac12-arm64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""mac12-arm64-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac12-arm64-rel""))
   * Experiment percentage: 100.0
 
-* [win10_chromium_x64_rel_ng-reclient](https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng-reclient) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""win10_chromium_x64_rel_ng-reclient"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""win10_chromium_x64_rel_ng-reclient""))
-  * Experiment percentage: 3.0
-
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 3c351383..95697c1 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2496,6 +2496,31 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/linux-chromeos-rel-reclient"
+        experiment_percentage: 3
+        location_filters {
+          gerrit_host_regexp: ".*"
+          gerrit_project_regexp: ".*"
+          path_regexp: "docs/.+"
+          exclude: true
+        }
+        location_filters {
+          gerrit_host_regexp: ".*"
+          gerrit_project_regexp: ".*"
+          path_regexp: "infra/config/.+"
+          exclude: true
+        }
+        location_filters {
+          gerrit_host_regexp: ".*"
+          gerrit_project_regexp: ".*"
+          path_regexp: "infra/config/generated/builders/try/linux-chromeos-rel-reclient/.+"
+        }
+      }
+      builders {
+        name: "chromium/try/linux-chromeos-rel-reclient-compilator"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/linux-chromeos-rel-rts"
         experiment_percentage: 5
         location_filters {
@@ -3812,31 +3837,6 @@
         includable_only: true
       }
       builders {
-        name: "chromium/try/win10_chromium_x64_rel_ng-reclient"
-        experiment_percentage: 3
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "docs/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient/.+"
-        }
-      }
-      builders {
-        name: "chromium/try/win10_chromium_x64_rel_ng-reclient-compilator"
-        includable_only: true
-      }
-      builders {
         name: "chromium/try/win11-blink-rel"
         includable_only: true
       }
@@ -4082,7 +4082,6 @@
     projects {
       name: "chromium/src"
       ref_regexp: "refs/branch-heads/.*"
-      ref_regexp_exclude: "refs/branch-heads/4896"
       ref_regexp_exclude: "refs/branch-heads/5005"
       ref_regexp_exclude: "refs/branch-heads/5112"
       ref_regexp_exclude: "refs/branch-heads/5195"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 9354b76..b0d99d9 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -62111,7 +62111,7 @@
       name: "android_compile_dbg"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:android_compile_dbg"
-      dimensions: "cores:8|16"
+      dimensions: "cores:16"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.try"
@@ -77684,6 +77684,227 @@
       description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel\">linux-chromeos-rel</a>."
     }
     builders {
+      name: "linux-chromeos-rel-reclient"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:2"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.try"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/linux-chromeos-rel-reclient/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.chromiumos",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium/orchestrator"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      caches {
+        name: "win_toolchain"
+        path: "win_toolchain"
+      }
+      build_numbers: YES
+      service_account: "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "enable_weetbix_queries"
+        value: 100
+      }
+      experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      experiments {
+        key: "weetbix.enable_weetbix_exonerations"
+        value: 100
+      }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-reclient-compilator\">linux-chromeos-rel-reclient-compilator</a>."
+    }
+    builders {
+      name: "linux-chromeos-rel-reclient-compilator"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:32"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:1"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/linux-chromeos-rel-reclient-compilator/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.chromiumos",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium/compilator"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      caches {
+        name: "win_toolchain"
+        path: "win_toolchain"
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "enable_weetbix_queries"
+        value: 100
+      }
+      experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      experiments {
+        key: "weetbix.enable_weetbix_exonerations"
+        value: 100
+      }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-reclient\">linux-chromeos-rel-reclient</a>."
+    }
+    builders {
       name: "linux-chromeos-rel-rts"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:linux-chromeos-rel-rts"
@@ -78884,7 +79105,7 @@
       name: "linux-lacros-asan-lsan-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
-      dimensions: "cores:8"
+      dimensions: "cores:16"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.try"
@@ -93810,227 +94031,6 @@
       description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng\">win10_chromium_x64_rel_ng</a>."
     }
     builders {
-      name: "win10_chromium_x64_rel_ng-reclient"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:2"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.try"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "tryserver.chromium.win",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/orchestrator"'
-        '}'
-      execution_timeout_secs: 14400
-      expiration_secs: 7200
-      grace_period {
-        seconds: 120
-      }
-      caches {
-        name: "win_toolchain"
-        path: "win_toolchain"
-      }
-      build_numbers: YES
-      service_account: "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com"
-      task_template_canary_percentage {
-        value: 5
-      }
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "enable_weetbix_queries"
-        value: 100
-      }
-      experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      experiments {
-        key: "weetbix.enable_weetbix_exonerations"
-        value: 100
-      }
-      experiments {
-        key: "weetbix.retry_weak_exonerations"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "try_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "Experimental shadow builder to test reclient migration. <br/>The bot is shadowing <a href=\"https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng\">win10_chromium_x64_rel_ng</a>.<br/>This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng-reclient-compilator\">win10_chromium_x64_rel_ng-reclient-compilator</a>."
-    }
-    builders {
-      name: "win10_chromium_x64_rel_ng-reclient-compilator"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:32"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.try"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng-reclient-compilator/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "tryserver.chromium.win",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/compilator"'
-        '}'
-      execution_timeout_secs: 14400
-      expiration_secs: 7200
-      grace_period {
-        seconds: 240
-      }
-      caches {
-        name: "win_toolchain"
-        path: "win_toolchain"
-      }
-      build_numbers: YES
-      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-      task_template_canary_percentage {
-        value: 5
-      }
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "enable_weetbix_queries"
-        value: 100
-      }
-      experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      experiments {
-        key: "weetbix.enable_weetbix_exonerations"
-        value: 100
-      }
-      experiments {
-        key: "weetbix.retry_weak_exonerations"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "try_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng-reclient\">win10_chromium_x64_rel_ng-reclient</a>."
-    }
-    builders {
       name: "win11-blink-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 783800f..8071e3d6 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -830,10 +830,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -1574,10 +1570,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -2077,10 +2069,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -2435,10 +2423,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -3065,10 +3049,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -3403,10 +3383,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -3846,10 +3822,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -4185,10 +4157,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -4747,10 +4715,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -5134,10 +5098,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -5542,10 +5502,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -5988,10 +5944,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -6551,10 +6503,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -7029,10 +6977,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -7409,10 +7353,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -7787,10 +7727,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -8279,10 +8215,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -9140,10 +9072,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -9570,10 +9498,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -9974,10 +9898,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -10368,10 +10288,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -11019,10 +10935,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -11432,10 +11344,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -11850,10 +11758,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -12293,10 +12197,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -12656,10 +12556,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -13114,10 +13010,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -13468,10 +13360,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -13846,10 +13734,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -14334,10 +14218,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -14707,10 +14587,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -15121,10 +14997,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -15514,10 +15386,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -15918,10 +15786,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -16269,10 +16133,6 @@
     links {
       name: "Branch Consoles"
       links {
-        text: "m100"
-        url: "/p/chromium-m100/g/main/console"
-      }
-      links {
         text: "m102"
         url: "/p/chromium-m102/g/main/console"
       }
@@ -17012,6 +16872,12 @@
     name: "buildbucket/luci.chromium.try/linux-chromeos-rel-compilator"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/linux-chromeos-rel-reclient"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.try/linux-chromeos-rel-reclient-compilator"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-chromeos-rel-rts"
   }
   builders {
@@ -17444,12 +17310,6 @@
     name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-compilator"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-reclient"
-  }
-  builders {
-    name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-reclient-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/win11-blink-rel"
   }
   builders {
@@ -17897,6 +17757,12 @@
     name: "buildbucket/luci.chromium.try/linux-chromeos-rel-compilator"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/linux-chromeos-rel-reclient"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.try/linux-chromeos-rel-reclient-compilator"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-chromeos-rel-rts"
   }
   builders {
@@ -18642,12 +18508,6 @@
     name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-compilator"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-reclient"
-  }
-  builders {
-    name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-reclient-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/win11-x64-fyi-rel"
   }
   builders {
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index f601d646..44434455 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -364,7 +364,6 @@
   name: "pools/ci"
   bindings {
     role: "role/swarming.poolUser"
-    principals: "project:chromium-m100"
     principals: "project:chromium-m102"
     principals: "project:chromium-m104"
     principals: "project:chromium-m105"
@@ -418,7 +417,6 @@
   bindings {
     role: "role/swarming.poolUser"
     principals: "group:chromium-led-users"
-    principals: "project:chromium-m100"
     principals: "project:chromium-m102"
     principals: "project:chromium-m104"
     principals: "project:chromium-m105"
diff --git a/infra/config/milestones.json b/infra/config/milestones.json
index 4c3179607..00462fa 100644
--- a/infra/config/milestones.json
+++ b/infra/config/milestones.json
@@ -1,9 +1,4 @@
 {
-    "100": {
-        "name": "m100",
-        "project": "chromium-m100",
-        "ref": "refs/branch-heads/4896"
-    },
     "102": {
         "name": "m102",
         "project": "chromium-m102",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
index 6a1205ea..3493b8728 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -591,9 +591,7 @@
 try_.builder(
     name = "android_compile_dbg",
     branch_selector = branches.STANDARD_MILESTONE,
-    cores = "8|16",
-    # TODO(crbug.com/1343843): Set to True once ssd bots are landed
-    ssd = None,
+    cores = 16,
     mirrors = [
         "ci/Android arm Builder (dbg)",
     ],
@@ -604,7 +602,7 @@
     builderless = not settings.is_main,
     goma_backend = None,
     main_list_view = "try",
-    reclient_jobs = reclient.jobs.LOW_JOBS_FOR_CQ,
+    reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CQ,
     tryjob = try_.job(),
 )
 
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index d1e02a80..0a9f3f1 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -269,6 +269,30 @@
     goma_jobs = goma.jobs.J300,
 )
 
+try_.orchestrator_builder(
+    name = "linux-chromeos-rel-reclient",
+    builderless = True,
+    mirrors = [
+        "ci/linux-chromeos-rel",
+    ],
+    compilator = "linux-chromeos-rel-reclient-compilator",
+    use_clang_coverage = True,
+    coverage_test_types = ["unit", "overall"],
+    tryjob = try_.job(
+        experiment_percentage = 3,
+    ),
+    try_settings = builder_config.try_settings(
+        is_compile_only = True,
+    ),
+)
+
+try_.compilator_builder(
+    name = "linux-chromeos-rel-reclient-compilator",
+    builderless = True,
+    reclient_instance = reclient.instance.DEFAULT_UNTRUSTED,
+    reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CQ,
+)
+
 try_.builder(
     name = "linux-lacros-dbg",
     # TODO(crbug.com/1233247) Adds the CI tester when it's available.
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index e568697..4e0739e 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -603,6 +603,7 @@
         "ci/linux-lacros-asan-lsan-rel",
     ],
     goma_jobs = goma.jobs.J150,
+    cores = 16,
 )
 
 try_.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
index 5113955..a19d149 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -288,41 +288,6 @@
     grace_period = 4 * time.minute,
 )
 
-try_.orchestrator_builder(
-    name = "win10_chromium_x64_rel_ng-reclient",
-    builderless = True,
-    check_for_flakiness = True,
-    compilator = "win10_chromium_x64_rel_ng-reclient-compilator",
-    mirrors = [
-        "ci/Win x64 Builder",
-        "ci/Win10 Tests x64",
-        "ci/GPU Win x64 Builder",
-        "ci/Win10 x64 Release (NVIDIA)",
-    ],
-    description_html = "Experimental shadow builder to test reclient migration. <br/>The bot is shadowing <a href=\"https://ci.chromium.org/p/chromium/builders/try/win10_chromium_x64_rel_ng\">win10_chromium_x64_rel_ng</a>.",
-    try_settings = builder_config.try_settings(
-        rts_config = builder_config.rts_config(
-            condition = builder_config.rts_condition.QUICK_RUN_ONLY,
-        ),
-        is_compile_only = True,
-    ),
-    use_clang_coverage = True,
-    coverage_test_types = ["unit", "overall"],
-    tryjob = try_.job(
-        experiment_percentage = 3,
-    ),
-)
-
-try_.compilator_builder(
-    name = "win10_chromium_x64_rel_ng-reclient-compilator",
-    builderless = True,
-    check_for_flakiness = True,
-    # TODO (crbug.com/1245171): Revert when root issue is fixed
-    grace_period = 4 * time.minute,
-    reclient_instance = reclient.instance.DEFAULT_UNTRUSTED,
-    reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CQ,
-)
-
 try_.builder(
     name = "win7-rel",
     branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE,
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 68c6dd54..f5b13aa9 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -466,7 +466,7 @@
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/browser_state:browser_state_impl",
     "//ios/chrome/browser/browsing_data",
-    "//ios/chrome/browser/commerce",
+    "//ios/chrome/browser/commerce/push_notification",
     "//ios/chrome/browser/crash_report",
     "//ios/chrome/browser/crash_report:crash_report_internal",
     "//ios/chrome/browser/crash_report/breadcrumbs",
diff --git a/ios/chrome/app/application_delegate/user_activity_handler.mm b/ios/chrome/app/application_delegate/user_activity_handler.mm
index fb7b0bb..fa4f0844 100644
--- a/ios/chrome/app/application_delegate/user_activity_handler.mm
+++ b/ios/chrome/app/application_delegate/user_activity_handler.mm
@@ -455,6 +455,7 @@
 
   const TemplateURL* defaultURL =
       templateURLService->GetDefaultSearchProvider();
+  DCHECK(defaultURL);
   DCHECK(!defaultURL->url().empty());
   DCHECK(
       defaultURL->url_ref().IsValid(templateURLService->search_terms_data()));
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index 4fbacd9..36791d2c 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/app/main_application_delegate_testing.h"
 #import "ios/chrome/app/main_controller.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/commerce/price_alert_util.h"
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
 #import "ios/chrome/browser/crash_report/crash_keys_helper.h"
 #import "ios/chrome/browser/download/background_service/background_download_service_factory.h"
 #import "ios/chrome/browser/push_notification/push_notification_delegate.h"
diff --git a/ios/chrome/app/resources/chrome_localize_strings_config.plist b/ios/chrome/app/resources/chrome_localize_strings_config.plist
index 06fdf192..a6c456c 100644
--- a/ios/chrome/app/resources/chrome_localize_strings_config.plist
+++ b/ios/chrome/app/resources/chrome_localize_strings_config.plist
@@ -22,6 +22,8 @@
 				<string>IDS_IOS_SAFE_MODE_RELOAD_CHROME</string>
 				<string>IDS_IOS_SAFE_MODE_AW_SNAP</string>
 				<string>IDS_IOS_FIRST_RUN_LAUNCH_SCREEN_ENTERPRISE</string>
+				<string>IDS_IOS_KEYBOARD_BOOKMARKS</string>
+				<string>IDS_IOS_KEYBOARD_HISTORY</string>
 				<string>IDS_IOS_KEYBOARD_NEW_TAB</string>
 				<string>IDS_IOS_KEYBOARD_NEW_INCOGNITO_TAB</string>
 				<string>IDS_IOS_KEYBOARD_NEW_WINDOW</string>
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 4570cbd..be5492a 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1267,6 +1267,9 @@
       <message name="IDS_IOS_KEYBOARD_ADD_TO_READING_LIST" desc="Title of the keyboard shortcut to add the current URL to the Reading List." meaning="Used as a command title in the iPad command menu.">
         Add to Reading List
       </message>
+      <message name="IDS_IOS_KEYBOARD_BOOKMARKS" desc="Title of the menu listing bookmarks-related keyboard shortcuts." meaning="Used as a menu title in the iPad command menu.">
+        Bookmarks
+      </message>
       <message name="IDS_IOS_KEYBOARD_CLEAR_BROWSING_DATA" desc="Title of the keyboard shortcut to clear the browsing data." meaning="Used as a command title in the iPad command menu.">
         Clear Browsing Data…
       </message>
@@ -1288,6 +1291,9 @@
       <message name="IDS_IOS_KEYBOARD_GO_TO_TAB_GRID" desc="The title of the keyboard shortcut to open the form to report an issue." meaning="Used as a command title in the iPad command menu.">
         Go to Tab Grid
       </message>
+      <message name="IDS_IOS_KEYBOARD_HISTORY" desc="Title of the menu listing history-related keyboard shortcuts." meaning="Used as a menu title in the iPad command menu.">
+        Bookmarks
+      </message>
       <message name="IDS_IOS_KEYBOARD_HISTORY_BACK" desc="Title of the keyboard shortcut to go back in the history menu." meaning="Used as a command title in the iPad command menu.">
         Back
       </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_BOOKMARKS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_BOOKMARKS.png.sha1
new file mode 100644
index 0000000..fcff6d4
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_BOOKMARKS.png.sha1
@@ -0,0 +1 @@
+36c1d4750bc48303edaf654f36938848d32e5f8e
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_HISTORY.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_HISTORY.png.sha1
new file mode 100644
index 0000000..9b40be7
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_KEYBOARD_HISTORY.png.sha1
@@ -0,0 +1 @@
+2dbc03be70ee1eb3ff62837d1873af21a507c230
\ No newline at end of file
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm
index 23d515a..5198a91 100644
--- a/ios/chrome/browser/autofill/form_structure_browsertest.mm
+++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -207,8 +207,6 @@
        // TODO(crbug.com/1150895) Remove once launched.
        features::kAutofillParsingPatternProvider,
        features::kAutofillPageLanguageDetection,
-       // TODO(crbug.com/1190334): Remove once launched.
-       autofill::features::kAutofillParseMerchantPromoCodeFields,
        // TODO(crbug.com/1335549): Remove once launched.
        features::kAutofillParseIBANFields,
        // TODO(crbug.com/1311937): Remove once launched.
diff --git a/ios/chrome/browser/commerce/price_alert_util.h b/ios/chrome/browser/commerce/price_alert_util.h
index 87826e9..0878504 100644
--- a/ios/chrome/browser/commerce/price_alert_util.h
+++ b/ios/chrome/browser/commerce/price_alert_util.h
@@ -15,7 +15,4 @@
 // MSBB and signed in users with a non-incognito Tab.
 BOOL IsPriceAlertsEligible(web::BrowserState* browser_state);
 
-// Determine if price drop notifications are enabled.
-BOOL IsPriceNotificationsEnabled();
-
 #endif  // IOS_CHROME_BROWSER_COMMERCE_PRICE_ALERT_UTIL_H_
diff --git a/ios/chrome/browser/commerce/price_alert_util.mm b/ios/chrome/browser/commerce/price_alert_util.mm
index 7eee52e..62f7a63 100644
--- a/ios/chrome/browser/commerce/price_alert_util.mm
+++ b/ios/chrome/browser/commerce/price_alert_util.mm
@@ -18,10 +18,6 @@
 #error "This file requires ARC support."
 #endif
 
-namespace {
-const char kPriceTrackingNotifications[] = "enable_price_notification";
-}  // namespace
-
 bool IsPriceAlertsEligible(web::BrowserState* browser_state) {
   if (browser_state->IsOffTheRecord()) {
     return false;
@@ -49,10 +45,3 @@
   }
   return true;
 }
-
-// Determine if price drop notifications are enabled.
-bool IsPriceNotificationsEnabled() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      commerce::kCommercePriceTracking, kPriceTrackingNotifications,
-      /** default_value */ false);
-}
diff --git a/ios/chrome/browser/commerce/push_notification/BUILD.gn b/ios/chrome/browser/commerce/push_notification/BUILD.gn
index 099ac01..5269678 100644
--- a/ios/chrome/browser/commerce/push_notification/BUILD.gn
+++ b/ios/chrome/browser/commerce/push_notification/BUILD.gn
@@ -6,9 +6,15 @@
   sources = [
     "commerce_push_notification_client.h",
     "commerce_push_notification_client.mm",
+    "push_notification_feature.h",
+    "push_notification_feature.mm",
   ]
 
-  deps = [ "//ios/chrome/browser/push_notification:push_notification_client" ]
+  deps = [
+    "//base",
+    "//components/commerce/core:feature_list",
+    "//ios/chrome/browser/push_notification:push_notification_client",
+  ]
 
   frameworks = [ "UserNotifications.framework" ]
 
diff --git a/ios/chrome/browser/commerce/push_notification/push_notification_feature.h b/ios/chrome/browser/commerce/push_notification/push_notification_feature.h
new file mode 100644
index 0000000..edcba293
--- /dev/null
+++ b/ios/chrome/browser/commerce/push_notification/push_notification_feature.h
@@ -0,0 +1,13 @@
+// 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 IOS_CHROME_BROWSER_COMMERCE_PUSH_NOTIFICATION_PUSH_NOTIFICATION_FEATURE_H_
+#define IOS_CHROME_BROWSER_COMMERCE_PUSH_NOTIFICATION_PUSH_NOTIFICATION_FEATURE_H_
+
+#import <Foundation/Foundation.h>
+
+// Determine if price drop notifications are enabled.
+BOOL IsPriceNotificationsEnabled();
+
+#endif  // IOS_CHROME_BROWSER_COMMERCE_PUSH_NOTIFICATION_PUSH_NOTIFICATION_FEATURE_H_
diff --git a/ios/chrome/browser/commerce/push_notification/push_notification_feature.mm b/ios/chrome/browser/commerce/push_notification/push_notification_feature.mm
new file mode 100644
index 0000000..159a9f16
--- /dev/null
+++ b/ios/chrome/browser/commerce/push_notification/push_notification_feature.mm
@@ -0,0 +1,23 @@
+// 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.
+
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
+
+#import "base/metrics/field_trial_params.h"
+#import "components/commerce/core/commerce_feature_list.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+const char kPriceTrackingNotifications[] = "enable_price_notification";
+}  // namespace
+
+// Determine if price drop notifications are enabled.
+bool IsPriceNotificationsEnabled() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      commerce::kCommercePriceTracking, kPriceTrackingNotifications,
+      /** default_value */ false);
+}
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn
index 7a02e40..c34167b 100644
--- a/ios/chrome/browser/flags/BUILD.gn
+++ b/ios/chrome/browser/flags/BUILD.gn
@@ -21,6 +21,7 @@
     "//components/breadcrumbs/core:feature_flags",
     "//components/commerce/core:feature_list",
     "//components/dom_distiller/core",
+    "//components/download/public/background_service:public",
     "//components/enterprise",
     "//components/feature_engagement/public",
     "//components/feed:feature_list",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index e76ab4d..0caea72 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -30,6 +30,7 @@
 #import "components/commerce/core/flag_descriptions.h"
 #import "components/content_settings/core/common/features.h"
 #import "components/dom_distiller/core/dom_distiller_switches.h"
+#import "components/download/public/background_service/features.h"
 #import "components/enterprise/browser/enterprise_switches.h"
 #import "components/feature_engagement/public/feature_constants.h"
 #import "components/feature_engagement/public/feature_list.h"
@@ -843,12 +844,6 @@
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(
          password_manager::features::kFillingAcrossAffiliatedWebsites)},
-    {"autofill-parse-merchant-promo-code-fields",
-     flag_descriptions::kAutofillParseMerchantPromoCodeFieldsName,
-     flag_descriptions::kAutofillParseMerchantPromoCodeFieldsDescription,
-     flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(
-         autofill::features::kAutofillParseMerchantPromoCodeFields)},
     {"interest-feed-v2-clicks-and-views-cond-upload",
      flag_descriptions::kInterestFeedV2ClickAndViewActionsConditionalUploadName,
      flag_descriptions::
@@ -1045,6 +1040,11 @@
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(
          autofill::features::kAutofillUpstreamAllowAllEmailDomains)},
+    {"enable-download-service-foreground-session",
+     flag_descriptions::kDownloadServiceForegroundSessionName,
+     flag_descriptions::kDownloadServiceForegroundSessionDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(download::kDownloadServiceForegroundSessionIOSFeature)},
     {"enable-tflite-language-detection",
      flag_descriptions::kTFLiteLanguageDetectionName,
      flag_descriptions::kTFLiteLanguageDetectionDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index f5dd71b..b21c9fbb 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -79,12 +79,6 @@
     "When enabled, Autofill will attempt to find International Bank Account "
     "Number (IBAN) fields when parsing forms.";
 
-const char kAutofillParseMerchantPromoCodeFieldsName[] =
-    "Parse promo code fields in forms";
-const char kAutofillParseMerchantPromoCodeFieldsDescription[] =
-    "When enabled, Autofill will attempt to find merchant promo/coupon/gift "
-    "code fields when parsing forms.";
-
 const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsName[] =
     "Parse standalone CVC fields for VCN card on file in forms";
 const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsDescription[] =
@@ -761,6 +755,11 @@
     "Enable showing the Start Surface when launching Chrome via clicking the "
     "icon or the app switcher.";
 
+const char kDownloadServiceForegroundSessionName[] =
+    "Download service foreground download";
+const char kDownloadServiceForegroundSessionDescription[] =
+    "Enable download service to download in app foreground only";
+
 const char kTFLiteLanguageDetectionName[] = "TFLite-based Language Detection";
 const char kTFLiteLanguageDetectionDescription[] =
     "Uses TFLite for language detection in place of CLD3";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 55284c1..78bcca1 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -68,10 +68,6 @@
 extern const char kAutofillParseIBANFieldsName[];
 extern const char kAutofillParseIBANFieldsDescription[];
 
-// Title and description for the flag to parse promo code fields in Autofill.
-extern const char kAutofillParseMerchantPromoCodeFieldsName[];
-extern const char kAutofillParseMerchantPromoCodeFieldsDescription[];
-
 // Title and description for the flag to parse standalone CVC fields for VCN
 // card on file in Autofill.
 extern const char kAutofillParseVcnCardOnFileStandaloneCvcFieldsName[];
@@ -563,6 +559,11 @@
 extern const char kOptimizationGuideDebugLogsName[];
 extern const char kOptimizationGuideDebugLogsDescription[];
 
+// Title and description for the flag enable download service to download in
+// foreground.
+extern const char kDownloadServiceForegroundSessionName[];
+extern const char kDownloadServiceForegroundSessionDescription[];
+
 // Title and description for the flag to enable TFLite model downloading.
 extern const char kOptimizationGuideModelDownloadingName[];
 extern const char kOptimizationGuideModelDownloadingDescription[];
diff --git a/ios/chrome/browser/push_notification/BUILD.gn b/ios/chrome/browser/push_notification/BUILD.gn
index 74b3b3c..bc7b2aa8 100644
--- a/ios/chrome/browser/push_notification/BUILD.gn
+++ b/ios/chrome/browser/push_notification/BUILD.gn
@@ -23,7 +23,6 @@
     "//components/prefs",
     "//ios/chrome/browser/application_context",
     "//ios/chrome/browser/browser_state",
-    "//ios/chrome/browser/commerce",
     "//ios/chrome/browser/commerce/push_notification",
     "//ios/chrome/browser/prefs:pref_names",
   ]
diff --git a/ios/chrome/browser/push_notification/push_notification_client_manager.mm b/ios/chrome/browser/push_notification/push_notification_client_manager.mm
index 6a09932..46c15df 100644
--- a/ios/chrome/browser/push_notification/push_notification_client_manager.mm
+++ b/ios/chrome/browser/push_notification/push_notification_client_manager.mm
@@ -7,8 +7,8 @@
 #import <Foundation/Foundation.h>
 #import <vector>
 
-#import "ios/chrome/browser/commerce/price_alert_util.h"
 #import "ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.h"
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
 #import "ios/chrome/browser/push_notification/push_notification_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 211db3e..3da3542 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -107,6 +107,7 @@
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/lens/lens_coordinator.h"
 #import "ios/chrome/browser/ui/main/default_browser_scene_agent.h"
+#import "ios/chrome/browser/ui/main/layout_guide_util.h"
 #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h"
 #import "ios/chrome/browser/ui/open_in/features.h"
@@ -679,6 +680,8 @@
       [[BubblePresenter alloc] initWithBrowserState:browserState];
   _bubblePresenter.toolbarHandler =
       HandlerForProtocol(_dispatcher, ToolbarCommands);
+  _bubblePresenter.layoutGuideCenter =
+      LayoutGuideCenterForBrowser(self.browser);
   [_dispatcher startDispatchingToTarget:_bubblePresenter
                             forProtocol:@protocol(HelpCommands)];
 
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 8fd25c6..51ed082 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -1847,11 +1847,8 @@
       kOmniboxGuide,
       kOmniboxLeadingImageGuide,
       kOmniboxTextFieldGuide,
-      kBackButtonGuide,
-      kForwardButtonGuide,
       kToolsMenuGuide,
       kTabSwitcherGuide,
-      kNewTabButtonGuide,
       kSecondaryToolbarGuide,
       kDiscoverFeedHeaderMenuGuide,
       kPrimaryToolbarLocationViewGuide,
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h
index a118761..043f7f5 100644
--- a/ios/chrome/browser/ui/bubble/bubble_presenter.h
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -11,6 +11,7 @@
 @protocol BubblePresenterDelegate;
 @class BubbleViewControllerPresenter;
 class ChromeBrowserState;
+@class LayoutGuideCenter;
 @protocol ToolbarCommands;
 
 // Object handling the presentation of the different bubbles tips. The class is
@@ -31,6 +32,7 @@
 @property(nonatomic, weak) id<BubblePresenterDelegate> delegate;
 @property(nonatomic, weak) UIViewController* rootViewController;
 @property(nonatomic, weak) id<ToolbarCommands> toolbarHandler;
+@property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter;
 
 - (void)stop;
 
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
index 34f86fbe..30a6a2e 100644
--- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -19,8 +19,8 @@
 #import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
 #import "ios/chrome/browser/ui/commands/toolbar_commands.h"
 #import "ios/chrome/browser/ui/util/named_guide.h"
-#import "ios/chrome/browser/ui/util/named_guide_util.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/browser/ui/util/util_swift.h"
 #import "ios/chrome/browser/url/chrome_url_constants.h"
 #import "ios/chrome/browser/url/url_util.h"
 #import "ios/chrome/grit/ios_chromium_strings.h"
@@ -507,8 +507,9 @@
 - (CGPoint)anchorPointToGuide:(GuideName*)guideName
                     direction:(BubbleArrowDirection)arrowDirection {
   UILayoutGuide* guide =
-      [NamedGuide guideWithName:guideName view:self.rootViewController.view];
+      [self.layoutGuideCenter makeLayoutGuideNamed:guideName];
   DCHECK(guide);
+  [self.rootViewController.view addLayoutGuide:guide];
   CGPoint anchorPoint =
       bubble_util::AnchorPoint(guide.layoutFrame, arrowDirection);
   return [guide.owningView convertPoint:anchorPoint
diff --git a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm
index c0310a32..207b736 100644
--- a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm
+++ b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm
@@ -137,8 +137,9 @@
       chrome_test_util::GetOriginalBrowserState();
   TemplateURLService* service =
       ios::TemplateURLServiceFactory::GetForBrowserState(browser_state);
-  return base::SysUTF16ToNSString(
-      service->GetDefaultSearchProvider()->short_name());
+  const TemplateURL* default_provider = service->GetDefaultSearchProvider();
+  DCHECK(default_provider);
+  return base::SysUTF16ToNSString(default_provider->short_name());
 }
 
 + (void)resetSearchEngineTo:(NSString*)defaultSearchEngine {
diff --git a/ios/chrome/browser/ui/keyboard/menu_builder.mm b/ios/chrome/browser/ui/keyboard/menu_builder.mm
index 92f70457..84018c4 100644
--- a/ios/chrome/browser/ui/keyboard/menu_builder.mm
+++ b/ios/chrome/browser/ui/keyboard/menu_builder.mm
@@ -49,24 +49,26 @@
   [builder insertChildMenu:viewMenu atStartOfMenuForIdentifier:UIMenuView];
 
   // History
-  UIMenu* historyMenu = [UIMenu menuWithTitle:@"History"
-                                     children:@[
-                                       UIKeyCommand.cr_back,
-                                       UIKeyCommand.cr_forward,
-                                       UIKeyCommand.cr_reopenLastClosedTab,
-                                       UIKeyCommand.cr_showHistory,
-                                       UIKeyCommand.cr_clearBrowsingData,
-                                     ]];
+  UIMenu* historyMenu =
+      [UIMenu menuWithTitle:NSLocalizedString(@"IDS_IOS_KEYBOARD_HISTORY", @"")
+                   children:@[
+                     UIKeyCommand.cr_back,
+                     UIKeyCommand.cr_forward,
+                     UIKeyCommand.cr_reopenLastClosedTab,
+                     UIKeyCommand.cr_showHistory,
+                     UIKeyCommand.cr_clearBrowsingData,
+                   ]];
   [builder insertSiblingMenu:historyMenu afterMenuForIdentifier:UIMenuView];
 
   // Bookmarks
-  UIMenu* bookmarksMenu = [UIMenu menuWithTitle:@"Bookmarks"
-                                       children:@[
-                                         UIKeyCommand.cr_showBookmarks,
-                                         UIKeyCommand.cr_addToBookmarks,
-                                         UIKeyCommand.cr_showReadingList,
-                                         UIKeyCommand.cr_addToReadingList,
-                                       ]];
+  UIMenu* bookmarksMenu = [UIMenu
+      menuWithTitle:NSLocalizedString(@"IDS_IOS_KEYBOARD_BOOKMARKS", @"")
+           children:@[
+             UIKeyCommand.cr_showBookmarks,
+             UIKeyCommand.cr_addToBookmarks,
+             UIKeyCommand.cr_showReadingList,
+             UIKeyCommand.cr_addToReadingList,
+           ]];
   [builder insertSiblingMenu:bookmarksMenu
       afterMenuForIdentifier:historyMenu.identifier];
 
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_session_recorder_unittest.mm b/ios/chrome/browser/ui/ntp/metrics/feed_session_recorder_unittest.mm
index 707142d0..40d5d73 100644
--- a/ios/chrome/browser/ui/ntp/metrics/feed_session_recorder_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/metrics/feed_session_recorder_unittest.mm
@@ -17,9 +17,10 @@
 
 namespace {
 
-// Reference of time.
+// Reference of time. Don't use 0 or it will be processed as nullptr instead of
+// 0 seconds.
 constexpr base::Time kOriginOfTime =
-    base::Time::FromDeltaSinceWindowsEpoch(base::Seconds(0));
+    base::Time::FromDeltaSinceWindowsEpoch(base::Seconds(1));
 
 }  // anonymous namespace
 
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn
index 78d83133..b340cc26 100644
--- a/ios/chrome/browser/ui/popup_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -63,7 +63,7 @@
     "//ios/chrome/browser/bookmarks",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/browser_state_metrics",
-    "//ios/chrome/browser/commerce",
+    "//ios/chrome/browser/commerce/push_notification",
     "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/find_in_page",
     "//ios/chrome/browser/follow:browser_agent",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
index 21c87280..bc579c0 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -64,7 +64,7 @@
     "//components/translate/core/browser",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/browser_state",
-    "//ios/chrome/browser/commerce",
+    "//ios/chrome/browser/commerce/push_notification",
     "//ios/chrome/browser/find_in_page",
     "//ios/chrome/browser/follow:browser_agent",
     "//ios/chrome/browser/follow:enums",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
index 86dcb81..373203982 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -24,7 +24,7 @@
 #import "components/translate/core/browser/translate_manager.h"
 #import "components/translate/core/browser/translate_prefs.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/commerce/price_alert_util.h"
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
 #import "ios/chrome/browser/find_in_page/find_tab_helper.h"
 #import "ios/chrome/browser/follow/follow_browser_agent.h"
 #import "ios/chrome/browser/follow/follow_menu_updater.h"
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index 50c72ae..08a9e4c 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -563,7 +563,12 @@
   self.presenter = [[PopupMenuPresenter alloc] init];
   self.presenter.baseViewController = self.baseViewController;
   self.presenter.presentedViewController = tableViewController;
-  self.presenter.guideName = guideName;
+  LayoutGuideCenter* layoutGuideCenter =
+      LayoutGuideCenterForBrowser(self.browser);
+  UILayoutGuide* layoutGuide =
+      [layoutGuideCenter makeLayoutGuideNamed:guideName];
+  [self.baseViewController.view addLayoutGuide:layoutGuide];
+  self.presenter.layoutGuide = layoutGuide;
   self.presenter.delegate = self;
 
   [self.UIUpdater updateUIForMenuDisplayed:type];
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
index e9ac8f36..7368da3 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -27,7 +27,7 @@
 #import "components/translate/core/browser/translate_manager.h"
 #import "components/translate/core/browser/translate_prefs.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/commerce/price_alert_util.h"
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
 #import "ios/chrome/browser/find_in_page/find_tab_helper.h"
 #import "ios/chrome/browser/follow/follow_browser_agent.h"
 #import "ios/chrome/browser/follow/follow_menu_updater.h"
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.h b/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.h
index 17936a8..62fc2d4 100644
--- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.h
+++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.h
@@ -9,8 +9,6 @@
 
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter_delegate.h"
 #import "ios/chrome/browser/ui/presenters/contained_presenter.h"
-// TODO(crbug.com/1382336): Remove the use of NamedGuide.
-#import "ios/chrome/browser/ui/util/named_guide.h"
 
 // Presenter for the popup menu. It handles showing/dismissing a popup menu.
 @interface PopupMenuPresenter : NSObject <ContainedPresenter>
@@ -22,11 +20,6 @@
 // Layout guide used for the presentation.
 @property(nonatomic, strong) UILayoutGuide* layoutGuide;
 
-// Guide name used for the presentation.
-// DEPRECATED - Do not use in new code. Use layoutGuide instead.
-// http://crbug.com/1382336
-@property(nonatomic, strong) GuideName* guideName;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_POPUP_MENU_PUBLIC_POPUP_MENU_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.mm b/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.mm
index 354bd36..cdeb19a 100644
--- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.mm
+++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.mm
@@ -8,8 +8,6 @@
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter_delegate.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_view_controller.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_view_controller_delegate.h"
-// TODO(crbug.com/1382336): Remove the use of NamedGuide.
-#import "ios/chrome/browser/ui/util/named_guide.h"
 #import "ios/chrome/common/material_timing.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
 
@@ -45,7 +43,6 @@
 
 @synthesize baseViewController = _baseViewController;
 @synthesize delegate = _delegate;
-@synthesize guideName = _guideName;
 @synthesize popupViewController = _popupViewController;
 @synthesize initialConstraints = _initialConstraints;
 @synthesize presentedConstraints = _presentedConstraints;
@@ -112,14 +109,7 @@
                                               constant:-kMinWidthDifference]
       .active = YES;
 
-  UILayoutGuide* layoutGuide;
-  if (self.guideName) {
-    // TODO(crbug.com/1382336): Remove the use of NamedGuide.
-    layoutGuide = [NamedGuide guideWithName:self.guideName
-                                       view:self.baseViewController.view];
-  } else {
-    layoutGuide = self.layoutGuide;
-  }
+  UILayoutGuide* layoutGuide = self.layoutGuide;
   self.initialConstraints = @[
     [popup.centerXAnchor constraintEqualToAnchor:layoutGuide.centerXAnchor],
     [popup.centerYAnchor constraintEqualToAnchor:layoutGuide.centerYAnchor],
@@ -200,21 +190,14 @@
 }
 
 // Sets `presentedConstraints` up, such as they are positioning the popup
-// relatively to the `guideName` layout guide. The popup is positioned closest
-// to the layout guide, by default it is presented below the layout guide,
-// aligned on its leading edge. However, it is respecting the safe area bounds.
+// relatively to `layoutGuide`. The popup is positioned closest to the layout
+// guide, by default it is presented below the layout guide, aligned on its
+// leading edge. However, it is respecting the safe area bounds.
 - (void)setUpPresentedConstraints {
   UIView* parentView = self.baseViewController.view;
   UIView* container = self.popupViewController.contentContainer;
 
-  UILayoutGuide* layoutGuide;
-  if (self.guideName) {
-    // TODO(crbug.com/1382336): Remove the use of NamedGuide.
-    layoutGuide = [NamedGuide guideWithName:self.guideName
-                                       view:self.baseViewController.view];
-  } else {
-    layoutGuide = self.layoutGuide;
-  }
+  UILayoutGuide* layoutGuide = self.layoutGuide;
   CGRect guideFrame =
       [self.popupViewController.view convertRect:layoutGuide.layoutFrame
                                         fromView:layoutGuide.owningView];
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 22e1d0c..491e81a 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -1550,6 +1550,7 @@
 
   const TemplateURL* defaultURL =
       templateURLService->GetDefaultSearchProvider();
+  DCHECK(defaultURL);
 
   TemplateURLRef::SearchTermsArgs search_args(
       base::SysNSStringToUTF16(self.searchTerms));
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 45d746da..3f117d0 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -144,7 +144,7 @@
     "//ios/chrome/browser/browser_state:browser_state_impl",
     "//ios/chrome/browser/browsing_data",
     "//ios/chrome/browser/browsing_data:feature_flags",
-    "//ios/chrome/browser/commerce",
+    "//ios/chrome/browser/commerce/push_notification",
     "//ios/chrome/browser/content_settings",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/feature_engagement",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
index 98e08ba..43a14190 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
@@ -78,6 +78,7 @@
     "//ios/chrome/browser/ui/infobars/resources:infobar_hide_password_icon",
     "//ios/chrome/browser/ui/infobars/resources:infobar_reveal_password_icon",
     "//ios/chrome/browser/ui/keyboard",
+    "//ios/chrome/browser/ui/list_model:list_model",
     "//ios/chrome/browser/ui/settings:settings_root",
     "//ios/chrome/browser/ui/settings/autofill",
     "//ios/chrome/browser/ui/settings/cells",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm
index 44de4aca..87e91ca 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm
@@ -124,7 +124,7 @@
 
 #pragma mark - AddPasswordMediatorDelegate
 
-- (void)dismissPasswordDetailsTableViewController {
+- (void)dismissAddPasswordTableViewController {
   [self.delegate passwordDetailsTableViewControllerDidFinish:self];
 }
 
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_handler.h b/ios/chrome/browser/ui/settings/password/password_details/add_password_handler.h
index 64c703e..3a3bc52 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/add_password_handler.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_handler.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_HANDLER_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_HANDLER_H_
 
-// Presenter which handles commands from `PasswordDetailsViewController`.
+// Presenter which handles commands from `AddPasswordViewController`.
 @protocol AddPasswordHandler
 
 // Called when the reauthentication protocol is not ready for the
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm
index 5d90f703..b07e012 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm
@@ -100,10 +100,10 @@
   _validationTaskTracker.reset();
 }
 
-#pragma mark - PasswordDetailsTableViewControllerDelegate
+#pragma mark - AddPasswordTableViewControllerDelegate
 
-- (void)passwordDetailsViewController:(AddPasswordViewController*)viewController
-               didEditPasswordDetails:(PasswordDetails*)password {
+- (void)addPasswordViewController:(AddPasswordViewController*)viewController
+           didEditPasswordDetails:(PasswordDetails*)password {
   NOTREACHED();
 }
 
@@ -131,7 +131,7 @@
 
   _manager->GetSavedPasswordsPresenter()->AddCredential(credential);
   [self.delegate setUpdatedPassword:credential];
-  [self.delegate dismissPasswordDetailsTableViewController];
+  [self.delegate dismissAddPasswordTableViewController];
 }
 
 - (void)checkForDuplicates:(NSString*)username {
@@ -171,7 +171,7 @@
 }
 
 - (void)didCancelAddPasswordDetails {
-  [self.delegate dismissPasswordDetailsTableViewController];
+  [self.delegate dismissAddPasswordTableViewController];
 }
 
 - (void)setWebsiteURL:(NSString*)website {
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator_delegate.h
index bc7f6f1..19c131e 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator_delegate.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator_delegate.h
@@ -12,8 +12,8 @@
 // Delegate for AddPasswordMediator.
 @protocol AddPasswordMediatorDelegate
 
-// Called when the password details view controller is to be dismissed.
-- (void)dismissPasswordDetailsTableViewController;
+// Called when the add password view controller is to be dismissed.
+- (void)dismissAddPasswordTableViewController;
 
 // Called after a new credential is added or an existing one is updated via the
 // add credential flow.
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_details/add_password_view_controller_unittest.mm
index 833eb91..168234b 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/add_password_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_view_controller_unittest.mm
@@ -45,7 +45,7 @@
 
 @end
 
-// Test class that conforms to PasswordDetailsViewControllerDelegate in order to
+// Test class that conforms to AddPasswordViewControllerDelegate in order to
 // test the delegate methods are called correctly.
 @interface FakeAddPasswordDelegate
     : NSObject <AddPasswordViewControllerDelegate>
@@ -56,8 +56,8 @@
 
 @implementation FakeAddPasswordDelegate
 
-- (void)passwordDetailsViewController:(AddPasswordViewController*)viewController
-               didEditPasswordDetails:(PasswordDetails*)password {
+- (void)addPasswordViewController:(AddPasswordViewController*)viewController
+           didEditPasswordDetails:(PasswordDetails*)password {
   self.password = password;
 }
 
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details.h b/ios/chrome/browser/ui/settings/password/password_details/password_details.h
index 87f10fb..062c055 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details.h
@@ -7,20 +7,36 @@
 
 #import <Foundation/Foundation.h>
 
+#import "ios/chrome/browser/ui/list_model/list_model.h"
 #include "url/gurl.h"
 
 namespace password_manager {
 struct CredentialUIEntry;
 }  // namespace password_manager
 
+// Represents the credential type (blocked, federated or regular) of the
+// credential in this Password Details.
+typedef NS_ENUM(NSInteger, CredentialType) {
+  CredentialTypeRegular = kItemTypeEnumZero,
+  CredentialTypeBlocked,
+  CredentialTypeFederation,
+};
+
 // Object which is used by `PasswordDetailsViewController` to show
 // information about password.
 @interface PasswordDetails : NSObject
 
+// Represents the type of the credential (blocked, federated or regular).
+@property(nonatomic, assign) CredentialType credentialType;
+
+// Associated sign-on realm used as identifier for this object.
+@property(nonatomic, copy, readonly) NSString* signonRealm;
+
 // Short version of website.
 @property(nonatomic, copy, readonly) NSString* origin;
 
-// Associated website.
+// Associated website. It is determined by either the sign-on realm or the
+// display name of the Android app.
 @property(nonatomic, copy, readonly) NSString* website;
 
 // Associated username.
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm
index 0ac906b8..3a45b886 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm
@@ -20,6 +20,8 @@
     (const password_manager::CredentialUIEntry&)credential {
   self = [super init];
   if (self) {
+    _signonRealm = [NSString
+        stringWithUTF8String:credential.GetFirstSignonRealm().c_str()];
     auto facetUri = password_manager::FacetURI::FromPotentiallyInvalidSpec(
         credential.GetFirstSignonRealm());
     if (facetUri.IsValidAndroidFacetURI()) {
@@ -52,6 +54,13 @@
       _federation =
           base::SysUTF8ToNSString(credential.federation_origin.host());
     }
+
+    _credentialType = credential.blocked_by_user ? CredentialTypeBlocked
+                                                 : CredentialTypeRegular;
+    if (_credentialType == CredentialTypeRegular &&
+        !credential.federation_origin.opaque()) {
+      _credentialType = CredentialTypeFederation;
+    }
   }
   return self;
 }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h
index 35ec30e..4a7b35c 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h
@@ -12,8 +12,10 @@
 // Sets the Password details for consumer.
 @protocol PasswordDetailsConsumer <NSObject>
 
-// Displays provided password details.
-- (void)setPassword:(PasswordDetails*)password;
+// Displays provided array of password details and the title for the Password
+// Details view.
+- (void)setPasswords:(NSArray<PasswordDetails*>*)passwords
+            andTitle:(NSString*)title;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h
index 0408289..6c0b403 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
 namespace password_manager {
+class AffiliatedGroup;
 struct CredentialUIEntry;
 }  // namespace password_manager
 
@@ -31,6 +32,16 @@
                 passwordCheckManager:(IOSChromePasswordCheckManager*)manager
     NS_DESIGNATED_INITIALIZER;
 
+- (instancetype)
+    initWithBaseNavigationController:
+        (UINavigationController*)navigationController
+                             browser:(Browser*)browser
+                     affiliatedGroup:(const password_manager::AffiliatedGroup&)
+                                         affiliatedGroup
+                        reauthModule:(ReauthenticationModule*)reauthModule
+                passwordCheckManager:(IOSChromePasswordCheckManager*)manager
+    NS_DESIGNATED_INITIALIZER;
+
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
                                    browser:(Browser*)browser NS_UNAVAILABLE;
 
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
index 0684840a..9b21d86 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -8,6 +8,7 @@
 #import "base/metrics/histogram_functions.h"
 #import "base/strings/sys_string_conversions.h"
 #import "components/password_manager/core/browser/password_manager_metrics_util.h"
+#import "components/password_manager/core/browser/ui/affiliated_group.h"
 #import "components/password_manager/core/browser/ui/credential_ui_entry.h"
 #import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/main/browser.h"
@@ -32,6 +33,7 @@
 #endif
 
 @interface PasswordDetailsCoordinator () <PasswordDetailsHandler> {
+  password_manager::AffiliatedGroup _affiliatedGroup;
   password_manager::CredentialUIEntry _credential;
 
   // Manager responsible for password check feature.
@@ -48,10 +50,6 @@
 // passwords.
 @property(nonatomic, weak) ReauthenticationModule* reauthenticationModule;
 
-// Denotes the type of the credential passed to this coordinator. Could be
-// blocked, federated, new or regular.
-@property(nonatomic, assign) CredentialType credentialType;
-
 // Modal alert for interactions with password.
 @property(nonatomic, strong) AlertCoordinator* alertCoordinator;
 
@@ -83,23 +81,51 @@
     _credential = credential;
     _manager = manager;
     _reauthenticationModule = reauthModule;
-    _credentialType = credential.blocked_by_user ? CredentialTypeBlocked
-                                                 : CredentialTypeRegular;
-    if (_credentialType == CredentialTypeRegular &&
-        !credential.federation_origin.opaque()) {
-      _credentialType = CredentialTypeFederation;
-    }
+  }
+  return self;
+}
+
+- (instancetype)
+    initWithBaseNavigationController:
+        (UINavigationController*)navigationController
+                             browser:(Browser*)browser
+                     affiliatedGroup:(const password_manager::AffiliatedGroup&)
+                                         affiliatedGroup
+                        reauthModule:(ReauthenticationModule*)reauthModule
+                passwordCheckManager:(IOSChromePasswordCheckManager*)manager {
+  self = [super initWithBaseViewController:navigationController
+                                   browser:browser];
+  if (self) {
+    DCHECK(navigationController);
+    DCHECK(manager);
+
+    _baseNavigationController = navigationController;
+    _affiliatedGroup = affiliatedGroup;
+    _manager = manager;
+    _reauthenticationModule = reauthModule;
   }
   return self;
 }
 
 - (void)start {
-  self.viewController = [[PasswordDetailsTableViewController alloc]
-      initWithCredentialType:_credentialType
-            syncingUserEmail:nil];
+  self.viewController =
+      [[PasswordDetailsTableViewController alloc] initWithSyncingUserEmail:nil];
 
-  self.mediator = [[PasswordDetailsMediator alloc] initWithPassword:_credential
-                                               passwordCheckManager:_manager];
+  std::vector<password_manager::CredentialUIEntry> credentials;
+  NSString* displayName;
+  if (_affiliatedGroup.GetCredentials().size() > 0) {
+    displayName = [NSString
+        stringWithUTF8String:_affiliatedGroup.GetDisplayName().c_str()];
+    for (const auto& credentialGroup : _affiliatedGroup.GetCredentials()) {
+      credentials.push_back(credentialGroup);
+    }
+  } else {
+    credentials.push_back(_credential);
+  }
+
+  self.mediator = [[PasswordDetailsMediator alloc] initWithPasswords:credentials
+                                                         displayName:displayName
+                                                passwordCheckManager:_manager];
   self.mediator.consumer = self.viewController;
   self.viewController.handler = self;
   self.viewController.delegate = self.mediator;
@@ -232,8 +258,9 @@
 
 // Notifies delegate about password deletion and records metric if needed.
 - (void)passwordDeletionConfirmedForCompromised:(BOOL)compromised {
+  // TODO(crbug.com/1358988): Fix logic here.
   [self.delegate passwordDetailsCoordinator:self
-                           deleteCredential:self.mediator.credential];
+                           deleteCredential:self.mediator.credentials[0]];
   if (compromised) {
     base::UmaHistogramEnumeration(
         "PasswordManager.BulkCheck.UserAction",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
index a631455..7e53d80 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
@@ -7,6 +7,7 @@
 
 #import <Foundation/Foundation.h>
 
+#import "base/mac/foundation_util.h"
 #import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h"
 
 namespace password_manager {
@@ -20,11 +21,14 @@
 @interface PasswordDetailsMediator
     : NSObject <PasswordDetailsTableViewControllerDelegate>
 
-// CredentialUIEntry is converted to the PasswordDetails and passed to a
-// consumer.
-- (instancetype)initWithPassword:
-                    (const password_manager::CredentialUIEntry&)credential
-            passwordCheckManager:(IOSChromePasswordCheckManager*)manager
+// Vector of CredentialUIEntry is converted to an array of PasswordDetails and
+// passed to a consumer with the display name (title) for the Password Details
+// view.
+- (instancetype)initWithPasswords:
+                    (const std::vector<password_manager::CredentialUIEntry>&)
+                        credentials
+                      displayName:(NSString*)displayName
+             passwordCheckManager:(IOSChromePasswordCheckManager*)manager
     NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
@@ -32,8 +36,9 @@
 // Consumer of this mediator.
 @property(nonatomic, weak) id<PasswordDetailsConsumer> consumer;
 
-// Password passed to the mediator.
-@property(nonatomic, readonly) password_manager::CredentialUIEntry credential;
+// Array of credentials passed to the mediator.
+@property(nonatomic, readonly) std::vector<password_manager::CredentialUIEntry>
+    credentials;
 
 // Disconnects the mediator from all observers.
 - (void)disconnect;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
index cb575e68..215db9b 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -31,28 +31,36 @@
 // List of the usernames for the same domain.
 @property(nonatomic, strong) NSSet<NSString*>* usernamesWithSameDomain;
 
+// Display name to use for the Password Details view.
+@property(nonatomic, strong) NSString* displayName;
+
 @end
 
 @implementation PasswordDetailsMediator
 
-- (instancetype)initWithPassword:
-                    (const password_manager::CredentialUIEntry&)credential
-            passwordCheckManager:(IOSChromePasswordCheckManager*)manager {
+- (instancetype)initWithPasswords:
+                    (const std::vector<password_manager::CredentialUIEntry>&)
+                        credentials
+                      displayName:(NSString*)displayName
+             passwordCheckManager:(IOSChromePasswordCheckManager*)manager {
   self = [super init];
   if (self) {
     _manager = manager;
-    _credential = credential;
+    _credentials = credentials;
+    _displayName = displayName;
     _passwordCheckObserver.reset(
         new PasswordCheckObserverBridge(self, manager));
+    DCHECK(!_credentials.empty());
     NSMutableSet<NSString*>* usernames = [[NSMutableSet alloc] init];
-    auto credentials =
+    auto savedCredentials =
         manager->GetSavedPasswordsPresenter()->GetSavedCredentials();
-    for (const auto& cred : credentials) {
-      if (cred.GetFirstSignonRealm() == credential.GetFirstSignonRealm()) {
+    for (const auto& cred : savedCredentials) {
+      // TODO(crbug.com/1358979): Fix usernames logic.
+      if (cred.GetFirstSignonRealm() == _credentials[0].GetFirstSignonRealm()) {
         [usernames addObject:base::SysUTF16ToNSString(cred.username)];
       }
     }
-    [usernames removeObject:base::SysUTF16ToNSString(credential.username)];
+    [usernames removeObject:base::SysUTF16ToNSString(_credentials[0].username)];
     _usernamesWithSameDomain = usernames;
   }
   return self;
@@ -76,13 +84,30 @@
             (PasswordDetailsTableViewController*)viewController
                didEditPasswordDetails:(PasswordDetails*)password {
   if ([password.password length] != 0) {
-    password_manager::CredentialUIEntry updated_credential = _credential;
+    password_manager::CredentialUIEntry original_credential;
+
+    auto it = std::find_if(
+        _credentials.begin(), _credentials.end(),
+        [password](password_manager::CredentialUIEntry credential) {
+          return [password.signonRealm
+              isEqualToString:[NSString stringWithUTF8String:
+                                            credential.GetFirstSignonRealm()
+                                                .c_str()]];
+        });
+
+    // There should be no reason not to find the credential in the vector of
+    // credentials.
+    DCHECK(it != _credentials.end());
+
+    original_credential = *it;
+    password_manager::CredentialUIEntry updated_credential =
+        original_credential;
     updated_credential.username = SysNSStringToUTF16(password.username);
     updated_credential.password = SysNSStringToUTF16(password.password);
     if (_manager->GetSavedPasswordsPresenter()->EditSavedCredentials(
-            _credential, updated_credential) ==
+            original_credential, updated_credential) ==
         password_manager::SavedPasswordsPresenter::EditResult::kSuccess) {
-      _credential = updated_credential;
+      *it = std::move(updated_credential);
       return;
     }
   }
@@ -142,10 +167,14 @@
 // Updates password details and sets it to a consumer.
 - (void)fetchPasswordWith:
     (const std::vector<password_manager::CredentialUIEntry>&)credentials {
-  PasswordDetails* password =
-      [[PasswordDetails alloc] initWithCredential:_credential];
-  password.compromised = base::Contains(credentials, _credential);
-  [self.consumer setPassword:password];
+  NSMutableArray<PasswordDetails*>* passwords = [NSMutableArray array];
+  for (password_manager::CredentialUIEntry credential : _credentials) {
+    PasswordDetails* password =
+        [[PasswordDetails alloc] initWithCredential:credential];
+    password.compromised = base::Contains(credentials, credential);
+    [passwords addObject:password];
+  }
+  [self.consumer setPasswords:passwords andTitle:_displayName];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
index 1182b4e0..55de4ca 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
@@ -16,23 +16,15 @@
 @protocol ReauthenticationProtocol;
 @protocol SnackbarCommands;
 
-// Denotes the credential type that is being displayed by the view controller.
-typedef NS_ENUM(NSInteger, CredentialType) {
-  CredentialTypeRegular = kItemTypeEnumZero,
-  CredentialTypeBlocked,
-  CredentialTypeFederation,
-};
-
 // Screen which shows password details and allows to edit it.
 @interface PasswordDetailsTableViewController
     : AutofillEditTableViewController <AddPasswordDetailsConsumer,
                                        PasswordDetailsConsumer>
 
 // The designated initializer.
-// `syncingUserEmail` stores the user email if the user is authenticated amd
+// `syncingUserEmail` stores the user email if the user is authenticated and
 // syncing passwords.
-- (instancetype)initWithCredentialType:(CredentialType)credentialType
-                      syncingUserEmail:(NSString*)syncingUserEmail
+- (instancetype)initWithSyncingUserEmail:(NSString*)syncingUserEmail
     NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
index 3840e9c..c607b48 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -89,9 +89,15 @@
 
 @interface PasswordDetailsTableViewController () <TableViewTextEditItemDelegate>
 
+// Array of passwords that are shown on the screen.
+@property(nonatomic, strong) NSArray<PasswordDetails*>* passwords;
+
 // Password which is shown on the screen.
+// TODO(crbug.com/1358979): Remove this.
 @property(nonatomic, strong) PasswordDetails* password;
 
+@property(nonatomic, strong) NSString* pageTitle;
+
 // Whether the password is shown in plain text form or in masked form.
 @property(nonatomic, assign, getter=isPasswordShown) BOOL passwordShown;
 
@@ -108,10 +114,6 @@
 // image icon in the `usernameTextItem` cell.
 @property(nonatomic, weak) UIView* usernameErrorAnchorView;
 
-// Denotes the type of the credential passed to this coordinator. Could be
-// blocked, federated, new or regular.
-@property(nonatomic, assign) CredentialType credentialType;
-
 // If YES, denotes that the credential with the same website/username
 // combination already exists. Used when creating a new credential.
 @property(nonatomic, assign) BOOL isDuplicatedCredential;
@@ -136,11 +138,9 @@
 
 #pragma mark - ViewController Life Cycle.
 
-- (instancetype)initWithCredentialType:(CredentialType)credentialType
-                      syncingUserEmail:(NSString*)syncingUserEmail {
+- (instancetype)initWithSyncingUserEmail:(NSString*)syncingUserEmail {
   self = [super initWithStyle:ChromeTableViewStyle()];
   if (self) {
-    _credentialType = credentialType;
     _isDuplicatedCredential = NO;
     _shouldEnableSave = NO;
     _showPasswordWithoutAuth = NO;
@@ -162,7 +162,9 @@
     titleLabel.font =
         [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
     titleLabel.adjustsFontForContentSizeCategory = YES;
-    titleLabel.text = self.password.origin;
+    titleLabel.text = (self.pageTitle && self.pageTitle.length > 0)
+                          ? self.pageTitle
+                          : self.password.origin;
     self.navigationItem.titleView = titleLabel;
 }
 
@@ -225,17 +227,13 @@
   [model addSectionWithIdentifier:SectionIdentifierTLDFooter];
 
   [model addSectionWithIdentifier:SectionIdentifierPassword];
-  // Blocked passwords don't have username and password value.
-  if (self.credentialType != CredentialTypeBlocked) {
-    self.usernameTextItem = [self usernameItem];
-    [model addItem:self.usernameTextItem
-        toSectionWithIdentifier:SectionIdentifierPassword];
 
-    if (self.credentialType == CredentialTypeFederation) {
-      // Federated password forms don't have password value.
-      [model addItem:[self federationItem]
+  switch (self.password.credentialType) {
+    case CredentialTypeRegular: {
+      self.usernameTextItem = [self usernameItem];
+      [model addItem:self.usernameTextItem
           toSectionWithIdentifier:SectionIdentifierPassword];
-    } else {
+
       self.passwordTextItem = [self passwordItem];
       [model addItem:self.passwordTextItem
           toSectionWithIdentifier:SectionIdentifierPassword];
@@ -262,6 +260,21 @@
               toSectionWithIdentifier:SectionIdentifierCompromisedInfo];
         }
       }
+      break;
+    }
+    case CredentialTypeFederation: {
+      self.usernameTextItem = [self usernameItem];
+      [model addItem:self.usernameTextItem
+          toSectionWithIdentifier:SectionIdentifierPassword];
+
+      // Federated password forms don't have password value.
+      [model addItem:[self federationItem]
+          toSectionWithIdentifier:SectionIdentifierPassword];
+      break;
+    }
+
+    case CredentialTypeBlocked: {
+      break;
     }
   }
 }
@@ -297,7 +310,7 @@
       l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME);
   item.textFieldValue = self.password.username;  // Empty for a new form.
   // If password is missing (federated credential) don't allow to edit username.
-  if (self.credentialType != CredentialTypeFederation) {
+  if (self.password.credentialType != CredentialTypeFederation) {
     item.textFieldEnabled = self.tableView.editing;
     item.hideIcon = !self.tableView.editing;
     item.autoCapitalizationType = UITextAutocapitalizationTypeNone;
@@ -665,8 +678,16 @@
 
 #pragma mark - PasswordDetailsConsumer
 
-- (void)setPassword:(PasswordDetails*)password {
-  _password = password;
+- (void)setPasswords:(NSArray<PasswordDetails*>*)passwords
+            andTitle:(NSString*)title {
+  _passwords = passwords;
+  _pageTitle = title;
+
+  // TODO(crbug.com/1358979): Use first password until we implement this.
+  if (_passwords.count >= 1) {
+    _password = _passwords[0];
+  }
+
   [self reloadData];
 }
 
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm
index 5af84b8f..69725d25 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm
@@ -171,8 +171,7 @@
   ChromeTableViewController* InstantiateController() override {
     PasswordDetailsTableViewController* controller =
         [[PasswordDetailsTableViewController alloc]
-            initWithCredentialType:credential_type_
-                  syncingUserEmail:syncing_user_email_];
+            initWithSyncingUserEmail:syncing_user_email_];
     controller.handler = handler_;
     controller.delegate = delegate_;
     controller.reauthModule = reauthentication_module_;
@@ -193,13 +192,15 @@
     form.username_element = u"email";
     form.scheme = password_manager::PasswordForm::Scheme::kHtml;
 
+    NSMutableArray<PasswordDetails*>* passwords = [NSMutableArray array];
     PasswordDetails* passwordDetails = [[PasswordDetails alloc]
         initWithCredential:password_manager::CredentialUIEntry(form)];
     passwordDetails.compromised = isCompromised;
+    [passwords addObject:passwordDetails];
 
     PasswordDetailsTableViewController* passwords_controller =
         static_cast<PasswordDetailsTableViewController*>(controller());
-    [passwords_controller setPassword:passwordDetails];
+    [passwords_controller setPasswords:passwords andTitle:nil];
   }
 
   void SetFederatedPassword() {
@@ -210,11 +211,13 @@
     form.signon_realm = form.url.spec();
     form.federation_origin =
         url::Origin::Create(GURL("http://www.example.com/"));
+    NSMutableArray<PasswordDetails*>* passwords = [NSMutableArray array];
     PasswordDetails* password = [[PasswordDetails alloc]
         initWithCredential:password_manager::CredentialUIEntry(form)];
+    [passwords addObject:password];
     PasswordDetailsTableViewController* passwords_controller =
         static_cast<PasswordDetailsTableViewController*>(controller());
-    [passwords_controller setPassword:password];
+    [passwords_controller setPasswords:passwords andTitle:nil];
   }
 
   void SetBlockedOrigin() {
@@ -223,11 +226,13 @@
     form.url = GURL("http://www.example.com/");
     form.blocked_by_user = true;
     form.signon_realm = form.url.spec();
+    NSMutableArray<PasswordDetails*>* passwords = [NSMutableArray array];
     PasswordDetails* password = [[PasswordDetails alloc]
         initWithCredential:password_manager::CredentialUIEntry(form)];
+    [passwords addObject:password];
     PasswordDetailsTableViewController* passwords_controller =
         static_cast<PasswordDetailsTableViewController*>(controller());
-    [passwords_controller setPassword:password];
+    [passwords_controller setPasswords:passwords andTitle:nil];
   }
 
   void CheckEditCellText(NSString* expected_text, int section, int item) {
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm
index a927e07..74feca4 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm
@@ -2225,11 +2225,19 @@
     case ItemTypeSavedPassword: {
       DCHECK_EQ(SectionIdentifierSavedPasswords,
                 [model sectionIdentifierForSectionIndex:indexPath.section]);
-      password_manager::CredentialUIEntry credential =
-          base::mac::ObjCCastStrict<PasswordFormContentItem>(
-              [model itemAtIndexPath:indexPath])
-              .credential;
-      [self.handler showDetailedViewForCredential:credential];
+      if (IsPasswordGroupingEnabled()) {
+        password_manager::AffiliatedGroup affiliatedGroup =
+            base::mac::ObjCCastStrict<PasswordFormContentItem>(
+                [model itemAtIndexPath:indexPath])
+                .affiliatedGroup;
+        [self.handler showDetailedViewForAffiliatedGroup:affiliatedGroup];
+      } else {
+        password_manager::CredentialUIEntry credential =
+            base::mac::ObjCCastStrict<PasswordFormContentItem>(
+                [model itemAtIndexPath:indexPath])
+                .credential;
+        [self.handler showDetailedViewForCredential:credential];
+      }
       break;
     }
     case ItemTypeBlocked: {
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
index dab380b7..1b649ed 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
@@ -191,6 +191,19 @@
   [self.passwordDetailsCoordinator start];
 }
 
+- (void)showDetailedViewForAffiliatedGroup:
+    (const password_manager::AffiliatedGroup&)affiliatedGroup {
+  DCHECK(!self.passwordDetailsCoordinator);
+  self.passwordDetailsCoordinator = [[PasswordDetailsCoordinator alloc]
+      initWithBaseNavigationController:self.baseNavigationController
+                               browser:self.browser
+                       affiliatedGroup:affiliatedGroup
+                          reauthModule:self.reauthModule
+                  passwordCheckManager:[self passwordCheckManager].get()];
+  self.passwordDetailsCoordinator.delegate = self;
+  [self.passwordDetailsCoordinator start];
+}
+
 - (void)showAddPasswordSheet {
   DCHECK(!self.addPasswordCoordinator);
   self.addPasswordCoordinator = [[AddPasswordCoordinator alloc]
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_commands.h b/ios/chrome/browser/ui/settings/password/passwords_settings_commands.h
index af36b46..80deba6 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_settings_commands.h
+++ b/ios/chrome/browser/ui/settings/password/passwords_settings_commands.h
@@ -17,10 +17,14 @@
 // Shows the screen with password issues.
 - (void)showCompromisedPasswords;
 
-// Shows passwords details.
+// Shows passwords details for blocked passwords.
 - (void)showDetailedViewForCredential:
     (const password_manager::CredentialUIEntry&)credential;
 
+// Shows passwords details for saved passwords.
+- (void)showDetailedViewForAffiliatedGroup:
+    (const password_manager::AffiliatedGroup&)affiliatedGroup;
+
 // Shows form to manually enter new password credentials.
 - (void)showAddPasswordSheet;
 
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index 908206a..2bfcb21 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -31,7 +31,7 @@
 #import "components/sync/driver/sync_service.h"
 #import "ios/chrome/browser/application_context/application_context.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/commerce/price_alert_util.h"
+#import "ios/chrome/browser/commerce/push_notification/push_notification_feature.h"
 #import "ios/chrome/browser/flags/system_flags.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/net/crurl.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/BUILD.gn
index 51a46f5..5e338314 100644
--- a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/BUILD.gn
@@ -5,14 +5,19 @@
 source_set("pinned_tabs_ui") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "pinned_cell.h",
+    "pinned_cell.mm",
     "pinned_tabs_constants.h",
     "pinned_tabs_constants.mm",
+    "pinned_tabs_layout.h",
+    "pinned_tabs_layout.mm",
     "pinned_tabs_view_controller.h",
     "pinned_tabs_view_controller.mm",
   ]
   deps = [
     ":features",
     "//ios/chrome/browser/ui/tab_switcher",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui",
     "//ios/chrome/common/ui/colors",
   ]
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.h b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.h
new file mode 100644
index 0000000..1e3479f
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.h
@@ -0,0 +1,28 @@
+// 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 IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_CELL_H_
+#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_CELL_H_
+
+#import <UIKit/UIKit.h>
+
+// A cell for the pinned tabs view. Contains an icon, title, snapshot.
+@interface PinnedCell : UICollectionViewCell
+
+// Unique identifier for the cell's contents. This is used to ensure that
+// updates in an asynchronous callback are only made if the item is the same.
+@property(nonatomic, copy) NSString* itemIdentifier;
+// View for displaying the favicon.
+@property(nonatomic, strong) UIImageView* faviconView;
+// Title is displayed by this label.
+@property(nonatomic, strong) UILabel* titleLabel;
+
+// Checks if cell has a specific identifier.
+- (BOOL)hasIdentifier:(NSString*)identifier;
+
+@property(nonatomic, readonly) UIDragPreviewParameters* dragPreviewParameters;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_CELL_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.mm b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.mm
new file mode 100644
index 0000000..ce21672
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.mm
@@ -0,0 +1,95 @@
+// 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.
+
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.h"
+
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h"
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Default favicon image.
+NSString* const kDefaultFaviconImage = @"default_world_favicon";
+
+}  // namespace
+
+@implementation PinnedCell
+
+- (instancetype)initWithFrame:(CGRect)frame {
+  if ((self = [super initWithFrame:frame])) {
+    self.contentView.layer.cornerRadius = kPinnedCellCornerRadius;
+    self.contentView.backgroundColor = [UIColor colorNamed:kGrey800Color];
+
+    [self setupFaviconView];
+    [self setupTitleLabel];
+  }
+  return self;
+}
+
+- (void)prepareForReuse {
+  [super prepareForReuse];
+  self.titleLabel.text = nil;
+  self.itemIdentifier = nil;
+  self.faviconView = nil;
+}
+
+#pragma mark - Public
+
+- (UIDragPreviewParameters*)dragPreviewParameters {
+  UIBezierPath* visiblePath = [UIBezierPath
+      bezierPathWithRoundedRect:self.bounds
+                   cornerRadius:self.contentView.layer.cornerRadius];
+  UIDragPreviewParameters* params = [[UIDragPreviewParameters alloc] init];
+  params.visiblePath = visiblePath;
+  return params;
+}
+
+- (BOOL)hasIdentifier:(NSString*)identifier {
+  return [self.itemIdentifier isEqualToString:identifier];
+}
+
+#pragma mark - Private
+
+// Sets up the favicon view.
+- (void)setupFaviconView {
+  UIImage* favicon = [[UIImage imageNamed:kDefaultFaviconImage]
+      imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+  _faviconView = [[UIImageView alloc] initWithImage:favicon];
+  [self.contentView addSubview:_faviconView];
+
+  _faviconView.translatesAutoresizingMaskIntoConstraints = NO;
+  [NSLayoutConstraint activateConstraints:@[
+    [_faviconView.leadingAnchor
+        constraintEqualToAnchor:self.contentView.leadingAnchor
+                       constant:kPinnedCellHorizontalPadding],
+    [_faviconView.centerYAnchor
+        constraintEqualToAnchor:self.contentView.centerYAnchor],
+
+  ]];
+}
+
+// Sets up the title label.
+- (void)setupTitleLabel {
+  _titleLabel = [[UILabel alloc] init];
+  _titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
+  [self.contentView addSubview:_titleLabel];
+
+  _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
+  [NSLayoutConstraint activateConstraints:@[
+    [_titleLabel.leadingAnchor
+        constraintEqualToAnchor:_faviconView.trailingAnchor
+                       constant:kPinnedCellTitleLeadingPadding],
+    [_titleLabel.trailingAnchor
+        constraintLessThanOrEqualToAnchor:self.contentView.trailingAnchor
+                                 constant:-kPinnedCellHorizontalPadding],
+    [_titleLabel.centerYAnchor
+        constraintEqualToAnchor:_faviconView.centerYAnchor],
+  ]];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h
index 1fb4e963..169ce83 100644
--- a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h
@@ -20,4 +20,18 @@
 // Pinned view animations.
 extern const NSTimeInterval kPinnedViewFadeInTime;
 
+// Pinned cell identifier.
+extern NSString* const kPinnedCellIdentifier;
+
+// Pinned cell dimensions.
+extern const CGFloat kPinnedCelldHeight;
+extern const CGFloat kPinnedCelldWidth;
+
+// Pinned cell constraints.
+extern const CGFloat kPinnedCellCornerRadius;
+extern const CGFloat kPinnedCellHorizontalPadding;
+extern const CGFloat kPinnedCellTitleLeadingPadding;
+extern const CGFloat kPinnedCellVerticalLayoutInsets;
+extern const CGFloat kPinnedCellHorizontalLayoutInsets;
+
 #endif  // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_TABS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.mm b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.mm
index 8ea9bad..f06ebef0 100644
--- a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.mm
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.mm
@@ -8,12 +8,31 @@
 #error "This file requires ARC support."
 #endif
 
+// Pinned view dimensions.
 const CGFloat kPinnedViewDragEnabledHeight = 94.0f;
 const CGFloat kPinnedViewDefaultHeight = 68.0f;
 const CGFloat kPinnedViewCornerRadius = 15.0f;
 
+// Pinned view constraints.
 const CGFloat kPinnedViewHorizontalPadding = 6.0f;
 const CGFloat kPinnedViewBottomPadding = 8.0f;
 const CGFloat kPinnedViewTopPadding = 24.0f;
 
+// Pinned view animations.
 const NSTimeInterval kPinnedViewFadeInTime = 0.2;
+
+// Pinned cell identifier.
+NSString* const kPinnedCellIdentifier = @"PinnedCellIdentifier";
+
+// Pinned cell dimensions.
+const CGFloat kPinnedCelldHeight = 36.0f;
+const CGFloat kPinnedCelldWidth = 168.0f;
+
+// Pinned cell constraints.
+const CGFloat kPinnedCellCornerRadius = 15.0f;
+const CGFloat kPinnedCellHorizontalPadding = 8.0f;
+const CGFloat kPinnedCellTitleLeadingPadding = 4.0f;
+
+// Pinned cell collection view layout constraints.
+const CGFloat kPinnedCellVerticalLayoutInsets = 16.0f;
+const CGFloat kPinnedCellHorizontalLayoutInsets = 8.0f;
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.h b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.h
new file mode 100644
index 0000000..b2109bb
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.h
@@ -0,0 +1,14 @@
+// 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 IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_TABS_LAYOUT_H_
+#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_TABS_LAYOUT_H_
+
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/flow_layout.h"
+
+// A specialization of FlowLayout that displays pinned items horizontally.
+@interface PinnedTabsLayout : FlowLayout
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_PINNED_TABS_PINNED_TABS_LAYOUT_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.mm b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.mm
new file mode 100644
index 0000000..885927b
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.mm
@@ -0,0 +1,34 @@
+// 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.
+
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.h"
+
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation PinnedTabsLayout
+
+- (instancetype)init {
+  if (self = [super init]) {
+    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+  }
+  return self;
+}
+
+#pragma mark - UICollectionViewLayout
+
+- (void)prepareLayout {
+  [super prepareLayout];
+
+  self.itemSize = CGSize{kPinnedCelldWidth, kPinnedCelldHeight};
+
+  self.sectionInset = UIEdgeInsets{
+      kPinnedCellVerticalLayoutInsets, kPinnedCellHorizontalLayoutInsets,
+      kPinnedCellVerticalLayoutInsets, kPinnedCellHorizontalLayoutInsets};
+}
+
+@end
diff --git a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_view_controller.mm
index e63f0930..dfff313 100644
--- a/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_view_controller.mm
@@ -4,7 +4,9 @@
 
 #import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_view_controller.h"
 
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_cell.h"
 #import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_constants.h"
+#import "ios/chrome/browser/ui/tab_switcher/pinned_tabs/pinned_tabs_layout.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
index 1ff703e..7420aca8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -953,6 +953,7 @@
 
   const TemplateURL* searchURLTemplate =
       templateURLService->GetDefaultSearchProvider();
+  DCHECK(searchURLTemplate);
 
   TemplateURLRef::SearchTermsArgs searchArgs(
       base::SysNSStringToUTF16(searchText));
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui.mm b/ios/chrome/browser/ui/webui/policy/policy_ui.mm
index f293093..d5d09126 100644
--- a/ios/chrome/browser/ui/webui/policy/policy_ui.mm
+++ b/ios/chrome/browser/ui/webui/policy/policy_ui.mm
@@ -39,6 +39,7 @@
       {"labelAssetId", IDS_POLICY_LABEL_ASSET_ID},
       {"labelClientId", IDS_POLICY_LABEL_CLIENT_ID},
       {"labelDirectoryApiId", IDS_POLICY_LABEL_DIRECTORY_API_ID},
+      {"labelError", IDS_POLICY_LABEL_ERROR},
       {"labelGaiaId", IDS_POLICY_LABEL_GAIA_ID},
       {"labelIsAffiliated", IDS_POLICY_LABEL_IS_AFFILIATED},
       {"labelLastCloudReportSentTimestamp",
@@ -77,6 +78,7 @@
       {"showUnset", IDS_POLICY_SHOW_UNSET},
       {"signinProfile", IDS_POLICY_SIGNIN_PROFILE},
       {"status", IDS_POLICY_STATUS},
+      {"statusErrorManagedNoPolicy", IDS_POLICY_STATUS_ERROR_MANAGED_NO_POLICY},
       {"statusDevice", IDS_POLICY_STATUS_DEVICE},
       {"statusMachine", IDS_POLICY_STATUS_MACHINE},
       {"statusUser", IDS_POLICY_STATUS_USER},
diff --git a/ios/chrome/browser/url_loading/image_search_param_generator.mm b/ios/chrome/browser/url_loading/image_search_param_generator.mm
index ed976936..e9944e5 100644
--- a/ios/chrome/browser/url_loading/image_search_param_generator.mm
+++ b/ios/chrome/browser/url_loading/image_search_param_generator.mm
@@ -66,6 +66,7 @@
 
   const TemplateURL* default_url =
       template_url_service->GetDefaultSearchProvider();
+  DCHECK(default_url);
   DCHECK(!default_url->image_url().empty());
   DCHECK(default_url->image_url_ref().IsValid(
       template_url_service->search_terms_data()));
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index ddd6bc72d..169f407 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -318,6 +318,7 @@
     "//ios/chrome/browser/ui/main_content:unit_tests",
     "//ios/chrome/browser/ui/menu:unit_tests",
     "//ios/chrome/browser/ui/ntp:unit_tests",
+    "//ios/chrome/browser/ui/ntp/metrics:unit_tests",
     "//ios/chrome/browser/ui/omnibox:unit_tests",
     "//ios/chrome/browser/ui/omnibox/popup:unit_tests",
     "//ios/chrome/browser/ui/open_in:unit_tests",
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index adb8d46..bdd77e5 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-f644da71b1badc97b700e1f39441698d0f807085
\ No newline at end of file
+0e33fad2907d043d2653ca39dd860e2fb1dcc905
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index bbe14a4..9da26d6 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-87f0350abeae6847c015810ca486e5f61aa133d8
\ No newline at end of file
+4069dc6955283f4d477fa401629a80be377a2c2f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 7e23dfaf7..983c31d 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b97840e08e063217fe013bf0c345ad8f55fe439d
\ No newline at end of file
+44d8314d87dac36d4e5648461b81ca17ef573840
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index c36d55c..66dd731 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-4b5d35646d24066fd559b30f5574e1b2ad62d1f0
\ No newline at end of file
+aa1567723f68c3274c24f31ae64872ed3e2dd9e7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 95ddc0c..c0cbf73 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-2348c74c761a97dcea7241949573f8f60e5c56ad
\ No newline at end of file
+46afe14638c3d0d4cbef875d85aa44b36d068c63
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index d29a480..10da84d8 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-75c2a7bd07b67cd9c583e52aa3e74f0f202abf36
\ No newline at end of file
+429f55c64c298fe8c4f2200744874327692bb9c8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index 2ad9eef..6686bd9 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a33dfcf9effc21e5b276ca9722ca660757a2cf18
\ No newline at end of file
+960b0a43075d08d68cecab80d659a0cdacd11ca8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 86e9234..ebcc3e2 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-58ffb387e0b174fb8ab4f4cceb2d99f3fd089726
\ No newline at end of file
+5d15dabbf5c9e843d7a7668b3be7f62a3e386d1f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index add9790d..242a6882 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b9046422f6c4e1cb1afd2e1fb9b7f1109f94d53c
\ No newline at end of file
+d5aa2b62ddbc153a9a09be46b7d97f8a832f52b3
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 81557b6..1aa9582 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ac3d95bdbf65bee08d21ebda92ea9e6c30c93c24
\ No newline at end of file
+2a52745107b2401168ffd05896582561ffe7ebd8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 46ae8b5d..6f876f8f 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-c2349acbbd445ea7ac95c4f790d3c831e0a0ef98
\ No newline at end of file
+18c0c825ec69c52fc52797ba1ad8db0250021dfe
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index df21c9c42..018ffce 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-1cd41144ff2201c9bcff61dd07adbb25f2870b1c
\ No newline at end of file
+ea76d325c903f0180f859e885653556b04f1d516
\ No newline at end of file
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 88e06b8..0b417c6 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -903,6 +903,8 @@
 
   // Copy all metadata to the wrapped frame->
   wrapping_frame->metadata().MergeMetadataFrom(frame->metadata());
+  wrapping_frame->set_color_space(frame->ColorSpace());
+  wrapping_frame->set_hdr_metadata(frame->hdr_metadata());
 
   if (frame->IsMappable()) {
     for (size_t i = 0; i < new_plane_count; ++i) {
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc
index f64dc0ac..ffecc9f 100644
--- a/media/gpu/android/media_codec_video_decoder.cc
+++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -1028,13 +1028,6 @@
   if (drain_type_ || deferred_flush_pending_)
     return true;
 
-  // Record the frame type that we're sending and some information about why.
-  UMA_HISTOGRAM_ENUMERATION(
-      "Media.AVDA.FrameInformation", cached_frame_information_,
-      static_cast<int>(
-          SurfaceChooserHelper::FrameInformation::FRAME_INFORMATION_MAX) +
-          1);  // PRESUBMIT_IGNORE_UMA_MAX
-
   // If we're getting outputs larger than our configured size, we run the risk
   // of exceeding MediaCodec's allowed input buffer size. Update the coded size
   // as we go to ensure we can correctly reconfigure if needed later.
@@ -1083,12 +1076,6 @@
   DVLOG(3) << __func__ << " : "
            << (frame ? frame->AsHumanReadableString() : "null");
 
-  // Record how long this frame was pending.
-  const base::TimeDelta duration = base::TimeTicks::Now() - started_at;
-  UMA_HISTOGRAM_CUSTOM_TIMES("Media.MCVD.ForwardVideoFrameTiming", duration,
-                             base::Milliseconds(1), base::Milliseconds(100),
-                             25);
-
   // Attach the HDR metadata if the color space got this far and is still an HDR
   // color space.  Note that it might be converted to something else along the
   // way, often sRGB.  In that case, don't confuse things with HDR metadata.
diff --git a/media/mojo/clients/mojo_renderer_unittest.cc b/media/mojo/clients/mojo_renderer_unittest.cc
index 36cb66f2..682b837 100644
--- a/media/mojo/clients/mojo_renderer_unittest.cc
+++ b/media/mojo/clients/mojo_renderer_unittest.cc
@@ -40,6 +40,7 @@
 using ::base::test::RunOnceClosure;
 using ::testing::_;
 using ::testing::DoAll;
+using ::testing::InvokeWithoutArgs;
 using ::testing::Return;
 using ::testing::SaveArg;
 using ::testing::StrictMock;
@@ -474,9 +475,6 @@
   Destroy();
 }
 
-// TODO(xhwang): Add more tests on OnError. For example, ErrorDuringFlush,
-// ErrorAfterFlush etc.
-
 TEST_F(MojoRendererTest, ErrorDuringPlayback) {
   Initialize();
 
@@ -492,4 +490,28 @@
   Flush();
 }
 
+TEST_F(MojoRendererTest, ErrorBeforeFlush) {
+  Initialize();
+  Play();
+
+  EXPECT_CALL(renderer_client_, OnError(HasStatusCode(PIPELINE_ERROR_DECODE)))
+      .Times(1);
+  remote_renderer_client_->OnError(PIPELINE_ERROR_DECODE);
+  Flush();
+}
+
+TEST_F(MojoRendererTest, ErrorDuringFlush) {
+  Initialize();
+  Play();
+
+  EXPECT_CALL(renderer_client_, OnError(HasStatusCode(PIPELINE_ERROR_DECODE)))
+      .Times(1);
+  EXPECT_CALL(*mock_renderer_, OnFlush(_))
+      .WillOnce(DoAll(InvokeWithoutArgs([&]() {
+                        remote_renderer_client_->OnError(PIPELINE_ERROR_DECODE);
+                      }),
+                      RunOnceClosure<0>()));
+  Flush();
+}
+
 }  // namespace media
diff --git a/media/mojo/clients/win/media_foundation_renderer_client.cc b/media/mojo/clients/win/media_foundation_renderer_client.cc
index 7f1aa79..3094cf4 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client.cc
+++ b/media/mojo/clients/win/media_foundation_renderer_client.cc
@@ -127,82 +127,6 @@
           weak_factory_.GetWeakPtr()));
 }
 
-void MediaFoundationRendererClient::InitializeFramePool(
-    mojom::FramePoolInitializationParametersPtr pool_info) {
-  DCHECK_GT(pool_info->frame_textures.size(), static_cast<size_t>(0));
-
-  // Release our references to the video pool so that once the
-  // rendering is complete the memory will be freed.
-  video_frame_pool_.clear();
-
-  for (const auto& frame_info : pool_info->frame_textures) {
-    dcomp_texture_wrapper_->CreateVideoFrame(
-        pool_info->texture_size, std::move(frame_info->texture_handle),
-        base::BindOnce(
-            [](base::flat_map<base::UnguessableToken,
-                              scoped_refptr<VideoFrame>>& video_frame_pool,
-               const base::UnguessableToken& token,
-               scoped_refptr<VideoFrame> video_frame) {
-              video_frame_pool.insert({token, std::move(video_frame)});
-            },
-            std::ref(video_frame_pool_), frame_info->token));
-  }
-}
-
-bool MediaFoundationRendererClient::IsFrameServerMode() const {
-  return rendering_mode_ == MediaFoundationRenderingMode::FrameServer;
-}
-
-void MediaFoundationRendererClient::OnFrameAvailable(
-    const base::UnguessableToken& frame_token,
-    const gfx::Size& size,
-    base::TimeDelta timestamp) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(has_video_);
-
-  auto video_frame = video_frame_pool_.find(frame_token);
-  // It is possible to become unsynced when we are reinitializing the frame
-  // pool so we are just checking to make sure the frame has been acquired.
-  if (video_frame == video_frame_pool_.end()) {
-    return;
-  }
-
-  scoped_refptr<VideoFrame> texture_pool_video_frame = video_frame->second;
-
-  texture_pool_video_frame->set_timestamp(timestamp);
-
-  // The Video Frame object's Destruction Observer is called when the video
-  // frame is no longer needed and the underlying texture can be reused. We
-  // cannot use the video frame we created in InitializeFramePool() directly
-  // because we hold onto a reference in our video frame pool so the callback
-  // would not be called, and for those their callback is to destroy the shared
-  // image anyway. Therefore we wrap the shared image based video frame in
-  // another video frame and add the callback which allows us to reuse the
-  // texture for a new video frame.
-  scoped_refptr<VideoFrame> frame = VideoFrame::WrapVideoFrame(
-      texture_pool_video_frame, texture_pool_video_frame->format(),
-      gfx::Rect(size), size);
-  frame->metadata().wants_promotion_hint = true;
-  frame->metadata().allow_overlay = true;
-  frame->AddDestructionObserver(base::BindPostTask(
-      media_task_runner_,
-      base::BindOnce(&MediaFoundationRendererClient::OnPaintComplete,
-                     weak_factory_.GetWeakPtr(), frame_token)));
-
-  // The sink needs a frame ASAP so the first frame will be painted, all
-  // following frames will be returned in the Render callback.
-  if (!next_video_frame_) {
-    sink_->PaintSingleFrame(frame);
-  }
-  next_video_frame_ = frame;
-}
-
-void MediaFoundationRendererClient::OnPaintComplete(
-    const base::UnguessableToken& token) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
-  renderer_extension_->NotifyFrameReleased(token);
-}
-
 void MediaFoundationRendererClient::SetCdm(CdmContext* cdm_context,
                                            CdmAttachedCB cdm_attached_cb) {
   DVLOG_FUNC(1) << "cdm_context=" << cdm_context;
@@ -354,6 +278,7 @@
 }
 
 // RenderCallback implementation.
+
 scoped_refptr<VideoFrame> MediaFoundationRendererClient::Render(
     base::TimeTicks deadline_min,
     base::TimeTicks deadline_max,
@@ -389,8 +314,88 @@
   return render_interval_;
 }
 
+// media::mojom::MediaFoundationRendererClientExtension
+
+void MediaFoundationRendererClient::InitializeFramePool(
+    mojom::FramePoolInitializationParametersPtr pool_info) {
+  DCHECK_GT(pool_info->frame_textures.size(), static_cast<size_t>(0));
+
+  // Release our references to the video pool so that once the
+  // rendering is complete the memory will be freed.
+  video_frame_pool_.clear();
+
+  for (const auto& frame_info : pool_info->frame_textures) {
+    dcomp_texture_wrapper_->CreateVideoFrame(
+        pool_info->texture_size, std::move(frame_info->texture_handle),
+        base::BindOnce(
+            [](base::flat_map<base::UnguessableToken,
+                              scoped_refptr<VideoFrame>>& video_frame_pool,
+               const base::UnguessableToken& token,
+               scoped_refptr<VideoFrame> video_frame) {
+              video_frame_pool.insert({token, std::move(video_frame)});
+            },
+            std::ref(video_frame_pool_), frame_info->token));
+  }
+}
+
+void MediaFoundationRendererClient::OnFrameAvailable(
+    const base::UnguessableToken& frame_token,
+    const gfx::Size& size,
+    base::TimeDelta timestamp) {
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(has_video_);
+
+  auto video_frame = video_frame_pool_.find(frame_token);
+  // It is possible to become unsynced when we are reinitializing the frame
+  // pool so we are just checking to make sure the frame has been acquired.
+  if (video_frame == video_frame_pool_.end()) {
+    return;
+  }
+
+  scoped_refptr<VideoFrame> texture_pool_video_frame = video_frame->second;
+
+  texture_pool_video_frame->set_timestamp(timestamp);
+
+  // The Video Frame object's Destruction Observer is called when the video
+  // frame is no longer needed and the underlying texture can be reused. We
+  // cannot use the video frame we created in InitializeFramePool() directly
+  // because we hold onto a reference in our video frame pool so the callback
+  // would not be called, and for those their callback is to destroy the shared
+  // image anyway. Therefore we wrap the shared image based video frame in
+  // another video frame and add the callback which allows us to reuse the
+  // texture for a new video frame.
+  scoped_refptr<VideoFrame> frame = VideoFrame::WrapVideoFrame(
+      texture_pool_video_frame, texture_pool_video_frame->format(),
+      gfx::Rect(size), size);
+  frame->metadata().wants_promotion_hint = true;
+  frame->metadata().allow_overlay = true;
+  frame->AddDestructionObserver(base::BindPostTask(
+      media_task_runner_,
+      base::BindOnce(&MediaFoundationRendererClient::OnPaintComplete,
+                     weak_factory_.GetWeakPtr(), frame_token)));
+
+  // The sink needs a frame ASAP so the first frame will be painted, all
+  // following frames will be returned in the Render callback.
+  if (!next_video_frame_) {
+    sink_->PaintSingleFrame(frame);
+  }
+  next_video_frame_ = frame;
+}
+
 // private
 
+bool MediaFoundationRendererClient::IsFrameServerMode() const {
+  return rendering_mode_ == MediaFoundationRenderingMode::FrameServer;
+}
+
+void MediaFoundationRendererClient::OnConnectionError() {
+  DVLOG_FUNC(1);
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  MEDIA_LOG(ERROR, media_log_) << "MediaFoundationRendererClient disconnected";
+  REPORT_ERROR_REASON(kOnConnectionError);
+  OnError(PIPELINE_ERROR_DISCONNECTED);
+}
+
 void MediaFoundationRendererClient::OnRemoteRendererInitialized(
     PipelineStatus status) {
   DVLOG_FUNC(1) << "status=" << status;
@@ -556,14 +561,6 @@
   std::move(cdm_attached_cb_).Run(success);
 }
 
-void MediaFoundationRendererClient::OnConnectionError() {
-  DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
-  MEDIA_LOG(ERROR, media_log_) << "MediaFoundationRendererClient disconnected";
-  REPORT_ERROR_REASON(kOnConnectionError);
-  OnError(PIPELINE_ERROR_DISCONNECTED);
-}
-
 void MediaFoundationRendererClient::SignalMediaPlayingStateChange(
     bool is_playing) {
   // Skip if we are already in the same playing state
@@ -582,6 +579,29 @@
   is_playing_ = is_playing;
 }
 
+void MediaFoundationRendererClient::ObserveMailboxForOverlayState(
+    const gpu::Mailbox& mailbox) {
+  // If the rendering strategy is dynamic then setup an OverlayStateObserver to
+  // respond to promotion changes. If the rendering strategy is Direct
+  // Composition or Frame Server then we do not need to listen & respond to
+  // overlay state changes.
+  if (rendering_strategy_ == MediaFoundationClearRenderingStrategy::kDynamic) {
+    mailbox_ = mailbox;
+    // 'observe_overlay_state_cb_' creates a content::OverlayStateObserver to
+    // subscribe to overlay state information for the given 'mailbox' from the
+    // Viz layer in the GPU process. We hold an OverlayStateObserverSubscription
+    // since a direct dependency on a content object is not allowed. Once the
+    // OverlayStateObserverSubscription is destroyed the OnOverlayStateChanged
+    // callback will no longer be invoked, so base::Unretained(this) is safe to
+    // use.
+    observer_subscription_ = observe_overlay_state_cb_.Run(
+        mailbox, base::BindRepeating(
+                     &MediaFoundationRendererClient::OnOverlayStateChanged,
+                     base::Unretained(this), mailbox));
+    DCHECK(observer_subscription_);
+  }
+}
+
 void MediaFoundationRendererClient::OnOverlayStateChanged(
     const gpu::Mailbox& mailbox,
     bool promoted) {
@@ -632,27 +652,10 @@
   }
 }
 
-void MediaFoundationRendererClient::ObserveMailboxForOverlayState(
-    const gpu::Mailbox& mailbox) {
-  // If the rendering strategy is dynamic then setup an OverlayStateObserver to
-  // respond to promotion changes. If the rendering strategy is Direct
-  // Composition or Frame Server then we do not need to listen & respond to
-  // overlay state changes.
-  if (rendering_strategy_ == MediaFoundationClearRenderingStrategy::kDynamic) {
-    mailbox_ = mailbox;
-    // 'observe_overlay_state_cb_' creates a content::OverlayStateObserver to
-    // subscribe to overlay state information for the given 'mailbox' from the
-    // Viz layer in the GPU process. We hold an OverlayStateObserverSubscription
-    // since a direct dependency on a content object is not allowed. Once the
-    // OverlayStateObserverSubscription is destroyed the OnOverlayStateChanged
-    // callback will no longer be invoked, so base::Unretained(this) is safe to
-    // use.
-    observer_subscription_ = observe_overlay_state_cb_.Run(
-        mailbox, base::BindRepeating(
-                     &MediaFoundationRendererClient::OnOverlayStateChanged,
-                     base::Unretained(this), mailbox));
-    DCHECK(observer_subscription_);
-  }
+void MediaFoundationRendererClient::OnPaintComplete(
+    const base::UnguessableToken& token) {
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  renderer_extension_->NotifyFrameReleased(token);
 }
 
 }  // namespace media
diff --git a/media/mojo/clients/win/media_foundation_renderer_client.h b/media/mojo/clients/win/media_foundation_renderer_client.h
index 5d1d7ca..08cab88 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client.h
+++ b/media/mojo/clients/win/media_foundation_renderer_client.h
@@ -115,15 +115,15 @@
   base::TimeDelta GetPreferredRenderInterval() override;
 
   // media::mojom::MediaFoundationRendererClientExtension
+  void InitializeFramePool(
+      mojom::FramePoolInitializationParametersPtr pool_info) override;
   void OnFrameAvailable(const base::UnguessableToken& frame_token,
                         const gfx::Size& size,
                         base::TimeDelta timestamp) override;
-  void InitializeFramePool(
-      mojom::FramePoolInitializationParametersPtr pool_info) override;
-
-  bool IsFrameServerMode() const;
 
  private:
+  bool IsFrameServerMode() const;
+  void OnConnectionError();
   void OnRemoteRendererInitialized(PipelineStatus status);
   void OnOutputRectChange(gfx::Rect output_rect);
   void OnSetOutputRectDone(const gfx::Size& output_size, bool success);
@@ -135,11 +135,11 @@
   void OnVideoFrameCreated(scoped_refptr<VideoFrame> video_frame,
                            const gpu::Mailbox& mailbox);
   void OnCdmAttached(bool success);
-  void OnConnectionError();
   void SignalMediaPlayingStateChange(bool is_playing);
   void ObserveMailboxForOverlayState(const gpu::Mailbox& mailbox);
   void OnOverlayStateChanged(const gpu::Mailbox& mailbox, bool promoted);
   void UpdateRenderMode();
+  void OnPaintComplete(const base::UnguessableToken& token);
 
   // This class is constructed on the main thread. Hence we store
   // PendingRemotes so we can bind the Remotes on the media task
@@ -188,8 +188,6 @@
   raw_ptr<CdmContext> cdm_context_ = nullptr;
   CdmAttachedCB cdm_attached_cb_;
 
-  void OnPaintComplete(const base::UnguessableToken& token);
-
   // The MF CDM process does not have access to the mailboxes but it creates the
   // textures. Therefore the MediaFoundationRenderer and the
   // MediaFoundationRendererClient need to have a mechanism, provided by the MF
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc
index faedaf8e..44dd46e 100644
--- a/media/mojo/services/media_metrics_provider.cc
+++ b/media/mojo/services/media_metrics_provider.cc
@@ -62,22 +62,25 @@
       uma_info_(is_incognito == BrowsingMode::kIncognito) {}
 
 MediaMetricsProvider::~MediaMetricsProvider() {
-  // These UKM and UMA metrics do not apply to MediaStreams.
-  if (media_stream_type_ != mojom::MediaStreamType::kNone)
+  if (!IsInitialized())
     return;
 
   // UKM may be unavailable in content_shell or other non-chrome/ builds; it
   // may also be unavailable if browser shutdown has started; so this may be a
   // nullptr. If it's unavailable, UKM reporting will be skipped.
   ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
-  if (!ukm_recorder || !initialized_)
+  if (!ukm_recorder)
+    return;
+
+  // These UKM and UMA metrics do not apply to MediaStreams.
+  if (media_info_->media_stream_type != mojom::MediaStreamType::kNone)
     return;
 
   ukm::builders::Media_WebMediaPlayerState builder(source_id_);
   builder.SetPlayerID(player_id_);
   builder.SetIsTopFrame(is_top_frame_);
   builder.SetIsEME(uma_info_.is_eme);
-  builder.SetIsMSE(is_mse_);
+  builder.SetIsMSE(media_info_->is_mse);
   builder.SetRendererType(static_cast<int>(renderer_type_));
   builder.SetKeySystem(GetKeySystemIntForUKM(key_system_));
   builder.SetIsHardwareSecure(is_hardware_secure_);
@@ -86,8 +89,8 @@
   builder.SetVideoEncryptionType(
       static_cast<int>(uma_info_.video_pipeline_info.encryption_type));
   builder.SetFinalPipelineStatus(uma_info_.last_pipeline_status);
-  if (!is_mse_) {
-    builder.SetURLScheme(static_cast<int64_t>(url_scheme_));
+  if (!media_info_->is_mse) {
+    builder.SetURLScheme(static_cast<int64_t>(media_info_->url_scheme));
     if (container_name_)
       builder.SetContainerName(*container_name_);
   }
@@ -230,19 +233,21 @@
     bool is_mse,
     mojom::MediaURLScheme url_scheme,
     mojom::MediaStreamType media_stream_type) {
-  if (initialized_) {
+  if (IsInitialized()) {
     mojo::ReportBadMessage(kInvalidInitialize);
     return;
   }
 
-  is_mse_ = is_mse;
-  initialized_ = true;
-  url_scheme_ = url_scheme;
-  media_stream_type_ = media_stream_type;
+  media_info_.emplace(MediaInfo{
+      .is_mse = is_mse,
+      .url_scheme = url_scheme,
+      .media_stream_type = media_stream_type,
+  });
+  DCHECK(IsInitialized());
 }
 
 void MediaMetricsProvider::OnError(const PipelineStatus& status) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   if (is_shutting_down_cb_.Run()) {
     DVLOG(1) << __func__ << ": Error " << PipelineStatusToString(status)
              << " ignored since it is reported during shutdown.";
@@ -253,7 +258,7 @@
 }
 
 void MediaMetricsProvider::OnFallback(const PipelineStatus& status) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   if (is_shutting_down_cb_.Run()) {
     DVLOG(1) << __func__ << ": Error " << PipelineStatusToString(status)
              << " ignored since it is reported during shutdown.";
@@ -268,26 +273,26 @@
 }
 
 void MediaMetricsProvider::SetTimeToMetadata(base::TimeDelta elapsed) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   DCHECK_EQ(time_to_metadata_, kNoTimestamp);
   time_to_metadata_ = elapsed;
 }
 
 void MediaMetricsProvider::SetTimeToFirstFrame(base::TimeDelta elapsed) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   DCHECK_EQ(time_to_first_frame_, kNoTimestamp);
   time_to_first_frame_ = elapsed;
 }
 
 void MediaMetricsProvider::SetTimeToPlayReady(base::TimeDelta elapsed) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   DCHECK_EQ(time_to_play_ready_, kNoTimestamp);
   time_to_play_ready_ = elapsed;
 }
 
 void MediaMetricsProvider::SetContainerName(
     container_names::MediaContainerName container_name) {
-  DCHECK(initialized_);
+  DCHECK(IsInitialized());
   DCHECK(!container_name_.has_value());
   container_name_ = container_name;
 }
@@ -307,7 +312,7 @@
 void MediaMetricsProvider::AcquireWatchTimeRecorder(
     mojom::PlaybackPropertiesPtr properties,
     mojo::PendingReceiver<mojom::WatchTimeRecorder> receiver) {
-  if (!initialized_) {
+  if (!IsInitialized()) {
     mojo::ReportBadMessage(kInvalidInitialize);
     return;
   }
@@ -321,7 +326,7 @@
 
 void MediaMetricsProvider::AcquireVideoDecodeStatsRecorder(
     mojo::PendingReceiver<mojom::VideoDecodeStatsRecorder> receiver) {
-  if (!initialized_) {
+  if (!IsInitialized()) {
     mojo::ReportBadMessage(kInvalidInitialize);
     return;
   }
@@ -368,4 +373,8 @@
       std::move(receiver));
 }
 
+bool MediaMetricsProvider::IsInitialized() const {
+  return media_info_.has_value();
+}
+
 }  // namespace media
diff --git a/media/mojo/services/media_metrics_provider.h b/media/mojo/services/media_metrics_provider.h
index eb0a1c1..6fbfbfc0 100644
--- a/media/mojo/services/media_metrics_provider.h
+++ b/media/mojo/services/media_metrics_provider.h
@@ -20,6 +20,7 @@
 #include "media/mojo/services/video_decode_perf_history.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace media {
@@ -89,7 +90,7 @@
 
  private:
   struct PipelineInfo {
-    PipelineInfo(bool is_incognito);
+    explicit PipelineInfo(bool is_incognito);
     ~PipelineInfo();
     bool is_incognito;
     bool has_ever_played = false;
@@ -98,13 +99,19 @@
     bool has_video = false;
     bool is_eme = false;
     bool video_decoder_changed = false;
-    AudioCodec audio_codec;
-    VideoCodec video_codec;
+    AudioCodec audio_codec = AudioCodec::kUnknown;
+    VideoCodec video_codec = VideoCodec::kUnknown;
     VideoPipelineInfo video_pipeline_info;
     AudioPipelineInfo audio_pipeline_info;
     PipelineStatusCodes last_pipeline_status = PIPELINE_OK;
   };
 
+  struct MediaInfo {
+    const bool is_mse;
+    const mojom::MediaURLScheme url_scheme;
+    const mojom::MediaStreamType media_stream_type;
+  };
+
   // mojom::MediaMetricsProvider implementation:
   void Initialize(bool is_mse,
                   mojom::MediaURLScheme url_scheme,
@@ -142,6 +149,8 @@
   void ReportPipelineUMA();
   std::string GetUMANameForAVStream(const PipelineInfo& player_info);
 
+  bool IsInitialized() const;
+
   // Session unique ID which maps to a given WebMediaPlayerImpl instances. Used
   // to coordinate multiply logged events with a singly logged metric.
   const uint64_t player_id_;
@@ -160,11 +169,9 @@
   // UMA pipeline packaged data
   PipelineInfo uma_info_;
 
-  // The values below are only set if |initialized_| is true.
-  bool initialized_ = false;
-  bool is_mse_;
-  mojom::MediaURLScheme url_scheme_;
-  mojom::MediaStreamType media_stream_type_;
+  // The values below are only set if `Initialize` has been called.
+  absl::optional<MediaInfo> media_info_;
+
   RendererType renderer_type_ = RendererType::kRendererImpl;
   std::string key_system_;
   bool is_hardware_secure_ = false;
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index f0048af..a43b60f9 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -87,7 +87,12 @@
 
 void MojoRendererService::Flush(FlushCallback callback) {
   DVLOG(2) << __func__;
-  DCHECK_EQ(state_, STATE_PLAYING);
+  DCHECK(state_ == STATE_PLAYING || state_ == STATE_ERROR);
+
+  if (state_ == STATE_ERROR) {
+    std::move(callback).Run();
+    return;
+  }
 
   state_ = STATE_FLUSHING;
   CancelPeriodicMediaTimeUpdates();
@@ -256,23 +261,26 @@
   DVLOG(2) << __func__;
 
   time_update_timer_.Stop();
-  UpdateMediaTime(false);
+  UpdateMediaTime(/*force=*/false);
 }
 
 void MojoRendererService::SchedulePeriodicMediaTimeUpdates() {
   DVLOG(2) << __func__;
 
-  UpdateMediaTime(true);
+  UpdateMediaTime(/*force=*/true);
   time_update_timer_.Start(
       FROM_HERE, kTimeUpdateInterval,
       base::BindRepeating(&MojoRendererService::UpdateMediaTime, weak_this_,
-                          false));
+                          /*force=*/false));
 }
 
 void MojoRendererService::OnFlushCompleted(FlushCallback callback) {
   DVLOG(1) << __func__;
-  DCHECK_EQ(state_, STATE_FLUSHING);
-  state_ = STATE_PLAYING;
+  DCHECK(state_ == STATE_FLUSHING || state_ == STATE_ERROR);
+
+  if (state_ == STATE_FLUSHING)
+    state_ = STATE_PLAYING;
+
   std::move(callback).Run();
 }
 
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc
index ff1f279..b5a075a 100644
--- a/media/video/av1_video_encoder.cc
+++ b/media/video/av1_video_encoder.cc
@@ -15,6 +15,7 @@
 #include "base/trace_event/trace_event.h"
 #include "media/base/svc_scalability_mode.h"
 #include "media/base/timestamp_constants.h"
+#include "media/base/video_color_space.h"
 #include "media/base/video_frame.h"
 #include "media/base/video_util.h"
 #include "third_party/libaom/source/libaom/aom/aomcx.h"
@@ -159,6 +160,16 @@
   return EncoderStatus::Codes::kOk;
 }
 
+std::string LogAomErrorMessage(aom_codec_ctx_t* context,
+                               const char* message,
+                               aom_codec_err_t status) {
+  auto formatted_msg = base::StringPrintf("%s: %s (%s)", message,
+                                          aom_codec_err_to_string(status),
+                                          aom_codec_error_detail(context));
+  DLOG(ERROR) << formatted_msg;
+  return formatted_msg;
+}
+
 }  // namespace
 
 Av1VideoEncoder::Av1VideoEncoder() : codec_(nullptr, FreeCodecCtx) {}
@@ -376,6 +387,7 @@
   if (last_frame_color_space_ != frame->ColorSpace()) {
     last_frame_color_space_ = frame->ColorSpace();
     key_frame = true;
+    UpdateEncoderColorSpace();
   }
 
   auto temporal_id_status = AssignNextTemporalId(key_frame);
@@ -393,10 +405,7 @@
   artificial_timestamp_ += duration_us;
 
   if (error != AOM_CODEC_OK) {
-    auto msg =
-        base::StringPrintf("AOM encoding error: %s (%d)",
-                           aom_codec_error_detail(codec_.get()), codec_->err);
-    DLOG(ERROR) << msg;
+    auto msg = LogAomErrorMessage(codec_.get(), "AOM encoding error", error);
     std::move(done_cb).Run(
         EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg));
     return;
@@ -542,9 +551,8 @@
     aom_codec_control(codec_.get(), AV1E_SET_ERROR_RESILIENT_MODE,
                       temporal_id > 0 ? 1 : 0);
   if (error != AOM_CODEC_OK) {
-    auto msg =
-        base::StringPrintf("Set AV1E_SET_SVC_LAYER_ID error: %s (%d)",
-                           aom_codec_error_detail(codec_.get()), codec_->err);
+    auto msg = LogAomErrorMessage(codec_.get(),
+                                  "Set AV1E_SET_SVC_LAYER_ID error", error);
     return EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg);
   }
   return temporal_id;
@@ -562,10 +570,7 @@
 
   auto error = aom_codec_encode(codec_.get(), nullptr, 0, 0, 0);
   if (error != AOM_CODEC_OK) {
-    auto msg =
-        base::StringPrintf("AOM encoding error: %s (%d)",
-                           aom_codec_error_detail(codec_.get()), codec_->err);
-    DLOG(ERROR) << msg;
+    auto msg = LogAomErrorMessage(codec_.get(), "AOM encoding error", error);
     std::move(done_cb).Run(
         EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg));
     return;
@@ -578,4 +583,38 @@
   std::move(done_cb).Run(EncoderStatus::Codes::kOk);
 }
 
+void Av1VideoEncoder::UpdateEncoderColorSpace() {
+  auto aom_cs = VideoColorSpace::FromGfxColorSpace(last_frame_color_space_);
+  if (aom_cs.primaries != VideoColorSpace::PrimaryID::INVALID) {
+    auto status = aom_codec_control(codec_.get(), AV1E_SET_COLOR_PRIMARIES,
+                                    aom_cs.primaries);
+    if (status != AOM_CODEC_OK)
+      LogAomErrorMessage(codec_.get(), "Failed to set color primaries", status);
+  }
+  if (aom_cs.transfer != VideoColorSpace::TransferID::INVALID) {
+    auto status = aom_codec_control(
+        codec_.get(), AV1E_SET_TRANSFER_CHARACTERISTICS, aom_cs.transfer);
+    if (status != AOM_CODEC_OK)
+      LogAomErrorMessage(codec_.get(), "Failed to set color transfer", status);
+  }
+  if (aom_cs.matrix != VideoColorSpace::MatrixID::INVALID) {
+    auto status = aom_codec_control(codec_.get(), AV1E_SET_MATRIX_COEFFICIENTS,
+                                    aom_cs.matrix);
+    if (status != AOM_CODEC_OK)
+      LogAomErrorMessage(codec_.get(), "Failed to set color transfer", status);
+  }
+
+  if (last_frame_color_space_.GetRangeID() == gfx::ColorSpace::RangeID::FULL ||
+      last_frame_color_space_.GetRangeID() ==
+          gfx::ColorSpace::RangeID::LIMITED) {
+    auto status = aom_codec_control(
+        codec_.get(), AV1E_SET_COLOR_RANGE,
+        last_frame_color_space_.GetRangeID() == gfx::ColorSpace::RangeID::FULL
+            ? AOM_CR_FULL_RANGE
+            : AOM_CR_STUDIO_RANGE);
+    if (status != AOM_CODEC_OK)
+      LogAomErrorMessage(codec_.get(), "Failed to set color range", status);
+  }
+}
+
 }  // namespace media
diff --git a/media/video/av1_video_encoder.h b/media/video/av1_video_encoder.h
index 5dd690c..c6080ceb 100644
--- a/media/video/av1_video_encoder.h
+++ b/media/video/av1_video_encoder.h
@@ -43,6 +43,7 @@
                     base::TimeDelta ts,
                     gfx::ColorSpace color_space);
   EncoderStatus::Or<int> AssignNextTemporalId(bool key_frame);
+  void UpdateEncoderColorSpace();
 
   using aom_codec_unique_ptr =
       std::unique_ptr<aom_codec_ctx_t, void (*)(aom_codec_ctx_t*)>;
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc
index 578bee7..6df0eb7 100644
--- a/media/video/vpx_video_encoder.cc
+++ b/media/video/vpx_video_encoder.cc
@@ -229,6 +229,16 @@
   delete codec_ctx;
 }
 
+std::string LogVpxErrorMessage(vpx_codec_ctx_t* context,
+                               const char* message,
+                               vpx_codec_err_t status) {
+  auto formatted_msg = base::StringPrintf("%s: %s (%s)", message,
+                                          vpx_codec_err_to_string(status),
+                                          vpx_codec_error_detail(context));
+  DLOG(ERROR) << formatted_msg;
+  return formatted_msg;
+}
+
 }  // namespace
 
 VpxVideoEncoder::VpxVideoEncoder() : codec_(nullptr, FreeCodecCtx) {}
@@ -307,10 +317,8 @@
       codec.get(), iface, &codec_config_,
       codec_config_.g_bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH);
   if (vpx_error != VPX_CODEC_OK) {
-    std::string msg = base::StringPrintf(
-        "VPX encoder initialization error: %s %s",
-        vpx_codec_err_to_string(vpx_error), codec->err_detail);
-    DLOG(ERROR) << msg;
+    auto msg = LogVpxErrorMessage(
+        codec.get(), "VPX encoder initialization error", vpx_error);
     std::move(done_cb).Run(
         EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError, msg));
     return;
@@ -324,10 +332,8 @@
   int cpu_used = is_vp9 ? 7 : -6;
   vpx_error = vpx_codec_control(codec.get(), VP8E_SET_CPUUSED, cpu_used);
   if (vpx_error != VPX_CODEC_OK) {
-    std::string msg =
-        base::StringPrintf("VPX encoder VP8E_SET_CPUUSED error: %s",
-                           vpx_codec_err_to_string(vpx_error));
-    DLOG(ERROR) << msg;
+    auto msg = LogVpxErrorMessage(
+        codec.get(), "VPX encoder VP8E_SET_CPUUSED error", vpx_error);
     std::move(done_cb).Run(
         EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError, msg));
     return;
@@ -361,10 +367,8 @@
       vpx_codec_control(codec.get(), VP9E_SET_SVC_PARAMETERS, &svc_conf);
       vpx_error = vpx_codec_control(codec.get(), VP9E_SET_SVC, 1);
       if (vpx_error != VPX_CODEC_OK) {
-        std::string msg =
-            base::StringPrintf("Can't activate SVC encoding: %s",
-                               vpx_codec_err_to_string(vpx_error));
-        DLOG(ERROR) << msg;
+        auto msg = LogVpxErrorMessage(codec.get(),
+                                      "Can't activate SVC encoding", vpx_error);
         status = EncoderStatus(
             EncoderStatus::Codes::kEncoderInitializationError, msg);
         std::move(done_cb).Run(status);
@@ -517,6 +521,7 @@
   if (last_frame_color_space_ != frame->ColorSpace()) {
     last_frame_color_space_ = frame->ColorSpace();
     key_frame = true;
+    UpdateEncoderColorSpace();
   }
   auto deadline = VPX_DL_REALTIME;
   vpx_codec_flags_t flags = key_frame ? VPX_EFLAG_FORCE_KF : 0;
@@ -544,10 +549,8 @@
                                     duration_us, flags, deadline);
 
   if (vpx_error != VPX_CODEC_OK) {
-    std::string msg = base::StringPrintf("VPX encoding error: %s (%s)",
-                                         vpx_codec_err_to_string(vpx_error),
-                                         vpx_codec_error_detail(codec_.get()));
-    DLOG(ERROR) << msg;
+    auto msg =
+        LogVpxErrorMessage(codec_.get(), "VPX encoding error", vpx_error);
     std::move(done_cb).Run(
         EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg)
             .WithData("vpx_error", vpx_error));
@@ -679,10 +682,8 @@
 
   auto vpx_error = vpx_codec_encode(codec_.get(), nullptr, -1, 0, 0, 0);
   if (vpx_error != VPX_CODEC_OK) {
-    std::string msg = base::StringPrintf("VPX flushing error: %s (%s)",
-                                         vpx_codec_err_to_string(vpx_error),
-                                         vpx_codec_error_detail(codec_.get()));
-    DLOG(ERROR) << msg;
+    auto msg =
+        LogVpxErrorMessage(codec_.get(), "VPX flushing error", vpx_error);
     auto status = EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg)
                       .WithData("vpx_error", vpx_error);
     std::move(done_cb).Run(std::move(status));
@@ -723,4 +724,53 @@
   }
 }
 
+void VpxVideoEncoder::UpdateEncoderColorSpace() {
+  auto vpx_cs = VPX_CS_UNKNOWN;
+  switch (last_frame_color_space_.GetPrimaryID()) {
+    case gfx::ColorSpace::PrimaryID::BT709: {
+      const auto matrix_id = last_frame_color_space_.GetMatrixID();
+      if (matrix_id == gfx::ColorSpace::MatrixID::GBR ||
+          matrix_id == gfx::ColorSpace::MatrixID::RGB) {
+        vpx_cs = VPX_CS_SRGB;
+      } else {
+        vpx_cs = VPX_CS_BT_709;
+      }
+      break;
+    }
+    case gfx::ColorSpace::PrimaryID::BT2020:
+      vpx_cs = VPX_CS_BT_2020;
+      break;
+    case gfx::ColorSpace::PrimaryID::SMPTE170M:
+      vpx_cs = VPX_CS_SMPTE_170;
+      break;
+    case gfx::ColorSpace::PrimaryID::SMPTE240M:
+      vpx_cs = VPX_CS_SMPTE_240;
+      break;
+    case gfx::ColorSpace::PrimaryID::BT470BG:
+      vpx_cs = VPX_CS_BT_601;
+      break;
+    default:
+      break;
+  };
+
+  if (vpx_cs != VPX_CS_UNKNOWN) {
+    auto vpx_error =
+        vpx_codec_control(codec_.get(), VP9E_SET_COLOR_SPACE, vpx_cs);
+    if (vpx_error != VPX_CODEC_OK)
+      LogVpxErrorMessage(codec_.get(), "Failed to set color space", vpx_error);
+  }
+
+  if (last_frame_color_space_.GetRangeID() == gfx::ColorSpace::RangeID::FULL ||
+      last_frame_color_space_.GetRangeID() ==
+          gfx::ColorSpace::RangeID::LIMITED) {
+    auto vpx_error = vpx_codec_control(
+        codec_.get(), VP9E_SET_COLOR_RANGE,
+        last_frame_color_space_.GetRangeID() == gfx::ColorSpace::RangeID::FULL
+            ? VPX_CR_FULL_RANGE
+            : VPX_CR_STUDIO_RANGE);
+    if (vpx_error != VPX_CODEC_OK)
+      LogVpxErrorMessage(codec_.get(), "Failed to set color range", vpx_error);
+  }
+}
+
 }  // namespace media
diff --git a/media/video/vpx_video_encoder.h b/media/video/vpx_video_encoder.h
index 05272d1d..9ca5438 100644
--- a/media/video/vpx_video_encoder.h
+++ b/media/video/vpx_video_encoder.h
@@ -42,6 +42,8 @@
                     base::TimeDelta ts,
                     gfx::ColorSpace color_space);
 
+  void UpdateEncoderColorSpace();
+
   using vpx_codec_unique_ptr =
       std::unique_ptr<vpx_codec_ctx_t, void (*)(vpx_codec_ctx_t*)>;
 
diff --git a/net/first_party_sets/global_first_party_sets.cc b/net/first_party_sets/global_first_party_sets.cc
index 0e8dc03..db45e27 100644
--- a/net/first_party_sets/global_first_party_sets.cc
+++ b/net/first_party_sets/global_first_party_sets.cc
@@ -12,6 +12,7 @@
 #include "base/containers/flat_set.h"
 #include "base/functional/function_ref.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/ranges/algorithm.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/types/optional_util.h"
 #include "net/base/schemeful_site.h"
@@ -80,18 +81,23 @@
     base::flat_map<SchemefulSite, SchemefulSite> aliases)
     : GlobalFirstPartySets(std::move(entries),
                            std::move(aliases),
+                           /*manual_sets=*/{},
                            FirstPartySetsContextConfig()) {}
 
 GlobalFirstPartySets::GlobalFirstPartySets(
     base::flat_map<SchemefulSite, FirstPartySetEntry> entries,
     base::flat_map<SchemefulSite, SchemefulSite> aliases,
+    base::flat_map<SchemefulSite, FirstPartySetEntry> manual_sets,
     FirstPartySetsContextConfig manual_config)
     : entries_(std::move(entries)),
       aliases_(std::move(aliases)),
+      manual_sets_(std::move(manual_sets)),
       manual_config_(std::move(manual_config)) {
   // `aliases_` can only be nonempty if `entries_` is also nonempty.
   if (!aliases_.empty())
     DCHECK(!entries_.empty());
+
+  DCHECK_EQ(manual_sets_.empty(), manual_config_.empty());
 }
 
 GlobalFirstPartySets::GlobalFirstPartySets(GlobalFirstPartySets&&) = default;
@@ -101,8 +107,9 @@
 GlobalFirstPartySets::~GlobalFirstPartySets() = default;
 
 bool GlobalFirstPartySets::operator==(const GlobalFirstPartySets& other) const {
-  return std::tie(entries_, aliases_, manual_config_) ==
-         std::tie(other.entries_, other.aliases_, other.manual_config_);
+  return std::tie(entries_, aliases_, manual_sets_, manual_config_) ==
+         std::tie(other.entries_, other.aliases_, other.manual_sets_,
+                  other.manual_config_);
 }
 
 bool GlobalFirstPartySets::operator!=(const GlobalFirstPartySets& other) const {
@@ -110,7 +117,8 @@
 }
 
 GlobalFirstPartySets GlobalFirstPartySets::Clone() const {
-  return GlobalFirstPartySets(entries_, aliases_, manual_config_.Clone());
+  return GlobalFirstPartySets(entries_, aliases_, manual_sets_,
+                              manual_config_.Clone());
 }
 
 absl::optional<FirstPartySetEntry> GlobalFirstPartySets::FindEntry(
@@ -218,16 +226,24 @@
 void GlobalFirstPartySets::ApplyManuallySpecifiedSet(
     const base::flat_map<SchemefulSite, FirstPartySetEntry>& manual_entries) {
   DCHECK(manual_config_.empty());
+  manual_sets_ = manual_entries;
   // We handle the manually-specified set the same way as we handle
   // replacement enterprise policy sets.
   manual_config_ = ComputeConfig(
       /*replacement_sets=*/{manual_entries}, /*addition_sets=*/{});
-  manual_sets_ = manual_entries;
 }
 
 FirstPartySetsContextConfig GlobalFirstPartySets::ComputeConfig(
     const std::vector<SingleSet>& replacement_sets,
     const std::vector<SingleSet>& addition_sets) const {
+  if (base::ranges::all_of(replacement_sets,
+                           [](const SingleSet& set) { return set.empty(); }) &&
+      base::ranges::all_of(addition_sets,
+                           [](const SingleSet& set) { return set.empty(); })) {
+    // Nothing to do.
+    return FirstPartySetsContextConfig();
+  }
+
   // Maps a site to its new entry if it has one.
   std::vector<std::pair<SchemefulSite, absl::optional<FirstPartySetEntry>>>
       site_to_entry;
@@ -287,7 +303,11 @@
   // Find out which potential singletons are actually singletons; delete
   // members whose owners left; and reparent the sets that intersected with
   // an addition set.
-  for (const auto& [member, set_entry] : entries_) {
+  // Note: use a null config here, to avoid taking unrelated policy sets into
+  // account.
+  ForEachEffectiveSetEntry(/*config=*/nullptr, [&](const SchemefulSite& member,
+                                                   const FirstPartySetEntry&
+                                                       set_entry) {
     // Reparent all sites in any intersecting addition sets.
     if (auto entry = addition_intersected_owners.find(set_entry.primary());
         entry != addition_intersected_owners.end() &&
@@ -300,7 +320,7 @@
                                      absl::nullopt));
     }
     if (member == set_entry.primary())
-      continue;
+      return true;
     // Remove non-singletons from the potential list.
     if (auto entry = potential_singletons.find(set_entry.primary());
         entry != potential_singletons.end() &&
@@ -315,7 +335,9 @@
         !addition_intersected_owners.contains(set_entry.primary())) {
       site_to_entry.emplace_back(member, absl::nullopt);
     }
-  }
+
+    return true;
+  });
   // Any owner remaining in `potential_singleton` is a real singleton, so delete
   // it:
   for (auto& [owner, members] : potential_singletons) {
@@ -338,6 +360,12 @@
 GlobalFirstPartySets::NormalizeAdditionSets(
     const std::vector<base::flat_map<SchemefulSite, FirstPartySetEntry>>&
         addition_sets) const {
+  if (base::ranges::all_of(addition_sets,
+                           [](const SingleSet& set) { return set.empty(); })) {
+    // Nothing to do.
+    return {};
+  }
+
   // Find all the addition sets that intersect with any given public set.
   base::flat_map<SchemefulSite, base::flat_set<size_t>> addition_set_overlaps;
   for (size_t set_idx = 0; set_idx < addition_sets.size(); set_idx++) {
@@ -395,6 +423,50 @@
   return true;
 }
 
+bool GlobalFirstPartySets::ForEachEffectiveSetEntry(
+    const FirstPartySetsContextConfig& config,
+    base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)> f)
+    const {
+  return ForEachEffectiveSetEntry(&config, f);
+}
+
+bool GlobalFirstPartySets::ForEachEffectiveSetEntry(
+    const FirstPartySetsContextConfig* config,
+    base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)> f)
+    const {
+  // Policy sets have highest precedence:
+  if (config != nullptr) {
+    if (!config->ForEachCustomizationEntry(
+            [&](const SchemefulSite& site,
+                const absl::optional<FirstPartySetEntry>& maybe_entry) {
+              if (maybe_entry.has_value())
+                return f(site, *maybe_entry);
+              return true;
+            })) {
+      return false;
+    }
+  }
+
+  // Then the manual set:
+  if (!manual_config_.ForEachCustomizationEntry(
+          [&](const SchemefulSite& site,
+              const absl::optional<FirstPartySetEntry>& maybe_entry) {
+            if (maybe_entry.has_value() && (!config || !config->Contains(site)))
+              return f(site, *maybe_entry);
+            return true;
+          })) {
+    return false;
+  }
+
+  // Finally, the public sets.
+  return ForEachPublicSetEntry([&](const SchemefulSite& site,
+                                   const FirstPartySetEntry& entry) {
+    if ((!config || !config->Contains(site)) && !manual_config_.Contains(site))
+      return f(site, entry);
+    return true;
+  });
+}
+
 std::ostream& operator<<(std::ostream& os, const GlobalFirstPartySets& sets) {
   os << "{entries = {";
   for (const auto& [site, entry] : sets.entries()) {
@@ -404,6 +476,18 @@
   for (const auto& [alias, canonical] : sets.aliases()) {
     os << "{" << alias.Serialize() << ": " << canonical.Serialize() << "}, ";
   }
+  os << "}, manual_sets = {";
+  for (const auto& [site, entry] : sets.manual_sets()) {
+    os << "{" << site.Serialize() << ": " << entry << "}, ";
+  }
+  os << "}, manual_config = {";
+  sets.manual_config().ForEachCustomizationEntry(
+      [&](const net::SchemefulSite& site,
+          const absl::optional<net::FirstPartySetEntry>& maybe_entry) {
+        os << "{" << site.Serialize() << ": ";
+        maybe_entry.has_value() ? os << maybe_entry.value() : os << "nullopt";
+        return true;
+      });
   os << "}}";
   return os;
 }
diff --git a/net/first_party_sets/global_first_party_sets.h b/net/first_party_sets/global_first_party_sets.h
index e921ef9..7ab6f3ba 100644
--- a/net/first_party_sets/global_first_party_sets.h
+++ b/net/first_party_sets/global_first_party_sets.h
@@ -39,10 +39,6 @@
   GlobalFirstPartySets(
       base::flat_map<SchemefulSite, FirstPartySetEntry> entries,
       base::flat_map<SchemefulSite, SchemefulSite> aliases);
-  GlobalFirstPartySets(
-      base::flat_map<SchemefulSite, FirstPartySetEntry> entries,
-      base::flat_map<SchemefulSite, SchemefulSite> aliases,
-      FirstPartySetsContextConfig manual_config);
 
   GlobalFirstPartySets(GlobalFirstPartySets&&);
   GlobalFirstPartySets& operator=(GlobalFirstPartySets&&);
@@ -55,9 +51,8 @@
   // Creates a clone of this instance.
   GlobalFirstPartySets Clone() const;
 
-  // Returns a FirstPartySetsContextConfig suitable for passing into
-  // FindEntries, in order to respect the overrides given by `replacement_sets`
-  // and `addition_sets`.
+  // Returns a FirstPartySetsContextConfig that respects the overrides given by
+  // `replacement_sets` and `addition_sets`, relative to this instance's state.
   //
   // Preconditions: sets defined by `replacement_sets` and
   // `addition_sets` must be disjoint.
@@ -103,6 +98,17 @@
       base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)>
           f) const;
 
+  // Synchronously iterate over all the effective entries (i.e. anything that
+  // could be returned by `FindEntry` using this instance and `config`,
+  // including the manual set, policy sets, and aliases). Returns early if any
+  // of the iterations returns false. Returns false if iteration was incomplete;
+  // true if all iterations returned true. No guarantees are made re: iteration
+  // order.
+  bool ForEachEffectiveSetEntry(
+      const FirstPartySetsContextConfig& config,
+      base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)>
+          f) const;
+
   // Whether the global sets are empty.
   bool empty() const { return entries_.empty() && manual_config_.empty(); }
 
@@ -118,6 +124,12 @@
   friend NET_EXPORT std::ostream& operator<<(std::ostream& os,
                                              const GlobalFirstPartySets& sets);
 
+  GlobalFirstPartySets(
+      base::flat_map<SchemefulSite, FirstPartySetEntry> entries,
+      base::flat_map<SchemefulSite, SchemefulSite> aliases,
+      base::flat_map<SchemefulSite, FirstPartySetEntry> manual_sets,
+      FirstPartySetsContextConfig manual_config);
+
   // Same as the public version of FindEntry, but is allowed to omit the
   // `config` argument (i.e. pass nullptr instead of a reference).
   absl::optional<FirstPartySetEntry> FindEntry(
@@ -145,6 +157,13 @@
       const std::set<SchemefulSite>& party_context,
       const FirstPartySetsContextConfig& fps_context_config) const;
 
+  // Same as the public version of ForEachEffectiveSetEntry, but is allowed to
+  // omit the `config` argument (i.e. pass nullptr instead of a reference).
+  bool ForEachEffectiveSetEntry(
+      const FirstPartySetsContextConfig* config,
+      base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)>
+          f) const;
+
   const base::flat_map<SchemefulSite, FirstPartySetEntry>& entries() const {
     return entries_;
   }
@@ -165,13 +184,13 @@
   // canonical representative, before looking it up in `entries_`.
   base::flat_map<SchemefulSite, SchemefulSite> aliases_;
 
-  // Stores the customizations induced by the manually-specified set. May be
-  // empty if no switch was provided.
-  FirstPartySetsContextConfig manual_config_;
-
   // A map representing the manually-specified sets. Contains entries for
   // aliases as well as canonical sites.
   base::flat_map<SchemefulSite, FirstPartySetEntry> manual_sets_;
+
+  // Stores the customizations induced by the manually-specified set. May be
+  // empty if no switch was provided.
+  FirstPartySetsContextConfig manual_config_;
 };
 
 NET_EXPORT std::ostream& operator<<(std::ostream& os,
diff --git a/net/first_party_sets/global_first_party_sets_unittest.cc b/net/first_party_sets/global_first_party_sets_unittest.cc
index 6dfb4a68..e6b0f894 100644
--- a/net/first_party_sets/global_first_party_sets_unittest.cc
+++ b/net/first_party_sets/global_first_party_sets_unittest.cc
@@ -25,6 +25,8 @@
 
 namespace net {
 
+namespace {
+
 const SchemefulSite kPrimary(GURL("https://primary.test"));
 const SchemefulSite kPrimary2(GURL("https://primary2.test"));
 const SchemefulSite kPrimary3(GURL("https://primary3.test"));
@@ -34,13 +36,56 @@
 const SchemefulSite kAssociated2(GURL("https://associated2.test"));
 const SchemefulSite kAssociated3(GURL("https://associated3.test"));
 const SchemefulSite kAssociated4(GURL("https://associated4.test"));
+const SchemefulSite kAssociated5(GURL("https://associated5.test"));
 const SchemefulSite kService(GURL("https://service.test"));
 
+base::flat_map<SchemefulSite, FirstPartySetEntry> CollectEffectiveSetEntries(
+    const GlobalFirstPartySets& sets,
+    const FirstPartySetsContextConfig& config) {
+  base::flat_map<SchemefulSite, FirstPartySetEntry> got;
+  sets.ForEachEffectiveSetEntry(
+      config, [&](const SchemefulSite& site, const FirstPartySetEntry& entry) {
+        DCHECK(!got.contains(site));
+        got[site] = entry;
+        return true;
+      });
+
+  // Consistency check: verify that all of the returned entries are what we'd
+  // get if we called FindEntry directly.
+  for (const auto& [site, entry] : got) {
+    DCHECK_EQ(sets.FindEntry(site, config).value(), entry);
+  }
+  return got;
+}
+
+}  // namespace
+
 class GlobalFirstPartySetsTest : public ::testing::Test {
  public:
   GlobalFirstPartySetsTest() = default;
 };
 
+TEST_F(GlobalFirstPartySetsTest, Clone) {
+  const SchemefulSite example(GURL("https://example.test"));
+  const SchemefulSite example_cctld(GURL("https://example.cctld"));
+  const SchemefulSite member1(GURL("https://member1.test"));
+  const FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  const FirstPartySetEntry member1_entry(example, SiteType::kAssociated, 1);
+
+  const SchemefulSite foo(GURL("https://foo.test"));
+  const SchemefulSite member2(GURL("https://member2.test"));
+  const FirstPartySetEntry foo_entry(foo, SiteType::kPrimary, absl::nullopt);
+  const FirstPartySetEntry member2_entry(foo, SiteType::kAssociated, 1);
+
+  GlobalFirstPartySets sets(
+      /*entries=*/
+      {{example, entry}, {member1, member1_entry}},
+      /*aliases=*/{{example_cctld, example}});
+  sets.ApplyManuallySpecifiedSet({{foo, foo_entry}, {member2, member2_entry}});
+
+  EXPECT_EQ(sets, sets.Clone());
+}
+
 TEST_F(GlobalFirstPartySetsTest, FindEntry_Nonexistent) {
   SchemefulSite example(GURL("https://example.test"));
 
@@ -203,6 +248,55 @@
   EXPECT_FALSE(sets.empty());
 }
 
+TEST_F(GlobalFirstPartySetsTest,
+       ForEachEffectiveSetEntry_ManualSetAndConfig_FullIteration) {
+  GlobalFirstPartySets global_sets;
+  global_sets.ApplyManuallySpecifiedSet({
+      {kPrimary,
+       FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+      {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
+      {kAssociated5, FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)},
+  });
+
+  // Modify kPrimary's set by removing kAssociated5 and modifying kAssociated4,
+  // via policy.
+  FirstPartySetsContextConfig config = global_sets.ComputeConfig(
+      /*replacement_sets=*/
+      {
+          {
+              {kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+              {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)},
+              {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kService,
+               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+          },
+      },
+      /*addition_sets=*/{});
+
+  // Note that since the policy sets take precedence over the manual set,
+  // kAssociated5 is no longer in an FPS.
+  EXPECT_THAT(
+      CollectEffectiveSetEntries(global_sets, config),
+      UnorderedElementsAre(
+          Pair(kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)),
+          Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+          Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
+                                            absl::nullopt))));
+}
+
 class PopulatedGlobalFirstPartySetsTest : public GlobalFirstPartySetsTest {
  public:
   PopulatedGlobalFirstPartySetsTest()
@@ -427,6 +521,148 @@
   EXPECT_EQ(count, 4);
 }
 
+TEST_F(PopulatedGlobalFirstPartySetsTest,
+       ForEachEffectiveSetEntry_PublicSetsOnly_FullIteration) {
+  EXPECT_THAT(
+      CollectEffectiveSetEntries(global_sets(), FirstPartySetsContextConfig()),
+      UnorderedElementsAre(
+          Pair(kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)),
+          Pair(kAssociated1,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)),
+          Pair(kAssociated2,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)),
+          Pair(kAssociated3,
+               FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
+          Pair(kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
+                                             absl::nullopt)),
+          Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
+                                            absl::nullopt))));
+}
+
+TEST_F(PopulatedGlobalFirstPartySetsTest,
+       ForEachEffectiveSetEntry_PublicSetsWithManualSet_FullIteration) {
+  // Replace kPrimary's set (including the alias and service site) with just
+  // {kPrimary, kAssociated4}.
+  global_sets().ApplyManuallySpecifiedSet({
+      {kPrimary,
+       FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+      {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
+  });
+
+  EXPECT_THAT(
+      CollectEffectiveSetEntries(global_sets(), FirstPartySetsContextConfig()),
+      UnorderedElementsAre(
+          Pair(kAssociated3,
+               FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
+          Pair(kAssociated4,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)),
+          Pair(kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
+                                             absl::nullopt))));
+}
+
+TEST_F(PopulatedGlobalFirstPartySetsTest,
+       ForEachEffectiveSetEntry_PublicSetsWithConfig_FullIteration) {
+  // Modify kPrimary's set by removing kAssociated2 and adding kAssociated4, via
+  // policy.
+  FirstPartySetsContextConfig config = global_sets().ComputeConfig(
+      /*replacement_sets=*/
+      {
+          {
+              {kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+              {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)},
+              {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kService,
+               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+          },
+      },
+      /*addition_sets=*/{});
+
+  EXPECT_THAT(
+      CollectEffectiveSetEntries(global_sets(), config),
+      UnorderedElementsAre(
+          Pair(kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)),
+          Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kAssociated3,
+               FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
+          Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
+                                             absl::nullopt)),
+          Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
+                                            absl::nullopt))));
+}
+
+TEST_F(
+    PopulatedGlobalFirstPartySetsTest,
+    ForEachEffectiveSetEntry_PublicSetsWithManualSetAndConfig_FullIteration) {
+  // Replace kPrimary's set (including the alias and service site) with just
+  // {kPrimary, kAssociated4, kAssociated5}.
+  global_sets().ApplyManuallySpecifiedSet({
+      {kPrimary,
+       FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+      {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
+      {kAssociated5, FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)},
+  });
+
+  // Modify kPrimary's set by removing kAssociated2 and adding kAssociated4, via
+  // policy.
+  FirstPartySetsContextConfig config = global_sets().ComputeConfig(
+      /*replacement_sets=*/
+      {
+          {
+              {kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+              {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)},
+              {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)},
+              {kService,
+               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+          },
+      },
+      /*addition_sets=*/{});
+
+  // Note that since the policy sets take precedence over the manual set,
+  // kAssociated5 is no longer in an FPS.
+  EXPECT_THAT(
+      CollectEffectiveSetEntries(global_sets(), config),
+      UnorderedElementsAre(
+          Pair(kAssociated1Cctld,
+               FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                  absl::nullopt)),
+          Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kAssociated3,
+               FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
+          Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
+                                                absl::nullopt)),
+          Pair(kPrimary,
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
+                                             absl::nullopt)),
+          Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
+                                            absl::nullopt))));
+}
+
 TEST_F(PopulatedGlobalFirstPartySetsTest, ComputeMetadata_EmptyContext) {
   SchemefulSite nonmember(GURL("https://nonmember.test"));
 
diff --git a/net/quic/OWNERS b/net/quic/OWNERS
index 4051f078..4bea52f8 100644
--- a/net/quic/OWNERS
+++ b/net/quic/OWNERS
@@ -3,7 +3,6 @@
 vasilvv@chromium.org
 rch@chromium.org
 bnc@chromium.org
-renjietang@chromium.org
 danzh@chromium.org
 fayang@chromium.org
 ianswett@chromium.org
diff --git a/remoting/host/chromoting_host_services_client_unittest.cc b/remoting/host/chromoting_host_services_client_unittest.cc
index b846ecb2..fec77aad 100644
--- a/remoting/host/chromoting_host_services_client_unittest.cc
+++ b/remoting/host/chromoting_host_services_client_unittest.cc
@@ -39,7 +39,7 @@
 
  protected:
   void SetChromeRemoteDesktopSessionEnvVar(bool is_crd_session);
-  void WaitForInvitationSent();
+  void WaitForServerEndpointCreated();
   void WaitForSessionServicesBound();
   void SetRemoteDisconnectCallback(base::OnceClosure callback);
 
@@ -53,10 +53,10 @@
       receivers_;
 
  private:
-  void OnInvitationSent();
+  void OnServerEndpointCreated();
 
-  // Used to block the thread until the server has sent out an invitation.
-  std::unique_ptr<base::RunLoop> on_invitation_sent_run_loop_;
+  // Used to block the thread until the server has created the endpoint.
+  std::unique_ptr<base::RunLoop> on_server_endpoint_created_run_loop_;
 
   // Used to block the thread until a session services bind request is received.
   std::unique_ptr<base::RunLoop> session_services_bound_run_loop_;
@@ -72,10 +72,11 @@
   ipc_server_ = std::make_unique<
       named_mojo_ipc_server::NamedMojoIpcServer<mojom::ChromotingHostServices>>(
       test_server_name, this, base::BindRepeating(&IsTrustedMojoEndpoint));
-  ipc_server_->set_on_invitation_sent_callback_for_testing(
-      base::BindRepeating(&ChromotingHostServicesClientTest::OnInvitationSent,
-                          base::Unretained(this)));
-  on_invitation_sent_run_loop_ = std::make_unique<base::RunLoop>();
+  ipc_server_->set_on_server_endpoint_created_callback_for_testing(
+      base::BindRepeating(
+          &ChromotingHostServicesClientTest::OnServerEndpointCreated,
+          base::Unretained(this)));
+  on_server_endpoint_created_run_loop_ = std::make_unique<base::RunLoop>();
   session_services_bound_run_loop_ = std::make_unique<base::RunLoop>();
   SetChromeRemoteDesktopSessionEnvVar(true);
 }
@@ -107,9 +108,9 @@
   // No-op on other platforms.
 }
 
-void ChromotingHostServicesClientTest::WaitForInvitationSent() {
-  on_invitation_sent_run_loop_->Run();
-  on_invitation_sent_run_loop_ = std::make_unique<base::RunLoop>();
+void ChromotingHostServicesClientTest::WaitForServerEndpointCreated() {
+  on_server_endpoint_created_run_loop_->Run();
+  on_server_endpoint_created_run_loop_ = std::make_unique<base::RunLoop>();
 }
 
 void ChromotingHostServicesClientTest::WaitForSessionServicesBound() {
@@ -122,8 +123,8 @@
   client_->on_session_disconnected_callback_for_testing_ = std::move(callback);
 }
 
-void ChromotingHostServicesClientTest::OnInvitationSent() {
-  on_invitation_sent_run_loop_->Quit();
+void ChromotingHostServicesClientTest::OnServerEndpointCreated() {
+  on_server_endpoint_created_run_loop_->Quit();
 }
 
 TEST_F(ChromotingHostServicesClientTest,
@@ -138,7 +139,7 @@
        NotInRemoteDesktopSession_GetSessionServicesReturnsNull) {
   SetChromeRemoteDesktopSessionEnvVar(false);
   ipc_server_->StartServer();
-  WaitForInvitationSent();
+  WaitForServerEndpointCreated();
   ASSERT_EQ(client_->GetSessionServices(), nullptr);
 }
 
@@ -147,7 +148,7 @@
 TEST_F(ChromotingHostServicesClientTest,
        CallGetSessionServicesTwice_SamePointerReturned) {
   ipc_server_->StartServer();
-  WaitForInvitationSent();
+  WaitForServerEndpointCreated();
   auto* session_services = client_->GetSessionServices();
   ASSERT_NE(session_services, nullptr);
   WaitForSessionServicesBound();
@@ -158,7 +159,7 @@
 TEST_F(ChromotingHostServicesClientTest,
        ServerClosesReceiverAndClientReconnects) {
   ipc_server_->StartServer();
-  WaitForInvitationSent();
+  WaitForServerEndpointCreated();
   ASSERT_NE(client_->GetSessionServices(), nullptr);
   WaitForSessionServicesBound();
   ASSERT_EQ(receivers_.size(), 1u);
diff --git a/services/accessibility/BUILD.gn b/services/accessibility/BUILD.gn
index e9b878cd..0988306f 100644
--- a/services/accessibility/BUILD.gn
+++ b/services/accessibility/BUILD.gn
@@ -27,6 +27,18 @@
       "accessibility_service_cros.h",
       "assistive_technology_controller_impl.cc",
       "assistive_technology_controller_impl.h",
+      "features/automation_internal_bindings.cc",
+      "features/automation_internal_bindings.h",
+      "features/v8_manager.cc",
+      "features/v8_manager.h",
+    ]
+    public_deps += [
+      "//gin",
+      "//ui/accessibility:accessibility",
+    ]
+    configs += [
+      "//tools/v8_context_snapshot:use_v8_context_snapshot",
+      "//v8:external_startup_data",
     ]
   } else {
     sources += [
@@ -62,7 +74,9 @@
     sources = [
       "accessibility_service_cros_unittest.cc",
       "assistive_technology_controller_impl_unittest.cc",
+      "features/v8_manager_unittest.cc",
     ]
+    deps += [ "//ui/accessibility:accessibility" ]
   } else {
     sources = [ "accessibility_service_chrome_unittest.cc" ]
   }
diff --git a/services/accessibility/README.md b/services/accessibility/README.md
index 90c08e7a..72ac11e2 100644
--- a/services/accessibility/README.md
+++ b/services/accessibility/README.md
@@ -1,5 +1,12 @@
+# Accessibility Service
+
 The accessibility service on Chrome OS provides accessibility services like
 ChromeVox, Select-to-Speak, Switch Access and Dictation, and a framework API
 to communicate with the operating system. On Chrome desktop, the
-accessibility service can be used by native APIs to expose accessibility
+accessibility service could be used by native APIs to expose accessibility
 information to the operating system.
+
+## Chrome OS
+
+On Chrome OS, the service runs a V8 instance which will execute Accessibility
+feature Javascript. The V8 implementation is in features/.
diff --git a/services/accessibility/accessibility_service_cros_unittest.cc b/services/accessibility/accessibility_service_cros_unittest.cc
index 88be937..6d45b7b 100644
--- a/services/accessibility/accessibility_service_cros_unittest.cc
+++ b/services/accessibility/accessibility_service_cros_unittest.cc
@@ -59,10 +59,12 @@
                         mojom::AssistiveTechnologyType feature) {
     return service->at_controller_->IsFeatureEnabled(feature);
   }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
 };
 
 TEST_F(AccessibilityServiceCrosTest, BindsAutomation) {
-  base::test::SingleThreadTaskEnvironment task_environment;
   mojo::PendingReceiver<mojom::AccessibilityService> receiver;
   std::unique_ptr<AccessibilityServiceCros> service =
       std::make_unique<AccessibilityServiceCros>(std::move(receiver));
@@ -72,8 +74,33 @@
   EXPECT_TRUE(client.IsBound());
 }
 
-TEST_F(AccessibilityServiceCrosTest, BindsAssistiveTechnologyController) {
-  base::test::SingleThreadTaskEnvironment task_environment;
+TEST_F(AccessibilityServiceCrosTest,
+       BindsAssistiveTechnologyControllerWithNoFeaturesEnabled) {
+  mojo::PendingReceiver<mojom::AccessibilityService> receiver;
+  std::unique_ptr<AccessibilityServiceCros> service =
+      std::make_unique<AccessibilityServiceCros>(std::move(receiver));
+
+  FakeAssistiveTechnologyController at_controller(service.get());
+  at_controller.BindAssistiveTechnologyController(
+      std::vector<mojom::AssistiveTechnologyType>());
+  EXPECT_TRUE(at_controller.IsBound());
+
+  EXPECT_FALSE(IsFeatureEnabled(service.get(),
+                                mojom::AssistiveTechnologyType::kChromeVox));
+  EXPECT_FALSE(IsFeatureEnabled(service.get(),
+                                mojom::AssistiveTechnologyType::kAutoClick));
+  EXPECT_FALSE(IsFeatureEnabled(service.get(),
+                                mojom::AssistiveTechnologyType::kSwitchAccess));
+  EXPECT_FALSE(IsFeatureEnabled(service.get(),
+                                mojom::AssistiveTechnologyType::kDictation));
+  EXPECT_FALSE(IsFeatureEnabled(service.get(),
+                                mojom::AssistiveTechnologyType::kMagnifier));
+  EXPECT_FALSE(IsFeatureEnabled(
+      service.get(), mojom::AssistiveTechnologyType::kSelectToSpeak));
+}
+
+TEST_F(AccessibilityServiceCrosTest,
+       BindsAssistiveTechnologyControllerWithSomeFeaturesEnabled) {
   mojo::PendingReceiver<mojom::AccessibilityService> receiver;
   std::unique_ptr<AccessibilityServiceCros> service =
       std::make_unique<AccessibilityServiceCros>(std::move(receiver));
diff --git a/services/accessibility/assistive_technology_controller_impl.cc b/services/accessibility/assistive_technology_controller_impl.cc
index 4378181..c6e99a8 100644
--- a/services/accessibility/assistive_technology_controller_impl.cc
+++ b/services/accessibility/assistive_technology_controller_impl.cc
@@ -4,6 +4,11 @@
 
 #include "services/accessibility/assistive_technology_controller_impl.h"
 
+#include <memory>
+
+#include "services/accessibility/automation_impl.h"
+#include "services/accessibility/features/v8_manager.h"
+
 namespace ax {
 
 AssistiveTechnologyControllerImpl::AssistiveTechnologyControllerImpl() =
@@ -15,19 +20,29 @@
 void AssistiveTechnologyControllerImpl::Bind(
     mojo::PendingReceiver<mojom::AssistiveTechnologyController>
         at_controller_receiver) {
-  at_controller_receivers_.Add(this, std::move(at_controller_receiver));
+  DCHECK(!at_controller_receiver_.is_bound());
+  at_controller_receiver_.Bind(std::move(at_controller_receiver));
+}
+
+void AssistiveTechnologyControllerImpl::BindAutomation(
+    mojo::PendingRemote<mojom::Automation> automation,
+    mojo::PendingReceiver<mojom::AutomationClient> automation_client) {
+  if (automation_bound_closure_for_test_) {
+    std::move(automation_bound_closure_for_test_).Run();
+  }
+  // TODO(crbug.com/1355633): Bind to Automation in the embedding OS
+  // after updating the mojom. See go/chromeos-atp-v8-design.
 }
 
 void AssistiveTechnologyControllerImpl::EnableAssistiveTechnology(
     mojom::AssistiveTechnologyType type,
     bool enabled) {
-  if (enabled) {
-    enabled_ATs_.insert(type);
-  } else {
+  auto it = enabled_ATs_.find(type);
+  if (enabled && it == enabled_ATs_.end()) {
+    enabled_ATs_[type] = GetOrMakeV8Manager(type);
+  } else if (!enabled && it != enabled_ATs_.end()) {
     enabled_ATs_.erase(type);
   }
-  // TODO(crbug.com/1355633): Load or unload features from V8.
-  // Turn on/off V8 if enabled_ATs_ size changed between 0 and non-zero.
 }
 
 bool AssistiveTechnologyControllerImpl::IsFeatureEnabled(
@@ -35,4 +50,37 @@
   return enabled_ATs_.find(type) != enabled_ATs_.end();
 }
 
+void AssistiveTechnologyControllerImpl::SetAutomationBoundClosureForTest(
+    base::OnceClosure closure) {
+  automation_bound_closure_for_test_ = std::move(closure);
+}
+
+void AssistiveTechnologyControllerImpl::RunScriptForTest(
+    mojom::AssistiveTechnologyType type,
+    const std::string& script,
+    base::OnceClosure on_complete) {
+  enabled_ATs_[type]->ExecuteScript(script, std::move(on_complete));
+}
+
+scoped_refptr<V8Manager> AssistiveTechnologyControllerImpl::GetOrMakeV8Manager(
+    mojom::AssistiveTechnologyType type) {
+  // For the first one we can ask it to initialize v8.
+  if (!v8_initialized_) {
+    V8Manager::InitializeV8();
+    v8_initialized_ = true;
+  }
+
+  scoped_refptr<V8Manager> v8_manager = V8Manager::Create();
+
+  // Install bindings on the global context depending on the type.
+  // For example, some types may need TTS and some may not. All need Automation.
+  v8_manager->InstallAutomation(weak_ptr_factory_.GetWeakPtr());
+  // TODO(crbug.com/1355633): Install other bindings based on the type
+  // once they are implemented.
+
+  // After installing all bindings, initialize.
+  v8_manager->AddV8Bindings();
+  return v8_manager;
+}
+
 }  // namespace ax
diff --git a/services/accessibility/assistive_technology_controller_impl.h b/services/accessibility/assistive_technology_controller_impl.h
index f8166a7..6324de36 100644
--- a/services/accessibility/assistive_technology_controller_impl.h
+++ b/services/accessibility/assistive_technology_controller_impl.h
@@ -5,13 +5,16 @@
 #ifndef SERVICES_ACCESSIBILITY_ASSISTIVE_TECHNOLOGY_CONTROLLER_IMPL_H_
 #define SERVICES_ACCESSIBILITY_ASSISTIVE_TECHNOLOGY_CONTROLLER_IMPL_H_
 
+#include <memory>
 #include <set>
+
 #include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 #include "services/accessibility/public/mojom/accessibility_service.mojom.h"
 
 namespace ax {
+class V8Manager;
 
 // Implementation of the assistive technology controller interface
 // for Chrome OS. This tracks which features are enabled and will
@@ -26,9 +29,16 @@
   AssistiveTechnologyControllerImpl& operator=(
       const AssistiveTechnologyControllerImpl&) = delete;
 
+  // Called by the AccessibilityService.
   void Bind(mojo::PendingReceiver<mojom::AssistiveTechnologyController>
                 at_controller_receiver);
 
+  // Called by the Automation implementation within a V8 isolate to request
+  // binding to the OS automation and automation client.
+  void BindAutomation(
+      mojo::PendingRemote<mojom::Automation> automation,
+      mojo::PendingReceiver<mojom::AutomationClient> automation_client);
+
   // TODO(crbug.com/1355633): Override this method from
   // mojom::AssistiveTechnologyController:
   void EnableAssistiveTechnology(mojom::AssistiveTechnologyType type,
@@ -36,11 +46,34 @@
 
   bool IsFeatureEnabled(mojom::AssistiveTechnologyType type) const;
 
- private:
-  std::set<mojom::AssistiveTechnologyType> enabled_ATs_;
+  // Methods for testing.
+  void SetAutomationBoundClosureForTest(base::OnceClosure closure);
+  void RunScriptForTest(mojom::AssistiveTechnologyType type,
+                        const std::string& script,
+                        base::OnceClosure on_complete);
 
-  mojo::ReceiverSet<mojom::AssistiveTechnologyController>
-      at_controller_receivers_;
+ private:
+  scoped_refptr<V8Manager> GetOrMakeV8Manager(
+      mojom::AssistiveTechnologyType type);
+
+  std::map<mojom::AssistiveTechnologyType, scoped_refptr<V8Manager>>
+      enabled_ATs_;
+
+  // Whether V8 has been initialized once. Allows us to only
+  // initialize V8 for the service one time. Assumes this class has the same
+  // lifetime as the service (as it's constructed and owned by the
+  // AccessibilityServiceCros).
+  bool v8_initialized_ = false;
+
+  // For testing.
+  base::OnceClosure automation_bound_closure_for_test_;
+
+  // This class is a receiver for mojom::AssistiveTechnologyController.
+  mojo::Receiver<mojom::AssistiveTechnologyController> at_controller_receiver_{
+      this};
+
+  base::WeakPtrFactory<AssistiveTechnologyControllerImpl> weak_ptr_factory_{
+      this};
 };
 
 }  // namespace ax
diff --git a/services/accessibility/assistive_technology_controller_impl_unittest.cc b/services/accessibility/assistive_technology_controller_impl_unittest.cc
index 52f8e481..c1f7fba 100644
--- a/services/accessibility/assistive_technology_controller_impl_unittest.cc
+++ b/services/accessibility/assistive_technology_controller_impl_unittest.cc
@@ -3,12 +3,58 @@
 // found in the LICENSE file.
 
 #include "services/accessibility/assistive_technology_controller_impl.h"
+#include "base/test/task_environment.h"
 #include "services/accessibility/public/mojom/accessibility_service.mojom-shared.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ax {
 
-TEST(AssistiveTechnologyControllerTest, EnableAndDisableFeatures) {
+class AssistiveTechnologyControllerTest : public testing::Test {
+ public:
+  AssistiveTechnologyControllerTest() = default;
+  AssistiveTechnologyControllerTest(const AssistiveTechnologyControllerTest&) =
+      delete;
+  AssistiveTechnologyControllerTest& operator=(
+      const AssistiveTechnologyControllerTest&) = delete;
+  ~AssistiveTechnologyControllerTest() override = default;
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+};
+
+// Disabling disabled features is a no-op.
+TEST_F(AssistiveTechnologyControllerTest, DisablesDisabledFeatures) {
+  AssistiveTechnologyControllerImpl at_controller;
+  // Features begin disabled at construction.
+  for (int i = static_cast<int>(mojom::AssistiveTechnologyType::kMinValue);
+       i < static_cast<int>(mojom::AssistiveTechnologyType::kMaxValue); i++) {
+    mojom::AssistiveTechnologyType type =
+        static_cast<mojom::AssistiveTechnologyType>(i);
+    EXPECT_FALSE(at_controller.IsFeatureEnabled(type));
+  }
+  // I have disabled your features. Pray I do not disable them further.
+  for (int i = static_cast<int>(mojom::AssistiveTechnologyType::kMinValue);
+       i < static_cast<int>(mojom::AssistiveTechnologyType::kMaxValue); i++) {
+    mojom::AssistiveTechnologyType type =
+        static_cast<mojom::AssistiveTechnologyType>(i);
+    at_controller.EnableAssistiveTechnology(type, /*enabled=*/false);
+    EXPECT_FALSE(at_controller.IsFeatureEnabled(type));
+  }
+}
+
+// Enables one feature several times in a row to ensure it doesn't cause issues.
+TEST_F(AssistiveTechnologyControllerTest, EnablesEnabledFeatures) {
+  AssistiveTechnologyControllerImpl at_controller;
+  for (int i = 0; i < 3; i++) {
+    at_controller.EnableAssistiveTechnology(
+        mojom::AssistiveTechnologyType::kDictation, /*enabled=*/true);
+    EXPECT_TRUE(at_controller.IsFeatureEnabled(
+        mojom::AssistiveTechnologyType::kDictation));
+  }
+}
+
+// Toggles all features.
+TEST_F(AssistiveTechnologyControllerTest, EnableAndDisableAllFeatures) {
   AssistiveTechnologyControllerImpl at_controller;
   // Turn everything on.
   for (int i = static_cast<int>(mojom::AssistiveTechnologyType::kMinValue);
@@ -28,4 +74,36 @@
   }
 }
 
+TEST_F(AssistiveTechnologyControllerTest,
+       BindsAutomationMojomAfterEnablingFeature) {
+  AssistiveTechnologyControllerImpl at_controller;
+  base::RunLoop automation_bound_runner_;
+  at_controller.SetAutomationBoundClosureForTest(
+      automation_bound_runner_.QuitClosure());
+  at_controller.EnableAssistiveTechnology(
+      mojom::AssistiveTechnologyType::kMagnifier, /*enabled=*/true);
+  automation_bound_runner_.Run();
+  // TODO(crbug.com/1355633): After adding mojom to bind automation, we can
+  // start passing a11y events to V8 here.
+}
+
+TEST_F(AssistiveTechnologyControllerTest,
+       BindsAutomationV8AfterEnablingFeature) {
+  AssistiveTechnologyControllerImpl at_controller;
+  at_controller.EnableAssistiveTechnology(
+      mojom::AssistiveTechnologyType::kChromeVox, /*enabled=*/true);
+  base::RunLoop script_waiter;
+  // This script will not compile if chrome.automation.GetFocus() is not found
+  // in V8, causing the test to crash.
+  // TODO(crbug.com/1355633): After adding mojom to bind automation, we can
+  // start passing a11y events to V8 and then ensuring calling these methods
+  // changes the underlying accessibility info.
+  std::string script = R"JS(
+    chrome.automation.GetFocus();
+  )JS";
+  at_controller.RunScriptForTest(mojom::AssistiveTechnologyType::kChromeVox,
+                                 script, script_waiter.QuitClosure());
+  script_waiter.Run();
+}
+
 }  // namespace ax
diff --git a/services/accessibility/features/DEPS b/services/accessibility/features/DEPS
new file mode 100644
index 0000000..2e9e102
--- /dev/null
+++ b/services/accessibility/features/DEPS
@@ -0,0 +1,14 @@
+include_rules = [
+  "+gin",
+  "+ui/accessibility/ax_event.h",
+  "+ui/accessibility/ax_node_id_forward.h",
+  "+ui/accessibility/ax_node_position.h",
+  "+ui/accessibility/ax_relative_bounds.h",
+  "+ui/accessibility/ax_tree_id.h",
+  "+ui/accessibility/ax_tree_update.h",
+  "+ui/accessibility/platform/automation/automation_tree_manager_owner.h",
+  "+ui/accessibility/platform/automation/automation_v8_bindings.h",
+  "+ui/accessibility/platform/automation/automation_v8_router.h",
+  "+ui/accessibility/platform/automation/automation_api_util.h",
+  "+v8/include",
+]
diff --git a/services/accessibility/features/automation_internal_bindings.cc b/services/accessibility/features/automation_internal_bindings.cc
new file mode 100644
index 0000000..f5a30223
--- /dev/null
+++ b/services/accessibility/features/automation_internal_bindings.cc
@@ -0,0 +1,224 @@
+// 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 "services/accessibility/features/automation_internal_bindings.h"
+
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
+#include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
+#include "gin/function_template.h"
+#include "services/accessibility/assistive_technology_controller_impl.h"
+#include "services/accessibility/automation_impl.h"
+#include "services/accessibility/features/v8_manager.h"
+#include "services/accessibility/public/mojom/accessibility_service.mojom.h"
+#include "ui/accessibility/ax_node_position.h"
+#include "ui/accessibility/ax_tree_id.h"
+#include "ui/accessibility/platform/automation/automation_api_util.h"
+#include "ui/accessibility/platform/automation/automation_v8_router.h"
+#include "v8/include/v8-local-handle.h"
+#include "v8/include/v8-template.h"
+
+namespace ax {
+
+AutomationInternalBindings::AutomationInternalBindings(
+    base::WeakPtr<V8Manager> v8_manager,
+    base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller,
+    scoped_refptr<base::SequencedTaskRunner> main_runner)
+    : v8_manager_(v8_manager),
+      automation_v8_bindings_(std::make_unique<ui::AutomationV8Bindings>(
+          /*AutomationTreeManagerOwner=*/this,
+          /*AutomationV8Router=*/this)) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  Bind(at_controller, main_runner);
+}
+
+AutomationInternalBindings::~AutomationInternalBindings() = default;
+void AutomationInternalBindings::AddRoutesToTemplate(
+    v8::Local<v8::ObjectTemplate>* object_template) {
+  template_ = object_template;
+  automation_v8_bindings_->AddV8Routes();
+  // TODO(crbug.com/1357889): Add bindings for AutomationInternalAPI functions,
+  // like automationInternal.enableTree, etc, paralleling the implementation in
+  // extensions/browser/api/automation_internal/automation_internal_api.h.
+  template_ = nullptr;
+}
+
+ui::AutomationV8Bindings* AutomationInternalBindings::GetAutomationV8Bindings()
+    const {
+  DCHECK(automation_v8_bindings_);
+  return automation_v8_bindings_.get();
+}
+
+void AutomationInternalBindings::NotifyTreeEventListenersChanged() {
+  // TODO(crbug.com/1357889): Implement.
+}
+
+void AutomationInternalBindings::ThrowInvalidArgumentsException(
+    bool is_fatal) const {
+  GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal(
+      GetIsolate(),
+      "Invalid arguments to AutomationInternalBindings function"));
+  if (!is_fatal)
+    return;
+  LOG(FATAL) << "Invalid arguments to AutomationInternalBindings function";
+  // TODO(crbug.com/1357889): Could print a stack trace from JS, paralleling
+  // AutomationInternalCustomBindings.
+}
+
+v8::Isolate* AutomationInternalBindings::GetIsolate() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(v8_manager_);
+  return v8_manager_->GetIsolate();
+}
+
+v8::Local<v8::Context> AutomationInternalBindings::GetContext() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(v8_manager_);
+  return v8_manager_->GetContext();
+}
+
+void AutomationInternalBindings::RouteHandlerFunction(
+    const std::string& name,
+    scoped_refptr<ui::V8HandlerFunctionWrapper> handler_function_wrapper) {
+  DCHECK(template_);
+  (*template_)
+      ->Set(GetIsolate(), name.c_str(),
+            gin::CreateFunctionTemplate(
+                GetIsolate(),
+                base::BindRepeating(&ui::V8HandlerFunctionWrapper::Run,
+                                    handler_function_wrapper)));
+}
+
+ui::TreeChangeObserverFilter
+AutomationInternalBindings::ParseTreeChangeObserverFilter(
+    const std::string& filter) const {
+  return ui::TreeChangeObserverFilter::kAllTreeChanges;
+}
+
+std::string AutomationInternalBindings::GetMarkerTypeString(
+    ax::mojom::MarkerType type) const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return "";
+}
+
+std::string AutomationInternalBindings::GetFocusedStateString() const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return "focused";
+}
+
+std::string AutomationInternalBindings::GetOffscreenStateString() const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return "offscreen";
+}
+
+std::string
+AutomationInternalBindings::GetLocalizedStringForImageAnnotationStatus(
+    ax::mojom::ImageAnnotationStatus status) const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return "";
+}
+
+std::string AutomationInternalBindings::GetTreeChangeTypeString(
+    ax::mojom::Mutation change_type) const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return ui::ToString(change_type);
+}
+
+std::string AutomationInternalBindings::GetEventTypeString(
+    const std::tuple<ax::mojom::Event, ui::AXEventGenerator::Event>& event_type)
+    const {
+  // TODO(crbug.com/1357889): Implement based on Automation API.
+  return "";
+}
+
+void AutomationInternalBindings::DispatchEvent(
+    const std::string& event_name,
+    const base::Value::List& event_args) const {
+  // TODO(crbug.com/1357889): Send the event to V8.
+}
+
+void AutomationInternalBindings::Enable() {
+  // TODO(crbug.com/1357889): Send to the OS AutomationClient.
+  // automation_client_remote_->Enable();
+}
+
+void AutomationInternalBindings::Disable() {
+  // TODO(crbug.com/1357889): Send to the OS AutomationClient.
+  // automation_client_remote_->Disable();
+}
+
+void AutomationInternalBindings::EnableTree(const ui::AXTreeID& tree_id) {
+  // TODO(crbug.com/1357889): Send to the OS AutomationClient.
+  // automation_client_remote_->EnableTree(tree_id);
+}
+
+void AutomationInternalBindings::PerformAction(
+    const ui::AXActionData& action_data) {
+  // TODO(crbug.com/1357889): Send to the OS AutomationClient.
+  // automation_client_remote_->PerformAction(action_data);
+}
+
+void AutomationInternalBindings::Bind(
+    base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller,
+    scoped_refptr<base::SequencedTaskRunner> main_runner) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  main_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller,
+             mojo::PendingReceiver<mojom::AutomationClient> remote,
+             mojo::PendingRemote<mojom::Automation> receiver) {
+            if (at_controller) {
+              at_controller->BindAutomation(std::move(receiver),
+                                            std::move(remote));
+            }
+          },
+          at_controller, automation_client_remote_.BindNewPipeAndPassReceiver(),
+          automation_receiver_.BindNewPipeAndPassRemote()));
+}
+
+void AutomationInternalBindings::DispatchTreeDestroyedEvent(
+    const ui::AXTreeID& tree_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TODO(crbug.com/1357889): Dispatch to V8, via
+  // automationInternal.OnAccessibilityTreeDestroyed, paralleling
+  // extensions/browser/api/automation_internal/automation_event_router.cc.
+}
+
+void AutomationInternalBindings::DispatchActionResult(
+    const ui::AXActionData& data,
+    bool result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TODO(crbug.com/1357889): Dispatch to V8 paralleling the implementation
+  // in extensions/browser/api/automation_internal/automation_event_router.cc.
+}
+
+void AutomationInternalBindings::DispatchAccessibilityEvents(
+    const ui::AXTreeID& tree_id,
+    const std::vector<ui::AXTreeUpdate>& updates,
+    const gfx::Point& mouse_location,
+    const std::vector<ui::AXEvent>& events) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  OnAccessibilityEvents(tree_id, events, updates, mouse_location,
+                        /*is_active_profile=*/true);
+}
+
+void AutomationInternalBindings::DispatchAccessibilityLocationChange(
+    const ui::AXTreeID& tree_id,
+    int node_id,
+    const ui::AXRelativeBounds& bounds) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  OnAccessibilityLocationChange(tree_id, node_id, bounds);
+}
+
+void AutomationInternalBindings::DispatchGetTextLocationResult(
+    const ax::mojom::AXActionData& data,
+    gfx::Rect rect) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TODO(crbug.com/1357889): Dispatch to V8 paralleling the implementation
+  // in extensions/browser/api/automation_internal/automation_event_router.cc.
+}
+
+}  // namespace ax
diff --git a/services/accessibility/features/automation_internal_bindings.h b/services/accessibility/features/automation_internal_bindings.h
new file mode 100644
index 0000000..a13e036a
--- /dev/null
+++ b/services/accessibility/features/automation_internal_bindings.h
@@ -0,0 +1,122 @@
+// 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 SERVICES_ACCESSIBILITY_FEATURES_AUTOMATION_INTERNAL_BINDINGS_H_
+#define SERVICES_ACCESSIBILITY_FEATURES_AUTOMATION_INTERNAL_BINDINGS_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/accessibility/assistive_technology_controller_impl.h"
+#include "services/accessibility/public/mojom/accessibility_service.mojom.h"
+#include "ui/accessibility/ax_event.h"
+#include "ui/accessibility/ax_node_id_forward.h"
+#include "ui/accessibility/ax_relative_bounds.h"
+#include "ui/accessibility/ax_tree_id.h"
+#include "ui/accessibility/ax_tree_update.h"
+#include "ui/accessibility/platform/automation/automation_tree_manager_owner.h"
+#include "ui/accessibility/platform/automation/automation_v8_bindings.h"
+#include "ui/accessibility/platform/automation/automation_v8_router.h"
+
+namespace ax {
+class V8Manager;
+
+// AutomationInternalBindings creates the Javascript V8 bindings for the
+// Automation API in the Accessibility Service. It runs in a V8 thread.
+// The service may have multiple AutomationInternalBindings, one per
+// V8 isolate, each owned by a V8Manager.
+class AutomationInternalBindings : public mojom::Automation,
+                                   public ui::AutomationTreeManagerOwner,
+                                   public ui::AutomationV8Router {
+ public:
+  explicit AutomationInternalBindings(
+      base::WeakPtr<V8Manager> v8_manager,
+      base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller,
+      scoped_refptr<base::SequencedTaskRunner> main_runner);
+  ~AutomationInternalBindings() override;
+  AutomationInternalBindings(const AutomationInternalBindings&) = delete;
+  AutomationInternalBindings& operator=(const AutomationInternalBindings&) =
+      delete;
+
+  // Creates bindings between C++ functions and Javascript by adding
+  // V8 bindings to the given |object_template|.
+  void AddRoutesToTemplate(v8::Local<v8::ObjectTemplate>* object_template);
+
+  // ui::AutomationTreeManagerOwner:
+  ui::AutomationV8Bindings* GetAutomationV8Bindings() const override;
+  void NotifyTreeEventListenersChanged() override;
+
+  // ui::AutomationV8Router:
+  void ThrowInvalidArgumentsException(bool is_fatal = true) const override;
+  v8::Isolate* GetIsolate() const override;
+  v8::Local<v8::Context> GetContext() const override;
+  void RouteHandlerFunction(const std::string& name,
+                            scoped_refptr<ui::V8HandlerFunctionWrapper>
+                                handler_function_wrapper) override;
+  ui::TreeChangeObserverFilter ParseTreeChangeObserverFilter(
+      const std::string& filter) const override;
+  std::string GetMarkerTypeString(ax::mojom::MarkerType type) const override;
+  std::string GetFocusedStateString() const override;
+  std::string GetOffscreenStateString() const override;
+  std::string GetLocalizedStringForImageAnnotationStatus(
+      ax::mojom::ImageAnnotationStatus status) const override;
+  std::string GetTreeChangeTypeString(
+      ax::mojom::Mutation change_type) const override;
+  std::string GetEventTypeString(
+      const std::tuple<ax::mojom::Event, ui::AXEventGenerator::Event>&
+          event_type) const override;
+  void StartCachingAccessibilityTrees() override {}
+  void StopCachingAccessibilityTrees() override {}
+  void DispatchEvent(const std::string& event_name,
+                     const base::Value::List& event_args) const override;
+
+  // Methods to communicate back to the OS main process. These should get bound
+  // to V8 JS methods and called from there.
+  void Enable();
+  void Disable();
+  void EnableTree(const ui::AXTreeID& tree_id);
+  void PerformAction(const ui::AXActionData& action_data);
+
+ private:
+  // Binds to Automation in the OS on the |main_runner|.
+  void Bind(base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller,
+            scoped_refptr<base::SequencedTaskRunner> main_runner);
+
+  // TODO(crbug.com/1355633): Override these from
+  // mojom::Automation:
+  void DispatchTreeDestroyedEvent(const ui::AXTreeID& tree_id);
+  void DispatchActionResult(const ui::AXActionData& data, bool result);
+  void DispatchAccessibilityEvents(const ui::AXTreeID& tree_id,
+                                   const std::vector<ui::AXTreeUpdate>& updates,
+                                   const gfx::Point& mouse_location,
+                                   const std::vector<ui::AXEvent>& events);
+  void DispatchAccessibilityLocationChange(const ui::AXTreeID& tree_id,
+                                           int node_id,
+                                           const ui::AXRelativeBounds& bounds);
+  void DispatchGetTextLocationResult(const ax::mojom::AXActionData& data,
+                                     gfx::Rect rect);
+
+  // Used during object template creation.
+  v8::Local<v8::ObjectTemplate>* template_;
+
+  base::WeakPtr<V8Manager> v8_manager_;
+
+  std::unique_ptr<ui::AutomationV8Bindings> automation_v8_bindings_;
+
+  mojo::Receiver<mojom::Automation> automation_receiver_{this};
+
+  // We can send automation info back to the main Service thread with the
+  // automation client interface.
+  mojo::Remote<mojom::AutomationClient> automation_client_remote_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  base::WeakPtrFactory<AutomationInternalBindings> weak_ptr_factory_{this};
+};
+
+}  // namespace ax
+
+#endif  // SERVICES_ACCESSIBILITY_FEATURES_AUTOMATION_INTERNAL_BINDINGS_H_
diff --git a/services/accessibility/features/v8_manager.cc b/services/accessibility/features/v8_manager.cc
new file mode 100644
index 0000000..2ba50871d
--- /dev/null
+++ b/services/accessibility/features/v8_manager.cc
@@ -0,0 +1,260 @@
+// 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 "services/accessibility/features/v8_manager.h"
+
+#include "base/functional/callback_forward.h"
+#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/task/single_thread_task_runner_thread_mode.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "gin/arguments.h"
+#include "gin/array_buffer.h"
+#include "gin/function_template.h"
+#include "gin/public/context_holder.h"
+#include "gin/public/isolate_holder.h"
+#include "gin/v8_initializer.h"
+#include "services/accessibility/assistive_technology_controller_impl.h"
+#include "services/accessibility/features/automation_internal_bindings.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-template.h"
+
+namespace ax {
+
+namespace {
+
+// Methods for debugging.
+// TODO(crbug.com/1355633): Use blink::mojom::DevToolsAgent interface to attach
+// to Chrome devtools.
+static std::string PrintArgs(gin::Arguments* args) {
+  std::string statement;
+  while (!args->PeekNext().IsEmpty()) {
+    v8::String::Utf8Value value(args->isolate(), args->PeekNext());
+    statement += base::StringPrintf("%s ", *value);
+    args->Skip();
+  }
+  return statement;
+}
+
+// Provides temporary functionality for atpconsole.log.
+static void ConsoleLog(gin::Arguments* args) {
+  LOG(ERROR) << "AccessibilityService V8: Info: " << PrintArgs(args);
+}
+
+// Provides temporary functionality for atpconsole.warn.
+static void ConsoleWarn(gin::Arguments* args) {
+  LOG(ERROR) << "AccessibilityService V8: Error: " << PrintArgs(args);
+}
+
+// Provides temporary functionality for atpconsole.error.
+static void ConsoleError(gin::Arguments* args) {
+  LOG(ERROR) << "AccessibilityService V8: Error: " << PrintArgs(args);
+}
+
+}  // namespace
+
+// static
+scoped_refptr<V8Manager> V8Manager::Create() {
+  // Create task runner for running V8. The Isolate should only ever be accessed
+  // on this thread.
+  auto v8_runner = base::ThreadPool::CreateSingleThreadTaskRunner(
+      {base::TaskPriority::USER_BLOCKING,
+       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, base::MayBlock()},
+      base::SingleThreadTaskRunnerThreadMode::DEDICATED);
+  // Get a reference to the current SequencedTaskRunner for posting tasks back
+  // to the constructor and current thread.
+  auto main_runner = base::SequencedTaskRunner::GetCurrentDefault();
+  scoped_refptr<V8Manager> result(new V8Manager(v8_runner, main_runner));
+  v8_runner->PostTask(
+      FROM_HERE, base::BindOnce(&V8Manager::ConstructIsolateOnThread, result));
+  return result;
+}
+
+// static
+void V8Manager::InitializeV8() {
+  // Only initialize V8 for the Accessibility Service once.
+  if (!gin::IsolateHolder::Initialized()) {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+    gin::V8Initializer::LoadV8Snapshot();
+#endif
+    gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
+                                   gin::ArrayBufferAllocator::SharedInstance());
+  }
+}
+
+V8Manager::V8Manager(scoped_refptr<base::SingleThreadTaskRunner> v8_runner,
+                     scoped_refptr<base::SequencedTaskRunner> main_runner)
+    : base::RefCountedDeleteOnSequence<V8Manager>(v8_runner),
+      v8_runner_(v8_runner),
+      main_runner_(main_runner) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
+
+V8Manager::~V8Manager() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!isolate_holder_)
+    return;
+
+  isolate_holder_->isolate()->TerminateExecution();
+  context_holder_.reset();
+  isolate_holder_.reset();
+}
+
+void V8Manager::InstallAutomation(
+    base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+  v8_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&V8Manager::BindAutomationOnThread,
+                                weak_ptr_factory_.GetWeakPtr(), at_controller));
+}
+
+void V8Manager::AddV8Bindings() {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+  v8_runner_->PostTask(FROM_HERE,
+                       base::BindOnce(&V8Manager::AddV8BindingsOnThread,
+                                      weak_ptr_factory_.GetWeakPtr()));
+}
+
+void V8Manager::ExecuteScript(const std::string& script,
+                              base::OnceCallback<void()> on_complete) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+  v8_runner_->PostTask(FROM_HERE,
+                       base::BindOnce(&V8Manager::ExecuteScriptOnThread,
+                                      weak_ptr_factory_.GetWeakPtr(), script,
+                                      std::move(on_complete)));
+}
+
+v8::Isolate* V8Manager::GetIsolate() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return isolate_holder_ ? isolate_holder_->isolate() : nullptr;
+}
+
+v8::Local<v8::Context> V8Manager::GetContext() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return context_holder_->context();
+}
+
+void V8Manager::ConstructIsolateOnThread() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (isolate_holder_ && context_holder_)
+    return;
+
+  std::unique_ptr<v8::Isolate::CreateParams> params =
+      gin::IsolateHolder::getDefaultIsolateParams();
+  isolate_holder_ = std::make_unique<gin::IsolateHolder>(
+      v8_runner_, gin::IsolateHolder::kSingleThread,
+      gin::IsolateHolder::IsolateType::kUtility, std::move(params));
+}
+
+void V8Manager::AddV8BindingsOnThread() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(isolate_holder_) << "V8 has not been started, cannot bind.";
+
+  // Enter isolate scope.
+  v8::Isolate::Scope isolate_scope(isolate_holder_->isolate());
+
+  // Creates and enters stack-allocated handle scope.
+  // All the Local handles (Local<>) in this function will belong to this
+  // HandleScope and will be garbage collected when it goes out of scope in this
+  // C++ function.
+  v8::HandleScope handle_scope(isolate_holder_->isolate());
+
+  // Create a template for the global object where we set the
+  // built-in global functions.
+  v8::Local<v8::ObjectTemplate> global_template =
+      v8::ObjectTemplate::New(isolate_holder_->isolate());
+
+  // Create a template for the global "chrome" object.
+  v8::Local<v8::ObjectTemplate> chrome_template =
+      v8::ObjectTemplate::New(isolate_holder_->isolate());
+  global_template->Set(isolate_holder_->isolate(), "chrome", chrome_template);
+
+  // Add automation bindings if needed.
+  if (automation_bindings_) {
+    v8::Local<v8::ObjectTemplate> automation_template =
+        v8::ObjectTemplate::New(isolate_holder_->isolate());
+    automation_bindings_->AddRoutesToTemplate(&automation_template);
+    chrome_template->Set(isolate_holder_->isolate(), "automation",
+                         automation_template);
+  }
+  // TODO(crbug.com/1355633): Add other API bindings to the global template.
+
+  // Use static bindings for console functions for initial development.
+  // Note that "console" seems to be protected in v8 so we have to make
+  // our own, "atpconsole".
+  // TODO(crbug.com/1355633): Use blink::mojom::DevToolsAgent interface to
+  // attach to Chrome devtools and remove these temporary bindings.
+  v8::Local<v8::ObjectTemplate> console_template =
+      v8::ObjectTemplate::New(isolate_holder_->isolate());
+  console_template->Set(
+      isolate_holder_->isolate(), "log",
+      gin::CreateFunctionTemplate(isolate_holder_->isolate(),
+                                  base::BindRepeating(&ConsoleLog)));
+  console_template->Set(
+      isolate_holder_->isolate(), "warn",
+      gin::CreateFunctionTemplate(isolate_holder_->isolate(),
+                                  base::BindRepeating(&ConsoleWarn)));
+  console_template->Set(
+      isolate_holder_->isolate(), "error",
+      gin::CreateFunctionTemplate(isolate_holder_->isolate(),
+                                  base::BindRepeating(&ConsoleError)));
+  global_template->Set(isolate_holder_->isolate(), "atpconsole",
+                       console_template);
+
+  // Add the global template to the current context.
+  v8::Local<v8::Context> context = v8::Context::New(
+      isolate_holder_->isolate(), /*extensions=*/nullptr, global_template);
+  context_holder_ =
+      std::make_unique<gin::ContextHolder>(isolate_holder_->isolate());
+  context_holder_->SetContext(context);
+
+  // TODO(crbug.com/1355633): At this point we could load in API Javascript
+  // using ExecuteScript.
+}
+
+void V8Manager::BindAutomationOnThread(
+    base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Construct the AutomationInternalBindings and its routes.
+  automation_bindings_ = std::make_unique<AutomationInternalBindings>(
+      weak_ptr_factory_.GetWeakPtr(), at_controller, main_runner_);
+}
+
+void V8Manager::ExecuteScriptOnThread(const std::string& script,
+                                      base::OnceCallback<void()> on_complete) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Enter isolate scope.
+  v8::Isolate::Scope isolate_scope(isolate_holder_->isolate());
+
+  // Creates and enters stack-allocated handle scope.
+  // All the Local handles (Local<>) in this function will belong to this
+  // HandleScope and will be garbage collected when it goes out of scope in this
+  // C++ function.
+  v8::HandleScope handle_scope(isolate_holder_->isolate());
+
+  // Enter the context for compiling and running the hello world script.
+  v8::Context::Scope context_scope(context_holder_->context());
+  {
+    const char* code_c = script.c_str();
+    v8::Local<v8::String> source =
+        v8::String::NewFromUtf8(isolate_holder_->isolate(), code_c)
+            .ToLocalChecked();
+
+    // Compile the source code.
+    v8::Local<v8::Script> compiled =
+        v8::Script::Compile(context_holder_->context(), source)
+            .ToLocalChecked();
+
+    // Run the script.
+    compiled->Run(context_holder_->context()).ToLocalChecked();
+
+    std::move(on_complete).Run();
+  }
+}
+
+}  // namespace ax
diff --git a/services/accessibility/features/v8_manager.h b/services/accessibility/features/v8_manager.h
new file mode 100644
index 0000000..e58e4be
--- /dev/null
+++ b/services/accessibility/features/v8_manager.h
@@ -0,0 +1,109 @@
+// 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 SERVICES_ACCESSIBILITY_FEATURES_V8_MANAGER_H_
+#define SERVICES_ACCESSIBILITY_FEATURES_V8_MANAGER_H_
+
+#include <memory>
+
+#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/task/sequenced_task_runner_helpers.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/thread_annotations.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-local-handle.h"
+
+namespace v8 {
+class Isolate;
+}  // namespace v8
+
+namespace gin {
+class ContextHolder;
+class IsolateHolder;
+}  // namespace gin
+
+namespace ax {
+class AutomationInternalBindings;
+class AssistiveTechnologyControllerImpl;
+
+// A V8Manager owns a V8 isolate within the Accessibility Service, and manages
+// the bindings that belong to that isolate, as well as loading the Javascript
+// that will run in that isolate.
+// V8Manager may be created on any service thread but must be destroyed
+// on the V8 thread created in V8Manager::Create so that the V8 context and
+// isolate are only accessed from that thread.
+// There may be one V8Manager per Assistive Technology feature or features
+// may share V8Managers.
+class V8Manager : public base::RefCountedDeleteOnSequence<V8Manager> {
+ public:
+  // Initializes V8 for the service. May be called from the main thread.
+  static void InitializeV8();
+
+  // Creates a new V8Manager with its own isolate and context.
+  static scoped_refptr<V8Manager> Create();
+
+  V8Manager(const V8Manager&) = delete;
+  V8Manager& operator=(const V8Manager&) = delete;
+
+  // Called from main service thread.
+  // All of the APIs should be installed before adding V8 bindings.
+  void InstallAutomation(
+      base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller);
+  void AddV8Bindings();
+  void ExecuteScript(const std::string& script,
+                     base::OnceCallback<void()> on_complete);
+
+  // Called from V8 thread.
+  v8::Isolate* GetIsolate();
+  v8::Local<v8::Context> GetContext();
+
+ private:
+  // Allows RefCountedDeleteOnSequence able access to the destructor.
+  friend class base::RefCountedDeleteOnSequence<V8Manager>;
+  friend class base::DeleteHelper<V8Manager>;
+
+  explicit V8Manager(scoped_refptr<base::SingleThreadTaskRunner> v8_runner,
+                     scoped_refptr<base::SequencedTaskRunner> main_runner);
+  ~V8Manager();
+
+  // Methods called from V8 thread.
+  void ConstructIsolateOnThread();
+  void AddV8BindingsOnThread();
+  void BindAutomationOnThread(
+      base::WeakPtr<AssistiveTechnologyControllerImpl> at_controller);
+  void ExecuteScriptOnThread(const std::string& script,
+                             base::OnceCallback<void()> on_complete);
+
+  // Thread runner for all things V8.
+  scoped_refptr<base::SingleThreadTaskRunner> v8_runner_;
+
+  // Thread runner for communicating with object which constructed this
+  // class using V8Manager::Create. This may be the main service thread
+  // but that is not required.
+  scoped_refptr<base::SequencedTaskRunner> main_runner_;
+
+  // Bindings wrappers for V8 APIs.
+  // TODO(crbug.com/1355633): Add more APIs including TTS, SST, etc.
+  std::unique_ptr<AutomationInternalBindings> automation_bindings_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Holders for isolate and context.
+  // These may only be accessed from the v8_runner_ thread.
+  std::unique_ptr<gin::IsolateHolder> isolate_holder_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+  std::unique_ptr<gin::ContextHolder> context_holder_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Used to check that the correct thread is used for V8 work and main
+  // service thread communication.
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  base::WeakPtrFactory<V8Manager> weak_ptr_factory_{this};
+};
+}  // namespace ax
+#endif  // SERVICES_ACCESSIBILITY_FEATURES_V8_MANAGER_H_
diff --git a/services/accessibility/features/v8_manager_unittest.cc b/services/accessibility/features/v8_manager_unittest.cc
new file mode 100644
index 0000000..d2b9240
--- /dev/null
+++ b/services/accessibility/features/v8_manager_unittest.cc
@@ -0,0 +1,42 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/accessibility/features/v8_manager.h"
+
+#include "base/test/task_environment.h"
+#include "services/accessibility/public/mojom/accessibility_service.mojom-shared.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ax {
+
+class V8ManagerTest : public testing::Test {
+ public:
+  V8ManagerTest() = default;
+  V8ManagerTest(const V8ManagerTest&) = delete;
+  V8ManagerTest& operator=(const V8ManagerTest&) = delete;
+  ~V8ManagerTest() override = default;
+
+  void SetUp() override { V8Manager::InitializeV8(); }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+};
+
+TEST_F(V8ManagerTest, ExecutesSimpleScript) {
+  scoped_refptr<V8Manager> manager = V8Manager::Create();
+  manager->AddV8Bindings();
+  base::RunLoop script_waiter;
+  // Test that this script compiles and runs. That indicates that
+  // the atpconsole.log binding was added and that JS works in general.
+  manager->ExecuteScript(R"JS(
+    const d = 22;
+    var m = 1;
+    let y = 1973;
+    atpconsole.log('Green is the loneliest color');
+  )JS",
+                         script_waiter.QuitClosure());
+  script_waiter.Run();
+}
+
+}  // namespace ax
diff --git a/services/device/compute_pressure/pressure_test_support.cc b/services/device/compute_pressure/pressure_test_support.cc
index c9a344d..c95c449 100644
--- a/services/device/compute_pressure/pressure_test_support.cc
+++ b/services/device/compute_pressure/pressure_test_support.cc
@@ -4,8 +4,6 @@
 
 #include "services/device/compute_pressure/pressure_test_support.h"
 
-#include <ostream>
-
 #include "base/location.h"
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
@@ -14,15 +12,6 @@
 
 namespace device {
 
-bool operator==(const PressureSample& lhs, const PressureSample& rhs) noexcept {
-  return lhs.cpu_utilization == rhs.cpu_utilization;
-}
-
-std::ostream& operator<<(std::ostream& os, const PressureSample& sample) {
-  os << "[utilization: " << sample.cpu_utilization << "]";
-  return os;
-}
-
 constexpr PressureSample FakeCpuProbe::kInitialSample;
 
 FakeCpuProbe::FakeCpuProbe() : last_sample_(kInitialSample) {
diff --git a/services/device/compute_pressure/pressure_test_support.h b/services/device/compute_pressure/pressure_test_support.h
index bdddd28f..18cfd69 100644
--- a/services/device/compute_pressure/pressure_test_support.h
+++ b/services/device/compute_pressure/pressure_test_support.h
@@ -5,8 +5,6 @@
 #ifndef SERVICES_DEVICE_COMPUTE_PRESSURE_PRESSURE_TEST_SUPPORT_H_
 #define SERVICES_DEVICE_COMPUTE_PRESSURE_PRESSURE_TEST_SUPPORT_H_
 
-#include <ostream>
-
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
@@ -32,7 +30,7 @@
   void SetLastSample(PressureSample sample);
 
  private:
-  // Bound to the sequence for State() and LastSample().
+  // Bound to the sequence for Update() and LastSample().
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::Lock lock_;
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index 01e0d03..0303be9 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -92,6 +92,8 @@
     "network_quality_tracker.h",
     "network_switches.cc",
     "network_switches.h",
+    "no_vary_search_header_parser.cc",
+    "no_vary_search_header_parser.h",
     "not_implemented_url_loader_factory.cc",
     "not_implemented_url_loader_factory.h",
     "origin_agent_cluster_parser.cc",
@@ -490,6 +492,7 @@
     "network_quality_tracker_unittest.cc",
     "optional_trust_token_params_unittest.cc",
     "origin_agent_cluster_parser_unittest.cc",
+    "parsed_headers_unittest.cc",
     "proxy_config_mojom_traits_unittest.cc",
     "schemeful_site_mojom_traits_unittest.cc",
     "simple_url_loader_unittest.cc",
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 4bd67f0..df94c44 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -336,4 +336,8 @@
              "AccessControlAllowMethodsInCORSPreflightSpecConformant",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kPrefetchNoVarySearch,
+             "PrefetchNoVarySearch",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 }  // namespace network::features
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 0b32ee0..a15eea0 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -107,6 +107,15 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 BASE_DECLARE_FEATURE(kAccessControlAllowMethodsInCORSPreflightSpecConformant);
 
+// If enabled, then navigation requests should check the match responses in the
+// prefetch cache by using the No-Vary-Search rules if No-Vary-Search header
+// is specified in prefetched responses.
+// Feature Meta bug: crbug.com/1378072.
+// No-Vary-Search explainer:
+//   https://github.com/WICG/nav-speculation/blob/main/no-vary-search.md
+COMPONENT_EXPORT(NETWORK_CPP)
+BASE_DECLARE_FEATURE(kPrefetchNoVarySearch);
+
 }  // namespace features
 }  // namespace network
 
diff --git a/services/network/public/cpp/first_party_sets_mojom_traits.cc b/services/network/public/cpp/first_party_sets_mojom_traits.cc
index 41b73570..a714fd6b 100644
--- a/services/network/public/cpp/first_party_sets_mojom_traits.cc
+++ b/services/network/public/cpp/first_party_sets_mojom_traits.cc
@@ -156,12 +156,16 @@
   if (!sets.ReadAliases(&aliases))
     return false;
 
+  base::flat_map<net::SchemefulSite, net::FirstPartySetEntry> manual_entries;
+  if (!sets.ReadManualEntries(&manual_entries))
+    return false;
+
   net::FirstPartySetsContextConfig manual_config;
   if (!sets.ReadManualConfig(&manual_config))
     return false;
 
-  *out_sets =
-      net::GlobalFirstPartySets(entries, aliases, std::move(manual_config));
+  *out_sets = net::GlobalFirstPartySets(entries, aliases, manual_entries,
+                                        std::move(manual_config));
 
   return true;
 }
diff --git a/services/network/public/cpp/first_party_sets_mojom_traits.h b/services/network/public/cpp/first_party_sets_mojom_traits.h
index 34e3843..059cc0f 100644
--- a/services/network/public/cpp/first_party_sets_mojom_traits.h
+++ b/services/network/public/cpp/first_party_sets_mojom_traits.h
@@ -120,6 +120,11 @@
     return sets.aliases();
   }
 
+  static const base::flat_map<net::SchemefulSite, net::FirstPartySetEntry>&
+  manual_entries(const net::GlobalFirstPartySets& sets) {
+    return sets.manual_sets();
+  }
+
   static const net::FirstPartySetsContextConfig& manual_config(
       const net::GlobalFirstPartySets& sets) {
     return sets.manual_config();
diff --git a/services/network/public/cpp/first_party_sets_mojom_traits_unittest.cc b/services/network/public/cpp/first_party_sets_mojom_traits_unittest.cc
index 2aabc297..02a1a6e1 100644
--- a/services/network/public/cpp/first_party_sets_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/first_party_sets_mojom_traits_unittest.cc
@@ -125,9 +125,7 @@
   net::SchemefulSite b_cctld(GURL("https://b.cctld"));
   net::SchemefulSite c(GURL("https://c.test"));
 
-  net::FirstPartySetsContextConfig manual_config({{c, absl::nullopt}});
-
-  const net::GlobalFirstPartySets original(
+  net::GlobalFirstPartySets original(
       /*entries=*/
       {
           {a,
@@ -136,7 +134,11 @@
           {c,
            net::FirstPartySetEntry(a, net::SiteType::kService, absl::nullopt)},
       },
-      /*aliases=*/{{b_cctld, b}}, manual_config.Clone());
+      /*aliases=*/{{b_cctld, b}});
+
+  original.ApplyManuallySpecifiedSet(
+      {{a, net::FirstPartySetEntry(a, net::SiteType::kPrimary, absl::nullopt)},
+       {b, net::FirstPartySetEntry(a, net::SiteType::kAssociated, 0)}});
 
   net::GlobalFirstPartySets round_tripped;
 
diff --git a/services/network/public/cpp/no_vary_search_header_parser.cc b/services/network/public/cpp/no_vary_search_header_parser.cc
new file mode 100644
index 0000000..12b47f7
--- /dev/null
+++ b/services/network/public/cpp/no_vary_search_header_parser.cc
@@ -0,0 +1,36 @@
+// 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 "services/network/public/cpp/no_vary_search_header_parser.h"
+
+#include "net/http/http_no_vary_search_data.h"
+
+namespace network {
+
+mojom::NoVarySearchPtr ParseNoVarySearch(
+    const net::HttpResponseHeaders& headers) {
+  mojom::NoVarySearchPtr no_vary_search;
+  // See No-Vary-Search header structure at
+  // https://github.com/WICG/nav-speculation/blob/main/no-vary-search.md#the-header
+  const auto no_vary_search_data =
+      net::HttpNoVarySearchData::ParseFromHeaders(headers);
+  if (!no_vary_search_data.has_value())
+    return no_vary_search;
+
+  no_vary_search = network::mojom::NoVarySearch::New();
+  no_vary_search->vary_on_key_order = no_vary_search_data->vary_on_key_order();
+  if (no_vary_search_data->vary_by_default()) {
+    no_vary_search->search_variance =
+        mojom::SearchParamsVariance::NewNoVaryParams(std::vector<std::string>(
+            no_vary_search_data->no_vary_params().begin(),
+            no_vary_search_data->no_vary_params().end()));
+    return no_vary_search;
+  }
+  no_vary_search->search_variance = mojom::SearchParamsVariance::NewVaryParams(
+      std::vector<std::string>(no_vary_search_data->vary_params().begin(),
+                               no_vary_search_data->vary_params().end()));
+  return no_vary_search;
+}
+
+}  // namespace network
diff --git a/services/network/public/cpp/no_vary_search_header_parser.h b/services/network/public/cpp/no_vary_search_header_parser.h
new file mode 100644
index 0000000..dc51b57
--- /dev/null
+++ b/services/network/public/cpp/no_vary_search_header_parser.h
@@ -0,0 +1,20 @@
+// 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 SERVICES_NETWORK_PUBLIC_CPP_NO_VARY_SEARCH_HEADER_PARSER_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_NO_VARY_SEARCH_HEADER_PARSER_H_
+
+#include "base/component_export.h"
+#include "net/http/http_response_headers.h"
+#include "services/network/public/mojom/no_vary_search.mojom.h"
+
+namespace network {
+
+COMPONENT_EXPORT(NETWORK_CPP)
+mojom::NoVarySearchPtr ParseNoVarySearch(
+    const net::HttpResponseHeaders& headers);
+
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_NO_VARY_SEARCH_HEADER_PARSER_H_
diff --git a/services/network/public/cpp/parsed_headers.cc b/services/network/public/cpp/parsed_headers.cc
index 0c0bdae..f1f24c7 100644
--- a/services/network/public/cpp/parsed_headers.cc
+++ b/services/network/public/cpp/parsed_headers.cc
@@ -16,6 +16,7 @@
 #include "services/network/public/cpp/cross_origin_opener_policy_parser.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/link_header_parser.h"
+#include "services/network/public/cpp/no_vary_search_header_parser.h"
 #include "services/network/public/cpp/origin_agent_cluster_parser.h"
 #include "services/network/public/cpp/supports_loading_mode/supports_loading_mode_parser.h"
 #include "services/network/public/cpp/timing_allow_origin_parser.h"
@@ -99,6 +100,10 @@
           ParseContentLanguages(content_language);
     }
   }
+
+  if (base::FeatureList::IsEnabled(network::features::kPrefetchNoVarySearch))
+    parsed_headers->no_vary_search = ParseNoVarySearch(*headers);
+
   return parsed_headers;
 }
 
diff --git a/services/network/public/cpp/parsed_headers_unittest.cc b/services/network/public/cpp/parsed_headers_unittest.cc
new file mode 100644
index 0000000..9367be2
--- /dev/null
+++ b/services/network/public/cpp/parsed_headers_unittest.cc
@@ -0,0 +1,159 @@
+// 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 "services/network/public/cpp/parsed_headers.h"
+
+#include <string>
+#include <tuple>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/strings/string_piece.h"
+#include "base/test/scoped_feature_list.h"
+#include "net/base/features.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
+#include "services/network/public/cpp/features.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace network {
+namespace {
+
+void TestNVSDefaultURLVariance(const base::StringPiece headers) {
+  std::string raw_headers = net::HttpUtil::AssembleRawHeaders(headers);
+  auto parsed = base::MakeRefCounted<net::HttpResponseHeaders>(raw_headers);
+  const auto parsed_headers =
+      network::PopulateParsedHeaders(parsed.get(), GURL("https://a.com"));
+
+  EXPECT_TRUE(parsed_headers);
+  EXPECT_FALSE(parsed_headers->no_vary_search);
+}
+
+class NoVarySearchPrefetchDisabledTest
+    : public ::testing::Test,
+      public ::testing::WithParamInterface<base::StringPiece> {};
+
+TEST_P(NoVarySearchPrefetchDisabledTest, ParsingNVSReturnsDefaultURLVariance) {
+  TestNVSDefaultURLVariance(GetParam());
+}
+
+constexpr base::StringPiece no_vary_search_prefetch_disabled_data[] = {
+    // No No-Vary-Search header.
+    "HTTP/1.1 200 OK\r\n"
+    "Set-Cookie: a\r\n"
+    "Set-Cookie: b\r\n\r\n",
+    // No-Vary-Search header present.
+    "HTTP/1.1 200 OK\r\n"
+    R"(No-Vary-Search: params=("a"))"
+    "\r\n\r\n",
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    NoVarySearchPrefetchDisabledTest,
+    NoVarySearchPrefetchDisabledTest,
+    testing::ValuesIn(no_vary_search_prefetch_disabled_data));
+
+TEST(NoVarySearchPrefetchEnabledTest, ParsingNVSReturnsDefaultURLVariance) {
+  base::test::ScopedFeatureList feature_list(
+      network::features::kPrefetchNoVarySearch);
+  const base::StringPiece& headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Set-Cookie: a\r\n"
+      "Set-Cookie: b\r\n\r\n";
+  TestNVSDefaultURLVariance(headers);
+}
+
+struct NoVarySearchTestData {
+  const char* raw_headers;
+  const std::vector<std::string> expected_no_vary_params;
+  const std::vector<std::string> expected_vary_params;
+  const bool expected_vary_on_key_order;
+  const bool expected_vary_by_default;
+};
+
+class NoVarySearchPrefetchEnabledTest
+    : public ::testing::Test,
+      public ::testing::WithParamInterface<NoVarySearchTestData> {
+ public:
+  NoVarySearchPrefetchEnabledTest() {
+    feature_list_.InitAndEnableFeature(
+        network::features::kPrefetchNoVarySearch);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_P(NoVarySearchPrefetchEnabledTest, ParsingSuccess) {
+  const auto& test_data = GetParam();
+  std::string headers =
+      net::HttpUtil::AssembleRawHeaders(test_data.raw_headers);
+
+  auto parsed = base::MakeRefCounted<net::HttpResponseHeaders>(headers);
+  const auto parsed_headers =
+      network::PopulateParsedHeaders(parsed.get(), GURL("https://a.com"));
+
+  EXPECT_TRUE(parsed_headers);
+  ASSERT_TRUE(parsed_headers->no_vary_search);
+  ASSERT_TRUE(parsed_headers->no_vary_search->search_variance);
+  if (test_data.expected_vary_by_default) {
+    EXPECT_THAT(
+        parsed_headers->no_vary_search->search_variance->get_no_vary_params(),
+        test_data.expected_no_vary_params);
+  } else {
+    EXPECT_THAT(
+        parsed_headers->no_vary_search->search_variance->get_vary_params(),
+        test_data.expected_vary_params);
+  }
+  EXPECT_EQ(parsed_headers->no_vary_search->vary_on_key_order,
+            test_data.expected_vary_on_key_order);
+}
+
+NoVarySearchTestData response_headers_tests[] = {
+    // params set to a list of strings with one element.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params=("a"))"
+        "\r\n\r\n",                       // raw_headers
+        std::vector<std::string>({"a"}),  // expected_no_vary_params
+        {},                               // expected_vary_params
+        true,                             // expected_vary_on_key_order
+        true,                             // expected_vary_by_default
+    },
+    // params set to true.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        "No-Vary-Search: params\r\n\r\n",  // raw_headers
+        {},                                // expected_no_vary_params
+        {},                                // expected_vary_params
+        true,                              // expected_vary_on_key_order
+        false,                             // expected_vary_by_default
+    },
+    // Vary on one search param.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        "No-Vary-Search: params\r\n"
+        R"(No-Vary-Search: except=("a"))"
+        "\r\n\r\n",                       // raw_headers
+        {},                               // expected_no_vary_params
+        std::vector<std::string>({"a"}),  // expected_vary_params
+        true,                             // expected_vary_on_key_order
+        false,                            // expected_vary_by_default
+    },
+    // Don't vary on search params order.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        "No-Vary-Search: key-order\r\n\r\n",  // raw_headers
+        {},                                   // expected_no_vary_params
+        {},                                   // expected_vary_params
+        false,                                // expected_vary_on_key_order
+        true,                                 // expected_vary_by_default
+    },
+};
+
+INSTANTIATE_TEST_SUITE_P(NoVarySearchPrefetchEnabledTest,
+                         NoVarySearchPrefetchEnabledTest,
+                         testing::ValuesIn(response_headers_tests));
+}  // namespace
+}  // namespace network
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
index 6f57813..b07e36c 100644
--- a/services/network/public/mojom/BUILD.gn
+++ b/services/network/public/mojom/BUILD.gn
@@ -352,6 +352,7 @@
     "network_change_manager.mojom",
     "network_interface.mojom",
     "network_types.mojom",
+    "no_vary_search.mojom",
     "parsed_headers.mojom",
     "referrer_policy.mojom",
     "request_priority.mojom",
@@ -938,6 +939,7 @@
     ":mojom_schemeful_site",
     "//components/content_settings/core/common:mojo_bindings",
     "//mojo/public/mojom/base",
+    "//sandbox/policy/mojom",
     "//url/mojom:url_mojom_gurl",
     "//url/mojom:url_mojom_origin",
   ]
diff --git a/services/network/public/mojom/cookie_manager.mojom b/services/network/public/mojom/cookie_manager.mojom
index 3b851b4..65c71af 100644
--- a/services/network/public/mojom/cookie_manager.mojom
+++ b/services/network/public/mojom/cookie_manager.mojom
@@ -6,6 +6,7 @@
 
 import "components/content_settings/core/common/content_settings.mojom";
 import "mojo/public/mojom/base/time.mojom";
+import "sandbox/policy/mojom/context.mojom";
 import "services/network/public/mojom/cookie_partition_key.mojom";
 import "services/network/public/mojom/first_party_sets.mojom";
 import "services/network/public/mojom/schemeful_site.mojom";
@@ -332,6 +333,11 @@
   OnCookieChange(CookieChangeInfo change);
 };
 
+// CookieManager is a privileged interface that should only be used in trusted
+// processes.
+//
+// Untrusted processes like renderers should use RestrictedCookieManager.
+[RequireContext=sandbox.mojom.Context.kBrowser]
 interface CookieManager {
   // TODO(rdsmith): Worthwhile specifying a sort order for the getters?
 
@@ -426,6 +432,7 @@
   // Clone the interface for use somewhere else.  After this call,
   // requests to the same implementation may be posted to the other side
   // of the pipe new_interface was configured on.
+  [AllowedContext=sandbox.mojom.Context.kBrowser]
   CloneInterface(pending_receiver<CookieManager> new_interface);
 
   // Flush the backing store (if any) to disk.
diff --git a/services/network/public/mojom/first_party_sets.mojom b/services/network/public/mojom/first_party_sets.mojom
index 3856b6c4..cd0b73e 100644
--- a/services/network/public/mojom/first_party_sets.mojom
+++ b/services/network/public/mojom/first_party_sets.mojom
@@ -81,12 +81,16 @@
 // This struct must match the class fields defined in
 // //net/first_party_sets/global_first_party_sets.h.
 struct GlobalFirstPartySets {
-  // The mapping from site to FPS entry.
+  // The mapping from site to FPS entry from public sets.
   map<SchemefulSite, FirstPartySetEntry> sets;
 
-  // The mapping from site alias to canonical site.
+  // The mapping from site alias to canonical site from public sets.
   map<SchemefulSite, SchemefulSite> aliases;
 
+  // The mapping of site to FPS entry representing the parsed manually-supplied
+  // set, without taking the underlying public sets into account.
+  map<SchemefulSite, FirstPartySetEntry> manual_entries;
+
   // The config induced by the manually-supplied set.
   FirstPartySetsContextConfig manual_config;
 };
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index d57c6f1..a2f605c 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -874,6 +874,7 @@
   //
   // The CookieManager must only be passed to trusted processes. Whenever
   // possible, a RestrictedCookieManager should be handed out instead.
+  [AllowedContext=sandbox.mojom.Context.kBrowser]
   GetCookieManager(pending_receiver<CookieManager> cookie_manager);
 
   // Gets a RestrictedCookieManager scoped to a given origin, and applying
diff --git a/services/network/public/mojom/no_vary_search.mojom b/services/network/public/mojom/no_vary_search.mojom
new file mode 100644
index 0000000..fcf868d
--- /dev/null
+++ b/services/network/public/mojom/no_vary_search.mojom
@@ -0,0 +1,35 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module network.mojom;
+
+// Describes the variance of URL query search params for cache matching
+// purposes.
+// For more information, see:
+// https://wicg.github.io/nav-speculation/no-vary-search.html#model
+union SearchParamsVariance {
+  // Query parameters which should be ignored when comparing a request
+  // to a cached response. This is empty if all query parameters are
+  // significant.
+  array<string> no_vary_params;
+  // Query parameters which should be respected when comparing a request
+  // to a cached response. This is empty if all query parameters should be
+  // ignored.
+  array<string> vary_params;
+};
+
+// The parsed value of the No-Vary-Search header.
+// For more information, see:
+// https://wicg.github.io/nav-speculation/no-vary-search.html#model
+struct NoVarySearch {
+  // Describes the variance of URL query search params for cache matching
+  // purposes.
+  // For more information, see:
+  // https://wicg.github.io/nav-speculation/no-vary-search.html#model
+  SearchParamsVariance search_variance;
+
+  // If false, parameters with distinct keys can be reordered in order to find a
+  // cache hit. Defaults to true.
+  bool vary_on_key_order;
+};
diff --git a/services/network/public/mojom/parsed_headers.mojom b/services/network/public/mojom/parsed_headers.mojom
index d72db40..d887c9a3 100644
--- a/services/network/public/mojom/parsed_headers.mojom
+++ b/services/network/public/mojom/parsed_headers.mojom
@@ -8,6 +8,7 @@
 import "services/network/public/mojom/cross_origin_embedder_policy.mojom";
 import "services/network/public/mojom/cross_origin_opener_policy.mojom";
 import "services/network/public/mojom/link_header.mojom";
+import "services/network/public/mojom/no_vary_search.mojom";
 import "services/network/public/mojom/supports_loading_mode.mojom";
 import "services/network/public/mojom/timing_allow_origin.mojom";
 import "services/network/public/mojom/variants_header.mojom";
@@ -111,4 +112,10 @@
 
   // The parsed value of the Content-Language header.
   array<string>? content_language;
+
+  // The parsed value of the No-Vary-Search header. Null if not present
+  // or if No-Vary-Search header represents the default URL search variance.
+  // For more information, see:
+  // https://wicg.github.io/nav-speculation/no-vary-search.html#model
+  NoVarySearch? no_vary_search;
 };
diff --git a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
index 5776b0b..9051e6a 100644
--- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
+++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
@@ -47,6 +47,21 @@
       external_begin_frame_controller;
 };
 
+// Response from StopFrameCounting that contains counted frames for all frame
+// sinks during the tracked time window.
+struct FrameCountingData {
+  array<FrameCountingPerSinkData> per_sink_data;
+};
+
+// Container for collected data for a given frame sink.
+struct FrameCountingPerSinkData {
+  CompositorFrameSinkType type;
+  bool is_root;
+
+  // Collected number of presented frames for the specified bucket size.
+  array<uint16> presented_frames;
+};
+
 // The FrameSinkManager interface is a privileged interface that allows the
 // frame sink manager host (browser or window server) to create
 // CompositorFrameSinks. Clients acquire a CompositorFrameSink connection
@@ -173,6 +188,13 @@
   // This allows dynamic manipulation of the viz debug options stored in
   // |debug_settings| (show_overdraw_feedback, etc.).
   UpdateDebugRendererSettings(DebugRendererSettings debug_settings);
+
+  // Starts frame counting per frame sink on the Viz thread.
+  StartFrameCountingForTest(mojo_base.mojom.TimeDelta bucket_size);
+
+  // Stops frame counting on the Viz thread and returns all records to the
+  // caller.
+  StopFrameCountingForTest() => (FrameCountingData data);
 };
 
 // The FrameSinkManagerClient interface is implemented by the Display
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 19a9e38..970277ff 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -9478,7 +9478,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
@@ -28364,7 +28364,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
@@ -28826,7 +28826,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
@@ -28892,7 +28892,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
@@ -28954,7 +28954,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
@@ -36205,7 +36205,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "machine_type": "e2-standard-8",
+              "machine_type": "e2-standard-8|n2-standard-8",
               "os": "Ubuntu-18.04",
               "pool": "chromium.tests.avd"
             }
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 4ea62ebc..46c13ea 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5875,9 +5875,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_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -5889,8 +5889,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -6041,9 +6041,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6055,8 +6055,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -6192,9 +6192,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6206,8 +6206,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 427c3e91..eb0d80ce 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -88083,9 +88083,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_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88097,8 +88097,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -88219,9 +88219,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88233,8 +88233,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -88345,9 +88345,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88359,8 +88359,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -89700,9 +89700,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_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -89713,8 +89713,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -89866,9 +89866,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -89879,8 +89879,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -90017,9 +90017,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -90030,8 +90030,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -91552,9 +91552,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_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91565,8 +91565,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -91718,9 +91718,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91731,8 +91731,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -91869,9 +91869,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91882,8 +91882,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -92681,9 +92681,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_v110.0.5422.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -92694,8 +92694,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -95378,6 +95378,40 @@
           "shards": 12
         },
         "test_id_prefix": "ninja://:wpt_tests_isolate_content_shell/"
+      },
+      {
+        "args": [
+          "--child-processes=8",
+          "--log-wptreport",
+          "--xvfb",
+          "--flag-specific",
+          "disable-site-isolation-trials"
+        ],
+        "experiment_percentage": 100,
+        "isolate_name": "wpt_tests_isolate_content_shell",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "wpt_tests_suite_not_site_per_process",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test_id_prefix": "ninja://:wpt_tests_isolate_content_shell/"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 4827b72..cbbbf8c 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18562,10 +18562,10 @@
       {
         "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_v110.0.5422.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18577,8 +18577,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -18736,10 +18736,10 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18751,8 +18751,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
@@ -18892,10 +18892,10 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5422.0",
+        "description": "Run with ash-chrome version 110.0.5423.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18907,8 +18907,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5422.0",
-              "revision": "version:110.0.5422.0"
+              "location": "lacros_version_skew_tests_v110.0.5423.0",
+              "revision": "version:110.0.5423.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index dc29cec..8106a52 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -77,7 +77,7 @@
           'shards': 2,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # crbug/1292221
+              'machine_type': 'e2-standard-8|n2-standard-8', # crbug/1292221
             },
           ],
         },
@@ -1381,7 +1381,8 @@
           'shards': 75,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # use 8-core to shorten runtime
+              # use 8-core to shorten runtime
+              'machine_type': 'e2-standard-8|n2-standard-8',
             },
           ],
         },
@@ -1747,7 +1748,8 @@
           'shards': 30,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # use 8-core to shorten runtime
+              # use 8-core to shorten runtime
+              'machine_type': 'e2-standard-8|n2-standard-8',
             },
           ],
         },
@@ -1781,7 +1783,8 @@
           'shards': 75,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # use 8-core to shorten runtime
+              # use 8-core to shorten runtime
+              'machine_type': 'e2-standard-8|n2-standard-8',
             },
           ],
         },
@@ -1885,7 +1888,8 @@
           'shards': 25,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # copying android-nougat-x86-rel
+              # copying android-nougat-x86-rel
+              'machine_type': 'e2-standard-8|n2-standard-8',
             },
           ],
         },
@@ -1928,7 +1932,8 @@
           'shards': 6,
           'dimension_sets': [
             {
-              'machine_type': 'e2-standard-8', # use 8-core to shorten runtime
+              # use 8-core to shorten runtime
+              'machine_type': 'e2-standard-8|n2-standard-8',
             },
           ],
         },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index cd09482..4632c9b4 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -5480,6 +5480,30 @@
         'experiment_percentage': 100,
       },
     },
+
+    'wpt_web_tests_not_site_per_process': {
+      'wpt_tests_suite_not_site_per_process': {
+        'args': [
+          '--child-processes=8',
+          '--log-wptreport',
+          '--xvfb',
+          '--flag-specific',
+          'disable-site-isolation-trials',
+        ],
+        'merge': {
+          'args': [
+            '--verbose',
+          ],
+          'script': '//third_party/blink/tools/merge_web_test_results.py',
+        },
+        'isolate_name': 'wpt_tests_isolate_content_shell',
+        'results_handler': 'layout tests',
+        'swarming': {
+          'shards': 10,
+        },
+        'experiment_percentage': 100,
+      },
+    },
   },
 
   ##############################################################################
@@ -6393,6 +6417,7 @@
 
     'wpt_web_tests_content_shell_multiple_flags': [
       'wpt_web_tests_content_shell',
+      'wpt_web_tests_not_site_per_process',
       'wpt_web_tests_layout_ng_disabled',
       'wpt_web_tests_highdpi',
     ],
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 2f16d30..0fe0fea 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_v110.0.5422.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5423.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 110.0.5422.0',
+    'description': 'Run with ash-chrome version 110.0.5423.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_v110.0.5422.0',
-          'revision': 'version:110.0.5422.0',
+          'location': 'lacros_version_skew_tests_v110.0.5423.0',
+          'revision': 'version:110.0.5423.0',
         },
       ],
     },
diff --git a/testing/test_env.py b/testing/test_env.py
index b68050f7..9e74ae3 100755
--- a/testing/test_env.py
+++ b/testing/test_env.py
@@ -120,7 +120,6 @@
     if lsan:
       msan_options.append('detect_leaks=1')
     extra_env['MSAN_OPTIONS'] = ' '.join(msan_options)
-    extra_env['LD_LIBRARY_PATH'] = 'instrumented_libraries_prebuilt/lib'
     extra_env['VK_ICD_FILENAMES'] = ''
 
   if tsan:
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index c46e309..879471f 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1806,26 +1806,6 @@
             ]
         }
     ],
-    "BackForwardCacheAppBanner": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "fuchsia",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "BackForwardCacheAppBanner"
-                    ]
-                }
-            ]
-        }
-    ],
     "BackForwardCacheDedicatedWorker": [
         {
             "platforms": [
@@ -3022,15 +3002,14 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20221108",
+                    "name": "Enabled_20221116",
                     "params": {
                         "compile-in-parallel": "true",
                         "compile-strategy": "eager",
                         "default-parser-budget": "10ms",
                         "inline-script-timeout": "5ms",
                         "long-parser-budget": "50ms",
-                        "num-yields-with-default-budget": "2",
-                        "preload-processing-mode": "immediate"
+                        "num-yields-with-default-budget": "2"
                     },
                     "enable_features": [
                         "BatchImageDecoding",
@@ -3040,11 +3019,7 @@
                         "PrecompileInlineScripts",
                         "PrefetchFontLookupTables",
                         "SplitCompositorTask",
-                        "ThreadedPreloadScanner",
                         "TimedHTMLParserBudget"
-                    ],
-                    "disable_features": [
-                        "PretokenizeCSS"
                     ]
                 }
             ]
@@ -3059,15 +3034,14 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20221108",
+                    "name": "Enabled_20221116",
                     "params": {
                         "compile-in-parallel": "true",
                         "compile-strategy": "eager",
-                        "default-parser-budget": "20ms",
+                        "default-parser-budget": "10ms",
                         "inline-script-timeout": "5ms",
                         "long-parser-budget": "500ms",
-                        "num-yields-with-default-budget": "2",
-                        "preload-processing-mode": "immediate",
+                        "num-yields-with-default-budget": "6",
                         "prewarm_cursive": "false",
                         "prewarm_fantasy": "false",
                         "prewarm_fixed": "false",
@@ -3081,12 +3055,10 @@
                         "OptimizeDataUrls",
                         "PrecompileInlineScripts",
                         "PrewarmDefaultFontFamilies",
-                        "ThreadedPreloadScanner",
                         "TimedHTMLParserBudget"
                     ],
                     "disable_features": [
-                        "EstablishGpuChannelAsync",
-                        "PretokenizeCSS"
+                        "EstablishGpuChannelAsync"
                     ]
                 }
             ]
@@ -3097,15 +3069,14 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20221108",
+                    "name": "Enabled_20221116",
                     "params": {
                         "compile-in-parallel": "true",
                         "compile-strategy": "eager",
                         "default-parser-budget": "10ms",
                         "inline-script-timeout": "5ms",
                         "long-parser-budget": "50ms",
-                        "num-yields-with-default-budget": "2",
-                        "preload-processing-mode": "immediate"
+                        "num-yields-with-default-budget": "2"
                     },
                     "enable_features": [
                         "DecodeScriptSourceOffThread",
@@ -3113,11 +3084,7 @@
                         "OptimizeDataUrls",
                         "PrecompileInlineScripts",
                         "PrefetchFontLookupTables",
-                        "ThreadedPreloadScanner",
                         "TimedHTMLParserBudget"
-                    ],
-                    "disable_features": [
-                        "PretokenizeCSS"
                     ]
                 }
             ]
@@ -3352,8 +3319,8 @@
                 {
                     "name": "Enabled",
                     "params": {
-                        "action_chip": "false",
-                        "action_chip_time_ms": "3000",
+                        "action_chip": "true",
+                        "action_chip_time_ms": "6000",
                         "action_chip_with_different_color": "false",
                         "enable_ui": "true",
                         "reader_mode_session_rate_limiting": "false"
@@ -5051,26 +5018,6 @@
             ]
         }
     ],
-    "GoogleLensDesktopRegionSearchPdf": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "fuchsia",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_20220929",
-                    "enable_features": [
-                        "LensEnableRegionSearchOnPdfViewer"
-                    ]
-                }
-            ]
-        }
-    ],
     "GoogleLensDesktopTransparentImagesFix": [
         {
             "platforms": [
@@ -8679,23 +8626,26 @@
             ]
         }
     ],
-    "PermissionChip": [
+    "PermissionConfirmationChip": [
         {
             "platforms": [
                 "chromeos",
                 "chromeos_lacros",
-                "fuchsia",
                 "linux",
                 "mac",
                 "windows"
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20210721",
+                    "name": "RequestChipConfirmationChipNoLockIconOverride",
                     "enable_features": [
+                        "ConfirmationChip",
                         "PermissionChip",
                         "PermissionChipGestureSensitive",
                         "PermissionChipRequestTypeSensitive"
+                    ],
+                    "disable_features": [
+                        "ChipLocationIconOverride"
                     ]
                 }
             ]
@@ -9404,6 +9354,26 @@
             ]
         }
     ],
+    "RecordPermissionExpirationTimestamps": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros",
+                "fuchsia",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "RecordPermissionExpirationTimestamps"
+                    ]
+                }
+            ]
+        }
+    ],
     "ReduceCpuUtilization": [
         {
             "platforms": [
@@ -9721,29 +9691,6 @@
             ]
         }
     ],
-    "SafeBrowsingCsbrrWithToken": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer",
-                "android_webview",
-                "chromeos",
-                "chromeos_lacros",
-                "fuchsia",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "SafeBrowsingCsbrrWithToken"
-                    ]
-                }
-            ]
-        }
-    ],
     "SafeBrowsingDelayedWarnings": [
         {
             "platforms": [
@@ -11199,9 +11146,16 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20221024",
+                    "name": "EnabledMainFrame_20221116",
+                    "params": {
+                        "max-data-to-process": "1",
+                        "pretokenize-main-frame-only": "true",
+                        "scan-main-frame-only": "true"
+                    },
                     "enable_features": [
-                        "ThreadedBodyLoader"
+                        "PretokenizeCSS",
+                        "ThreadedBodyLoader",
+                        "ThreadedPreloadScanner"
                     ]
                 }
             ]
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index b9cebca..be2007a9 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1218,11 +1218,6 @@
              "OriginAgentClusterDefaultWarning",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// TODO(https://crbug.com/1276864): Delete this flag.
-BASE_FEATURE(kBackForwardCacheAppBanner,
-             "BackForwardCacheAppBanner",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 BASE_FEATURE(kSystemColorChooser,
              "SystemColorChooser",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
index d01b149..4b9c1c44 100644
--- a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
+++ b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
@@ -92,8 +92,6 @@
               "requested storage access permission"};
     case WebSchedulerTrackedFeature::kWebNfc:
       return {"WebNfc", "WebNfc"};
-    case WebSchedulerTrackedFeature::kAppBanner:
-      return {"AppBanner", "AppBanner"};
     case WebSchedulerTrackedFeature::kPrinting:
       return {"Printing", "Printing"};
     case WebSchedulerTrackedFeature::kWebDatabase:
@@ -203,7 +201,6 @@
       WebSchedulerTrackedFeature::kWebLocks,
       WebSchedulerTrackedFeature::kRequestedStorageAccessGrant,
       WebSchedulerTrackedFeature::kWebNfc,
-      WebSchedulerTrackedFeature::kAppBanner,
       WebSchedulerTrackedFeature::kPrinting,
       WebSchedulerTrackedFeature::kPictureInPicture,
       WebSchedulerTrackedFeature::kIdleManager,
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 8edebac..ce556a4 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -524,10 +524,6 @@
 // kOriginAgentClusterDefaultEnabled above.)
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kOriginAgentClusterDefaultWarning);
 
-// Allows pages that support App Install Banners to stay eligible for the
-// back/forward cache.
-BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kBackForwardCacheAppBanner);
-
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kSystemColorChooser);
 
 // Disables forced frame updates for web tests. Used by web test runner only.
diff --git a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
index f750742..40eb39b1 100644
--- a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
+++ b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
@@ -99,8 +99,8 @@
 
   kOutstandingNetworkRequestFetch = 40,
   kOutstandingNetworkRequestXHR = 41,
-
-  kAppBanner = 42,
+  // kAppBanner = 42. Removed after support added for back/forward cache.
+  // See https://crbug.com/1276864.
   kPrinting = 43,
   kWebDatabase = 44,
   kPictureInPicture = 45,
diff --git a/third_party/blink/public/web/web_ax_context.h b/third_party/blink/public/web/web_ax_context.h
index 914c481f..01b96de5 100644
--- a/third_party/blink/public/web/web_ax_context.h
+++ b/third_party/blink/public/web/web_ax_context.h
@@ -87,6 +87,9 @@
   // Ensure that a layout and accessibility update will occur soon.
   void ScheduleAXUpdate();
 
+  // If the document is loaded, fire a load complete event.
+  void FireLoadCompleteIfLoaded();
+
  private:
   std::unique_ptr<AXContext> private_;
 };
diff --git a/third_party/blink/renderer/BUILD.gn b/third_party/blink/renderer/BUILD.gn
index 6d140b8..28ad2d01 100644
--- a/third_party/blink/renderer/BUILD.gn
+++ b/third_party/blink/renderer/BUILD.gn
@@ -112,10 +112,6 @@
       "-add-plugin",
       "-Xclang",
       "blink-gc-plugin",
-      "-Xclang",
-      "-plugin-arg-blink-gc-plugin",
-      "-Xclang",
-      "fix-bugs-of-is-considered-abstract",
     ]
 
     # Add arguments for enabled GC plugin options:
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
index c48dcb8..f8aabf4 100644
--- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -138,7 +138,7 @@
                       .CreateLength(conversion_data, value_range_);
   if (LengthPropertyFunctions::SetLength(CssProperty(), builder, length)) {
 #if DCHECK_IS_ON()
-    scoped_refptr<const ComputedStyle> before_style = builder.ToStyle();
+    scoped_refptr<const ComputedStyle> before_style = builder.CloneStyle();
     // Assert that setting the length on ComputedStyle directly is identical to
     // the StyleBuilder code path. This check is useful for catching differences
     // in clamping behavior.
@@ -149,7 +149,7 @@
     StyleBuilder::ApplyProperty(
         GetProperty().GetCSSProperty(), state,
         ScopedCSSValue(*CSSValue::Create(length, zoom), nullptr));
-    scoped_refptr<const ComputedStyle> after_style = builder.ToStyle();
+    scoped_refptr<const ComputedStyle> after_style = builder.CloneStyle();
     DCHECK(
         LengthPropertyFunctions::GetLength(CssProperty(), *after_style, after));
     DCHECK(before.IsSpecified());
diff --git a/third_party/blink/renderer/core/animation/view_timeline.cc b/third_party/blink/renderer/core/animation/view_timeline.cc
index 34c9be6..91d3c043 100644
--- a/third_party/blink/renderer/core/animation/view_timeline.cc
+++ b/third_party/blink/renderer/core/animation/view_timeline.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
 #include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
+#include "third_party/blink/renderer/core/css/cssom/css_unit_values.h"
 #include "third_party/blink/renderer/core/css/resolver/element_resolve_context.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -395,6 +396,22 @@
                         (1 - end_fraction.value_or(1)) * duration.value());
 }
 
+CSSNumericValue* ViewTimeline::startOffset() const {
+  absl::optional<ScrollOffsets> scroll_offsets = GetResolvedScrollOffsets();
+  if (!scroll_offsets)
+    return nullptr;
+
+  return CSSUnitValues::px(scroll_offsets->start);
+}
+
+CSSNumericValue* ViewTimeline::endOffset() const {
+  absl::optional<ScrollOffsets> scroll_offsets = GetResolvedScrollOffsets();
+  if (!scroll_offsets)
+    return nullptr;
+
+  return CSSUnitValues::px(scroll_offsets->end);
+}
+
 void ViewTimeline::Trace(Visitor* visitor) const {
   visitor->Trace(style_dependant_start_inset_);
   visitor->Trace(style_dependant_end_inset_);
diff --git a/third_party/blink/renderer/core/animation/view_timeline.h b/third_party/blink/renderer/core/animation/view_timeline.h
index 1e63d61..1d9d6af 100644
--- a/third_party/blink/renderer/core/animation/view_timeline.h
+++ b/third_party/blink/renderer/core/animation/view_timeline.h
@@ -65,6 +65,10 @@
 
   void Trace(Visitor*) const override;
 
+  CSSNumericValue* startOffset() const;
+
+  CSSNumericValue* endOffset() const;
+
  protected:
   const Inset& GetInset() const { return inset_; }
 
diff --git a/third_party/blink/renderer/core/animation/view_timeline.idl b/third_party/blink/renderer/core/animation/view_timeline.idl
index 4261265..9301a84 100644
--- a/third_party/blink/renderer/core/animation/view_timeline.idl
+++ b/third_party/blink/renderer/core/animation/view_timeline.idl
@@ -11,5 +11,6 @@
 ] interface ViewTimeline : ScrollTimeline {
     [CallWith=Document, RaisesException, MeasureAs=ViewTimelineConstructor] constructor(optional ViewTimelineOptions options = {});
     readonly attribute Element? subject;
-    // TODO(crbug.com/1329159): Add remaining fields as ratified.
+    readonly attribute CSSNumericValue? startOffset;
+    readonly attribute CSSNumericValue? endOffset;
 };
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
index 7f1442c..781c5cd8 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -45,9 +45,10 @@
                                   sizeof(MatchedProperties) * vector.size());
 }
 
-void CachedMatchedProperties::Set(const ComputedStyle& style,
-                                  const ComputedStyle& parent_style,
-                                  const MatchedPropertiesVector& properties) {
+void CachedMatchedProperties::Set(
+    scoped_refptr<const ComputedStyle>&& style,
+    scoped_refptr<const ComputedStyle>&& parent_style,
+    const MatchedPropertiesVector& properties) {
   for (const auto& new_matched_properties : properties) {
     matched_properties.push_back(new_matched_properties.properties);
     matched_properties_types.push_back(new_matched_properties.types_);
@@ -56,8 +57,8 @@
   // Note that we don't cache the original ComputedStyle instance. It may be
   // further modified.  The ComputedStyle in the cache is really just a holder
   // for the substructures and never used as-is.
-  this->computed_style = ComputedStyle::Clone(style);
-  this->parent_computed_style = ComputedStyle::Clone(parent_style);
+  this->computed_style = style;
+  this->parent_computed_style = parent_style;
 }
 
 void CachedMatchedProperties::Clear() {
@@ -164,9 +165,10 @@
   return !(*this == properties);
 }
 
-void MatchedPropertiesCache::Add(const Key& key,
-                                 const ComputedStyle& style,
-                                 const ComputedStyle& parent_style) {
+void MatchedPropertiesCache::Add(
+    const Key& key,
+    scoped_refptr<const ComputedStyle>&& style,
+    scoped_refptr<const ComputedStyle>&& parent_style) {
   DCHECK(key.IsValid());
 
   Member<CachedMatchedProperties>& cache_item =
@@ -177,7 +179,8 @@
   else
     cache_item->Clear();
 
-  cache_item->Set(style, parent_style, key.result_.GetMatchedProperties());
+  cache_item->Set(std::move(style), std::move(parent_style),
+                  key.result_.GetMatchedProperties());
 }
 
 void MatchedPropertiesCache::Clear() {
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
index 895b61c..e18cf96 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -48,11 +48,11 @@
   Vector<UntracedMember<CSSPropertyValueSet>> matched_properties;
   Vector<MatchedProperties::Data> matched_properties_types;
 
-  scoped_refptr<ComputedStyle> computed_style;
-  scoped_refptr<ComputedStyle> parent_computed_style;
+  scoped_refptr<const ComputedStyle> computed_style;
+  scoped_refptr<const ComputedStyle> parent_computed_style;
 
-  void Set(const ComputedStyle&,
-           const ComputedStyle& parent_style,
+  void Set(scoped_refptr<const ComputedStyle>&& style,
+           scoped_refptr<const ComputedStyle>&& parent_style,
            const MatchedPropertiesVector&);
   void Clear();
 
@@ -97,7 +97,9 @@
   };
 
   const CachedMatchedProperties* Find(const Key&, const StyleResolverState&);
-  void Add(const Key&, const ComputedStyle&, const ComputedStyle& parent_style);
+  void Add(const Key&,
+           scoped_refptr<const ComputedStyle>&&,
+           scoped_refptr<const ComputedStyle>&& parent_style);
 
   void Clear();
   void ClearViewportDependent();
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
index 28fede9..78b5aac 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
@@ -60,7 +60,8 @@
   void Add(const TestKey& key,
            const ComputedStyle& style,
            const ComputedStyle& parent_style) {
-    cache_.Add(key.InnerKey(), style, parent_style);
+    cache_.Add(key.InnerKey(), ComputedStyle::Clone(style),
+               ComputedStyle::Clone(parent_style));
   }
 
   const CachedMatchedProperties* Find(const TestKey& key,
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index bcaa7a9..0c8552ec 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1349,7 +1349,7 @@
     ApplyBaseStyleNoCache(element, style_recalc_context, style_request, state,
                           cascade);
     scoped_refptr<const ComputedStyle> style_snapshot =
-        state.StyleBuilder().ToStyle();
+        state.StyleBuilder().CloneStyle();
     DCHECK_EQ(g_null_atom, ComputeBaseComputedStyleDiff(
                                animation_base_computed_style, *style_snapshot));
 #endif
@@ -1708,7 +1708,7 @@
   if (!IsAnimationStyleChange(*animating_element) ||
       !state.StyleBuilder().BaseData()) {
     state.StyleBuilder().SetBaseData(StyleBaseData::Create(
-        ComputedStyle::Clone(*state.Style()), cascade.GetImportantSet()));
+        state.StyleBuilder().CloneStyle(), cascade.GetImportantSet()));
   }
 
   CSSAnimations::CalculateAnimationUpdate(
@@ -1931,8 +1931,9 @@
       MatchedPropertiesCache::IsCacheable(state)) {
     INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
                                   matched_property_cache_added, 1);
-    matched_properties_cache_.Add(cache_success.key, *state.Style(),
-                                  *state.ParentStyle());
+    matched_properties_cache_.Add(cache_success.key,
+                                  state.StyleBuilder().CloneStyle(),
+                                  ComputedStyle::Clone(*state.ParentStyle()));
   }
 }
 
@@ -2118,8 +2119,8 @@
   apply(CascadeFilter(CSSProperty::kLegacyOverlapping, true));
 
   if (state.RejectedLegacyOverlapping()) {
-    scoped_refptr<ComputedStyle> non_legacy_style =
-        ComputedStyle::Clone(*state.Style());
+    scoped_refptr<const ComputedStyle> non_legacy_style =
+        state.StyleBuilder().CloneStyle();
     // Re-apply all overlapping properties (both legacy and non-legacy).
     apply(CascadeFilter(CSSProperty::kOverlapping, false));
     UseCountLegacyOverlapping(GetDocument(), *non_legacy_style, *state.Style());
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index 026705d4..86490c1 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -263,10 +263,12 @@
         }
       }
     }
-    if (auto* document_rules =
-            DocumentSpeculationRules::FromIfExists(GetDocument())) {
-      document_rules->HrefAttributeChanged(this, params.old_value,
-                                           params.new_value);
+    if (isConnected()) {
+      if (auto* document_rules =
+              DocumentSpeculationRules::FromIfExists(GetDocument())) {
+        document_rules->HrefAttributeChanged(this, params.old_value,
+                                             params.new_value);
+      }
     }
     InvalidateCachedVisitedLinkHash();
     LogUpdateAttributeIfIsolatedWorldAndInDocument("a", params);
@@ -604,7 +606,7 @@
     AnchorElementMetricsSender::From(top_document)->AddAnchorElement(*this);
   }
 
-  if (IsLink()) {
+  if (isConnected() && IsLink()) {
     if (auto* document_rules =
             DocumentSpeculationRules::FromIfExists(GetDocument())) {
       document_rules->LinkInserted(this);
@@ -617,7 +619,7 @@
 void HTMLAnchorElement::RemovedFrom(ContainerNode& insertion_point) {
   HTMLElement::RemovedFrom(insertion_point);
 
-  if (IsLink()) {
+  if (insertion_point.isConnected() && IsLink()) {
     if (auto* document_rules =
             DocumentSpeculationRules::FromIfExists(GetDocument())) {
       document_rules->LinkRemoved(this);
diff --git a/third_party/blink/renderer/core/html/parser/literal_buffer.h b/third_party/blink/renderer/core/html/parser/literal_buffer.h
index ef1cf6d..f18a8d9 100644
--- a/third_party/blink/renderer/core/html/parser/literal_buffer.h
+++ b/third_party/blink/renderer/core/html/parser/literal_buffer.h
@@ -271,10 +271,12 @@
   void Append(const String& string) {
     if (string.empty())
       return;
-    if (string.Is8Bit())
+    if (string.Is8Bit()) {
       this->AppendSpan(string.Span8());
-    else
+    } else {
       this->AppendSpan(string.Span16());
+      is_8bit_ &= string.ContainsOnlyLatin1OrEmpty();
+    }
   }
 
   String AsString() const {
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index adb54e9..4520ef6 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -263,6 +263,7 @@
       return ContrastAlgorithmEnum::Apca;
   }
 }
+}  // namespace
 
 void AppendStyleInfo(Node* node,
                      protocol::DictionaryValue* element_info,
@@ -298,6 +299,9 @@
     AtomicString name = CSSPropertyName(properties[i]).ToAtomicString();
     if (value->IsColorValue()) {
       Color color = static_cast<const cssvalue::CSSColor*>(value)->Value();
+      if (!color.IsLegacyColor()) {
+        computed_style->setString(name + "-css-text", value->CssText());
+      }
       computed_style->setString(name, ToHEXA(color));
     } else {
       computed_style->setString(name, value->CssText());
@@ -380,6 +384,7 @@
   return element_info;
 }
 
+namespace {
 std::unique_ptr<protocol::DictionaryValue> BuildTextNodeInfo(Text* text_node) {
   std::unique_ptr<protocol::DictionaryValue> text_info =
       protocol::DictionaryValue::create();
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h
index e338477..d7547a4 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.h
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -319,6 +319,14 @@
                          const InspectorIsolationModeHighlightConfig& config,
                          float scale);
 
+void CORE_EXPORT
+AppendStyleInfo(Node* node,
+                protocol::DictionaryValue* element_info,
+                const InspectorHighlightContrastInfo& node_contrast,
+                const ContrastAlgorithm& contrast_algorithm);
+
+std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
+BuildElementInfo(Element* element);
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_HIGHLIGHT_H_
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
index e3df0e6..b2ed997 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/inspector/inspector_highlight.h"
 
 #include "base/test/values_test_util.h"
+#include "base/values.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -274,4 +275,83 @@
                         expected_isolated_element);
 }
 
+static std::string GetBackgroundColorFromElementInfo(Element* element) {
+  EXPECT_TRUE(element);
+  auto info = BuildElementInfo(element);
+  EXPECT_TRUE(info);
+  AppendStyleInfo(element, info.get(), {}, {});
+
+  protocol::ErrorSupport errors;
+  auto actual_value = protocol::ValueConversions<protocol::Value>::fromValue(
+      info.get(), &errors);
+  EXPECT_TRUE(actual_value);
+
+  std::string json_actual;
+  auto status_to_json = crdtp::json::ConvertCBORToJSON(
+      crdtp::SpanFrom(actual_value->Serialize()), &json_actual);
+  EXPECT_TRUE(status_to_json.ok());
+  base::Value parsed_json_actual = ParseJson(json_actual);
+  auto* style =
+      parsed_json_actual.FindKeyOfType("style", base::Value::Type::DICTIONARY);
+  EXPECT_TRUE(style);
+  auto* backgroundColor = style->FindKeyOfType("background-color-css-text",
+                                               base::Value::Type::STRING);
+  if (!backgroundColor) {
+    backgroundColor =
+        style->FindKeyOfType("background-color", base::Value::Type::STRING);
+  }
+  EXPECT_TRUE(backgroundColor);
+  return backgroundColor->GetString();
+}
+
+TEST_F(InspectorHighlightTest, BuildElementInfo_Colors) {
+  GetDocument().body()->setInnerHTML(R"HTML(
+    <style>
+      div {
+        width: 400px;
+        height: 500px;
+      }
+      #lab {
+        background-color: lab(100% 0 0);
+      }
+      #color {
+        background-color: color(display-p3 50% 50% 50%);
+      }
+      #hex {
+        background-color: #ff00ff;
+      }
+      #rgb {
+        background-color: rgb(128 128 128);
+      }
+      #var {
+        background-color: Var(--lab);
+      }
+      :root {
+        --lab: lab(20% -10 -10);
+      }
+    </style>
+    <div id="lab"></div>
+    <div id="color"></div>
+    <div id="hex"></div>
+    <div id="rgb"></div>
+    <div id="var"></div>
+  )HTML");
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+  EXPECT_THAT(
+      GetBackgroundColorFromElementInfo(GetDocument().getElementById("lab")),
+      Eq("lab(100 0 0)"));
+  EXPECT_THAT(
+      GetBackgroundColorFromElementInfo(GetDocument().getElementById("color")),
+      Eq("color(display-p3 0.5 0.5 0.5)"));
+  EXPECT_THAT(
+      GetBackgroundColorFromElementInfo(GetDocument().getElementById("hex")),
+      Eq("#FF00FFFF"));
+  EXPECT_THAT(
+      GetBackgroundColorFromElementInfo(GetDocument().getElementById("rgb")),
+      Eq("#808080FF"));
+  EXPECT_THAT(
+      GetBackgroundColorFromElementInfo(GetDocument().getElementById("var")),
+      Eq("lab(20 -10 -10)"));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 36fd996..7800182 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1302,7 +1302,8 @@
   // We also want to make sure that if our entrance point into layout changes,
   // e.g. an OOF-positioned object is laid out by an NG containing block, then
   // Legacy, then NG again, NG won't use a stale layout result.
-  if (!IsLayoutNGObject() &&
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled() &&
+      !IsLayoutNGObject() &&
       // When side effects are disabled, it's not possible to disable side
       // effects completely for |RunLegacyLayout|, but at least keep the
       // fragment tree unaffected.
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 1a44e6cc..bb1fc738 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -316,7 +316,8 @@
 void LayoutEmbeddedContent::UpdateLayout() {
   NOT_DESTROYED();
   DCHECK(NeedsLayout());
-  UpdateAfterLayout();
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
+    UpdateAfterLayout();
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index aa2d35e..bdd77d77 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -100,7 +100,8 @@
 
   ClearLayoutOverflow();
 
-  UpdateAfterLayout();
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
+    UpdateAfterLayout();
 
   if (!GetEmbeddedContentView() && GetFrameView())
     GetFrameView()->AddPartToUpdate(*this);
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.cc b/third_party/blink/renderer/core/layout/layout_iframe.cc
index b33261be..77ba4fd 100644
--- a/third_party/blink/renderer/core/layout/layout_iframe.cc
+++ b/third_party/blink/renderer/core/layout/layout_iframe.cc
@@ -51,7 +51,8 @@
   UpdateLogicalHeight();
 
   ClearLayoutOverflow();
-  UpdateAfterLayout();
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
+    UpdateAfterLayout();
 
   ClearNeedsLayout();
 }
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index c9251b03..12e45f7a 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -132,7 +132,8 @@
   ClearSelfNeedsLayoutOverflowRecalc();
   ClearChildNeedsLayoutOverflowRecalc();
 
-  UpdateAfterLayout();
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
+    UpdateAfterLayout();
 
   ClearNeedsLayout();
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 229ee00..88322114 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1393,7 +1393,8 @@
 
   // Replaced elements already have |LayoutBox::UpdateAfterLayout| called when
   // we force a layout for them inside |NGBlockNode::FinishLayout|.
-  if (!box_->IsLayoutReplaced())
+  if (RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled() ||
+      !box_->IsLayoutReplaced())
     box_->UpdateAfterLayout();
 
   if (needs_full_invalidation)
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index 020e83e8..e3732cc 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -275,7 +275,8 @@
       Layer()->SetNeedsCompositingInputsUpdate();
   }
 
-  UpdateAfterLayout();
+  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
+    UpdateAfterLayout();
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index f863ba3..77cc3f26 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -549,20 +549,24 @@
     }
     needs_descendant_dependent_flags_update_ = false;
 
-    if (IsSelfPaintingLayer() && needs_visual_overflow_recalc_) {
-      PhysicalRect old_visual_rect =
-          PhysicalVisualOverflowRectAllowingUnset(GetLayoutObject());
-      GetLayoutObject().RecalcVisualOverflow();
-      if (old_visual_rect != GetLayoutObject().PhysicalVisualOverflowRect()) {
-        MarkAncestorChainForFlagsUpdate(kDoesNotNeedDescendantDependentUpdate);
+    if (needs_visual_overflow_recalc_) {
+      if (IsSelfPaintingLayer()) {
+        PhysicalRect old_visual_rect =
+            PhysicalVisualOverflowRectAllowingUnset(GetLayoutObject());
+        GetLayoutObject().RecalcVisualOverflow();
+        if (old_visual_rect != GetLayoutObject().PhysicalVisualOverflowRect()) {
+          MarkAncestorChainForFlagsUpdate(
+              kDoesNotNeedDescendantDependentUpdate);
+        }
       }
+      if (base::FeatureList::IsEnabled(
+              features::kFastPathPaintPropertyUpdates)) {
+        GetLayoutObject().InvalidateIntersectionObserverCachedRects();
+        GetLayoutObject().GetFrameView()->SetIntersectionObservationState(
+            LocalFrameView::kDesired);
+      }
+      needs_visual_overflow_recalc_ = false;
     }
-    if (base::FeatureList::IsEnabled(features::kFastPathPaintPropertyUpdates)) {
-      GetLayoutObject().InvalidateIntersectionObserverCachedRects();
-      GetLayoutObject().GetFrameView()->SetIntersectionObservationState(
-          LocalFrameView::kDesired);
-    }
-    needs_visual_overflow_recalc_ = false;
   }
 
   bool previously_has_visible_content = has_visible_content_;
diff --git a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
index f69c083..779af1b9 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
+++ b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
@@ -129,12 +129,19 @@
 }
 
 void DocumentSpeculationRules::LinkInserted(HTMLAnchorElement* link) {
+  if (!initialized_)
+    return;
+
   DCHECK(link->IsLink());
+  DCHECK(link->isConnected());
   AddLink(link);
   QueueUpdateSpeculationCandidates();
 }
 
 void DocumentSpeculationRules::LinkRemoved(HTMLAnchorElement* link) {
+  if (!initialized_)
+    return;
+
   DCHECK(link->IsLink());
   RemoveLink(link);
   QueueUpdateSpeculationCandidates();
@@ -144,11 +151,12 @@
     HTMLAnchorElement* link,
     const AtomicString& old_value,
     const AtomicString& new_value) {
-  DCHECK_NE(old_value, new_value);
-
-  if (!link->isConnected())
+  if (!initialized_)
     return;
 
+  DCHECK_NE(old_value, new_value);
+  DCHECK(link->isConnected());
+
   if (old_value.IsNull())
     AddLink(link);
   else if (new_value.IsNull())
@@ -367,6 +375,7 @@
 }
 
 void DocumentSpeculationRules::AddLink(HTMLAnchorElement* link) {
+  DCHECK(initialized_);
   DCHECK(link->IsLink());
   DCHECK(!base::Contains(unmatched_links_, link));
   DCHECK(!base::Contains(matched_links_, link));
@@ -376,6 +385,8 @@
 }
 
 void DocumentSpeculationRules::RemoveLink(HTMLAnchorElement* link) {
+  DCHECK(initialized_);
+
   if (auto it = matched_links_.find(link); it != matched_links_.end()) {
     matched_links_.erase(it);
     DCHECK(!base::Contains(unmatched_links_, link));
@@ -396,6 +407,8 @@
 }
 
 void DocumentSpeculationRules::InvalidateLink(HTMLAnchorElement* link) {
+  DCHECK(initialized_);
+
   pending_links_.insert(link);
   if (auto it = matched_links_.find(link); it != matched_links_.end()) {
     matched_links_.erase(it);
@@ -407,6 +420,8 @@
 }
 
 void DocumentSpeculationRules::InvalidateAllLinks() {
+  DCHECK(initialized_);
+
   for (const auto& it : matched_links_)
     pending_links_.insert(it.key);
   matched_links_.clear();
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
index 0e95ecb..841f46b 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/html/html_anchor_element.h"
 #include "third_party/blink/renderer/core/html/html_area_element.h"
+#include "third_party/blink/renderer/core/html/html_div_element.h"
 #include "third_party/blink/renderer/core/html/html_head_element.h"
 #include "third_party/blink/renderer/core/html/html_script_element.h"
 #include "third_party/blink/renderer/core/loader/empty_clients.h"
@@ -1660,5 +1661,75 @@
   EXPECT_TRUE(candidates.empty());
 }
 
+// Test that adding a link to an element that isn't connected doesn't DCHECK.
+TEST_F(DocumentRulesTest, DisconnectedLink) {
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+  Document& document = page_holder.GetDocument();
+
+  String speculation_script = R"(
+    {"prefetch": [
+      {"source": "document", "where": {"href_matches": "https://foo.com/*"}}
+    ]}
+  )";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  ASSERT_TRUE(candidates.empty());
+
+  HTMLDivElement* div = nullptr;
+  HTMLAnchorElement* link = nullptr;
+  PropagateRulesToStubSpeculationHostWithMicrotasksScope(
+      page_holder, speculation_host, [&]() {
+        div = MakeGarbageCollected<HTMLDivElement>(document);
+        link = AddAnchor(*div, "https://foo.com/blah.html");
+        document.body()->AppendChild(div);
+      });
+  EXPECT_EQ(candidates.size(), 1u);
+
+  PropagateRulesToStubSpeculationHostWithMicrotasksScope(
+      page_holder, speculation_host, [&]() {
+        div->remove();
+        link->remove();
+      });
+  EXPECT_TRUE(candidates.empty());
+}
+
+// Similar to test above, but now inside a shadow tree.
+TEST_F(DocumentRulesTest, DisconnectedLinkInShadowTree) {
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+  Document& document = page_holder.GetDocument();
+
+  String speculation_script = R"(
+    {"prefetch": [
+      {"source": "document", "where": {"href_matches": "https://foo.com/*"}}
+    ]}
+  )";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  ASSERT_TRUE(candidates.empty());
+
+  HTMLDivElement* div = nullptr;
+  HTMLAnchorElement* link = nullptr;
+  PropagateRulesToStubSpeculationHostWithMicrotasksScope(
+      page_holder, speculation_host, [&]() {
+        div = MakeGarbageCollected<HTMLDivElement>(document);
+        ShadowRoot& shadow_root =
+            div->AttachShadowRootInternal(ShadowRootType::kOpen);
+        link = AddAnchor(shadow_root, "https://foo.com/blah.html");
+        document.body()->AppendChild(div);
+      });
+  EXPECT_EQ(candidates.size(), 1u);
+
+  PropagateRulesToStubSpeculationHostWithMicrotasksScope(
+      page_holder, speculation_host, [&]() {
+        div->remove();
+        link->remove();
+      });
+  EXPECT_TRUE(candidates.empty());
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 0a71d54..a8cabc9 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -2706,12 +2706,11 @@
 
   scoped_refptr<ComputedStyle> TakeStyle() { return std::move(style_); }
 
-#if DCHECK_IS_ON()
-  scoped_refptr<ComputedStyle> ToStyle() {
+  // NOTE: Prefer `TakeStyle()` if possible.
+  scoped_refptr<const ComputedStyle> CloneStyle() const {
     DCHECK(style_);
     return ComputedStyle::Clone(*style_);
   }
-#endif  // DCHECK_IS_ON()
 
   CORE_EXPORT void InheritFrom(
       const ComputedStyle& inherit_parent,
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
index d00bc14..f457d7dd 100644
--- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
+++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
@@ -110,7 +110,7 @@
 void SoftNavigationHeuristics::ClickEventEnded(ScriptState* script_state) {
   ThreadScheduler* scheduler = ThreadScheduler::Current();
   DCHECK(scheduler);
-  scheduler->GetTaskAttributionTracker()->UnregisterObserver();
+  scheduler->GetTaskAttributionTracker()->UnregisterObserver(this);
   CheckAndReportSoftNavigation(script_state);
   TRACE_EVENT0("scheduler", "SoftNavigationHeuristics::ClickEventEnded");
 }
@@ -234,4 +234,8 @@
   potential_soft_navigation_task_ids_.insert(task_id.value());
 }
 
+ExecutionContext* SoftNavigationHeuristics::GetExecutionContext() {
+  return GetSupplementable();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
index 40ce6998f..32db599 100644
--- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
+++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
@@ -46,6 +46,7 @@
 
   // TaskAttributionTracker::Observer's implementation.
   void OnCreateTaskScope(const scheduler::TaskAttributionId&) override;
+  ExecutionContext* GetExecutionContext() override;
 
  private:
   void CheckAndReportSoftNavigation(ScriptState*);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 9f6283f..7548af35 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -665,8 +665,6 @@
       ax_tree_source_(BlinkAXTreeSource::Create(*this)),
       ax_tree_serializer_(
           std::make_unique<ui::AXTreeSerializer<AXObject*>>(ax_tree_source_)) {
-  if (document_->IsLoadCompleted())
-    AddPermissionStatusListener();
   use_ax_menu_list_ = GetSettings()->GetUseAXMenuList();
 }
 
@@ -4368,7 +4366,6 @@
   if (!document->IsLoadCompleted() || IsInitialEmptyDocument(*document))
     return;
 
-  AddPermissionStatusListener();
   PostNotification(GetOrCreate(document_node),
                    ax::mojom::blink::Event::kLoadComplete);
 }
diff --git a/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc b/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
index e7780371..61c29b22 100644
--- a/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
+++ b/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
@@ -69,15 +69,6 @@
   // TODO(http://crbug/1289079): Test that prompt() behaves correctly when
   // called in pagehide().
 
-  if (!base::FeatureList::IsEnabled(features::kBackForwardCacheAppBanner)) {
-    // With the current implementation, bfcache could cause prompt() event to be
-    // lost if called after being put into the cache, and the banner will not be
-    // hidden properly. We disable bfcache to avoid these issues.
-    GetSupplementable()->GetFrame()->GetFrameScheduler()->RegisterStickyFeature(
-        blink::SchedulingPolicy::Feature::kAppBanner,
-        {blink::SchedulingPolicy::DisableBackForwardCache()});
-  }
-
   mojom::AppBannerPromptReply reply =
       GetSupplementable()->DispatchEvent(*BeforeInstallPromptEvent::Create(
           event_type_names::kBeforeinstallprompt, *GetSupplementable(),
diff --git a/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc b/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
index a777d21..b8a60f6e 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
 
+#include "base/notreached.h"
 #include "media/base/eme_constants.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/modules/exported/web_ax_context.cc b/third_party/blink/renderer/modules/exported/web_ax_context.cc
index c6138a63..ddc43019 100644
--- a/third_party/blink/renderer/modules/exported/web_ax_context.cc
+++ b/third_party/blink/renderer/modules/exported/web_ax_context.cc
@@ -130,4 +130,9 @@
   return private_->GetAXObjectCache().ScheduleAXUpdate();
 }
 
+void WebAXContext::FireLoadCompleteIfLoaded() {
+  if (!private_->HasActiveDocument())
+    return;
+  return private_->GetDocument()->DispatchHandleLoadComplete();
+}
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_device.idl b/third_party/blink/renderer/modules/hid/hid_device.idl
index c01e8cb..88a9696 100644
--- a/third_party/blink/renderer/modules/hid/hid_device.idl
+++ b/third_party/blink/renderer/modules/hid/hid_device.idl
@@ -43,11 +43,7 @@
 
     // Revoke permission to the device. The promise is resolved once the
     // device is forgotten.
-    [
-        CallWith=ScriptState,
-        RaisesException,
-        RuntimeEnabled=HidDeviceForget
-    ] Promise<void> forget();
+    [CallWith=ScriptState, RaisesException] Promise<void> forget();
 
     // Send an output report to the device. Set |reportId| to the first byte of
     // the report and |data| to the remaining bytes. Set |reportId| to zero if
diff --git a/third_party/blink/renderer/modules/hid/hid_device_request_options.idl b/third_party/blink/renderer/modules/hid/hid_device_request_options.idl
index ba0022b..1cbc067 100644
--- a/third_party/blink/renderer/modules/hid/hid_device_request_options.idl
+++ b/third_party/blink/renderer/modules/hid/hid_device_request_options.idl
@@ -7,5 +7,5 @@
 
 dictionary HIDDeviceRequestOptions {
     required sequence<HIDDeviceFilter> filters;
-    [RuntimeEnabled=WebHIDExclusionFiltersOption] sequence<HIDDeviceFilter> exclusionFilters;
+    sequence<HIDDeviceFilter> exclusionFilters;
 };
diff --git a/third_party/blink/renderer/modules/nfc/ndef_reader.idl b/third_party/blink/renderer/modules/nfc/ndef_reader.idl
index d4ebdc0..38b871b 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_reader.idl
+++ b/third_party/blink/renderer/modules/nfc/ndef_reader.idl
@@ -24,6 +24,6 @@
         NDEFMessageSource message,
         optional NDEFWriteOptions options={});
 
-    [CallWith=ScriptState, RaisesException, MeasureAs=WebNfcNdefMakeReadOnly, RuntimeEnabled=WebNFCMakeReadOnly] Promise<void> makeReadOnly(
+    [CallWith=ScriptState, RaisesException, MeasureAs=WebNfcNdefMakeReadOnly] Promise<void> makeReadOnly(
         optional NDEFMakeReadOnlyOptions options={});
 };
diff --git a/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.cc b/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.cc
index d697b71..e3ad90b 100644
--- a/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.cc
+++ b/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_script_wrappable_task_attribution_id.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/modules/scheduler/script_wrappable_task_attribution_id.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
@@ -163,8 +164,11 @@
   running_task_id_ = next_task_id_;
 
   InsertTaskAttributionIdPair(next_task_id_, parent_task_id);
-  if (observer_) {
-    observer_->OnCreateTaskScope(next_task_id_);
+  ExecutionContext* execution_context = ExecutionContext::From(script_state);
+  for (Observer* observer : observers_) {
+    if (observer->GetExecutionContext() == execution_context) {
+      observer->OnCreateTaskScope(next_task_id_);
+    }
   }
 
   SaveTaskIdStateInV8(script_state, next_task_id_);
diff --git a/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.h b/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.h
index a5b7a14..67dd03ea 100644
--- a/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.h
+++ b/third_party/blink/renderer/modules/scheduler/task_attribution_tracker_impl.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/common/scheduler/task_attribution_id.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -56,11 +57,19 @@
   void TaskScopeCompleted(ScriptState*, TaskAttributionId);
 
   void RegisterObserver(TaskAttributionTracker::Observer* observer) override {
-    DCHECK(!observer_ || observer == observer_);
-    observer_ = observer;
+    if (observers_.find(observer) == observers_.end()) {
+      observers_.insert(observer);
+    }
   }
 
-  void UnregisterObserver() override { observer_.Clear(); }
+  void UnregisterObserver(TaskAttributionTracker::Observer* observer) override {
+    auto it = observers_.find(observer);
+    // It's possible for the observer to not be registered if it already
+    // unregistered itself in the past.
+    if (it != observers_.end()) {
+      observers_.erase(it);
+    }
+  }
 
  private:
   struct TaskAttributionIdPair {
@@ -151,7 +160,7 @@
   WTF::Vector<TaskAttributionIdPair> task_container_ =
       WTF::Vector<TaskAttributionIdPair>(kVectorSize);
 
-  WeakPersistent<TaskAttributionTracker::Observer> observer_;
+  WTF::HashSet<WeakPersistent<TaskAttributionTracker::Observer>> observers_;
 };
 
 }  // namespace blink::scheduler
diff --git a/third_party/blink/renderer/modules/serial/serial_port.idl b/third_party/blink/renderer/modules/serial/serial_port.idl
index 6591d1f..ee84a814 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.idl
+++ b/third_party/blink/renderer/modules/serial/serial_port.idl
@@ -26,6 +26,6 @@
     Promise<void> setSignals(optional SerialOutputSignals signals = {});
     [RaisesException, CallWith=ScriptState, MeasureAs=SerialPortClose]
     Promise<void> close();
-    [RaisesException, CallWith=ScriptState, MeasureAs=SerialPortForget, RuntimeEnabled=SerialPortForget]
+    [RaisesException, CallWith=ScriptState, MeasureAs=SerialPortForget]
     Promise<void> forget();
 };
diff --git a/third_party/blink/renderer/modules/storage/cached_storage_area.cc b/third_party/blink/renderer/modules/storage/cached_storage_area.cc
index 9fda143..a94789b 100644
--- a/third_party/blink/renderer/modules/storage/cached_storage_area.cc
+++ b/third_party/blink/renderer/modules/storage/cached_storage_area.cc
@@ -233,8 +233,13 @@
     return;
   }
 
-  auto task_runner =
-      local_dom_window->GetTaskRunner(TaskType::kInternalNavigationAssociated);
+  // Because the storage area is keyed by the BlinkStorageKey it could be
+  // reused by other frames in the same agent cluster so we use the
+  // associated AgentGroupScheduler's task runner.
+  auto task_runner = local_dom_window->GetFrame()
+                         ->GetFrameScheduler()
+                         ->GetAgentGroupScheduler()
+                         ->DefaultTaskRunner();
   if (new_area) {
     remote_area_.Bind(std::move(new_area), task_runner);
   } else if (storage_namespace_) {
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
index f6d6ab8..de8fd6c 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -631,10 +631,12 @@
   if (it != chunk_metadata_.end()) {
     const auto duration = it->second.duration;
     if (!duration.is_zero() && duration != media::kNoTimestamp) {
-      output = media::VideoFrame::WrapVideoFrame(output, output->format(),
-                                                 output->visible_rect(),
-                                                 output->natural_size());
-      output->metadata().frame_duration = duration;
+      auto wrapped_output = media::VideoFrame::WrapVideoFrame(
+          output, output->format(), output->visible_rect(),
+          output->natural_size());
+      wrapped_output->set_color_space(output->ColorSpace());
+      wrapped_output->metadata().frame_duration = duration;
+      output = wrapped_output;
     }
   }
 
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.idl b/third_party/blink/renderer/modules/webusb/usb_device.idl
index 44330c1..658ea75 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.idl
+++ b/third_party/blink/renderer/modules/webusb/usb_device.idl
@@ -38,7 +38,7 @@
 
     [CallWith=ScriptState, MeasureAs=UsbDeviceOpen, RaisesException] Promise<void> open();
     [CallWith=ScriptState, MeasureAs=UsbDeviceClose, RaisesException] Promise<void> close();
-    [CallWith=ScriptState, MeasureAs=UsbDeviceForget, RaisesException, RuntimeEnabled=WebUsbDeviceForget] Promise<void> forget();
+    [CallWith=ScriptState, MeasureAs=UsbDeviceForget, RaisesException] Promise<void> forget();
     [CallWith=ScriptState, MeasureAs=UsbDeviceSelectConfiguration, RaisesException] Promise<void> selectConfiguration(octet configurationValue);
     [CallWith=ScriptState, MeasureAs=UsbDeviceClaimInterface, RaisesException] Promise<void> claimInterface(octet interfaceNumber);
     [CallWith=ScriptState, MeasureAs=UsbDeviceReleaseInterface, RaisesException] Promise<void> releaseInterface(octet interfaceNumber);
diff --git a/third_party/blink/renderer/platform/heap/cross_thread_persistent.h b/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
index 5f106445..3b0223c 100644
--- a/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
+++ b/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
@@ -96,6 +96,9 @@
 template <typename T>
 struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {};
 
+template <typename>
+struct BindUnwrapTraits;
+
 template <typename T>
 struct BindUnwrapTraits<blink::CrossThreadWeakPersistent<T>> {
   static blink::CrossThreadPersistent<T> Unwrap(
diff --git a/third_party/blink/renderer/platform/heap/persistent.h b/third_party/blink/renderer/platform/heap/persistent.h
index 3718057..9b6bf7d8 100644
--- a/third_party/blink/renderer/platform/heap/persistent.h
+++ b/third_party/blink/renderer/platform/heap/persistent.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
 
-#include "base/bind.h"
 #include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
 #include "third_party/blink/renderer/platform/wtf/hash_functions.h"
@@ -245,6 +244,9 @@
 namespace base {
 
 template <typename T>
+struct IsWeakReceiver;
+
+template <typename T>
 struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {};
 
 // template <typename T>
@@ -259,6 +261,9 @@
 //   }
 // };
 
+template <typename>
+struct MaybeValidTraits;
+
 // TODO(https://crbug.com/653394): Consider returning a thread-safe best
 // guess of validity. MaybeValid() can be invoked from an arbitrary thread.
 template <typename T>
diff --git a/third_party/blink/renderer/platform/network/http_parsers.cc b/third_party/blink/renderer/platform/network/http_parsers.cc
index 9714186..cf9f5c9 100644
--- a/third_party/blink/renderer/platform/network/http_parsers.cc
+++ b/third_party/blink/renderer/platform/network/http_parsers.cc
@@ -43,6 +43,7 @@
 #include "services/network/public/cpp/content_security_policy/content_security_policy.h"
 #include "services/network/public/cpp/parsed_headers.h"
 #include "services/network/public/cpp/timing_allow_origin_parser.h"
+#include "services/network/public/mojom/no_vary_search.mojom-blink.h"
 #include "services/network/public/mojom/parsed_headers.mojom-blink.h"
 #include "services/network/public/mojom/supports_loading_mode.mojom-blink.h"
 #include "services/network/public/mojom/timing_allow_origin.mojom-blink.h"
@@ -249,6 +250,23 @@
                                     ConvertToBlink(in->available_values));
 }
 
+blink::NoVarySearchPtr ConvertToBlink(const NoVarySearchPtr& in) {
+  if (!in)
+    return nullptr;
+
+  DCHECK(in->search_variance);
+  if (in->search_variance->is_no_vary_params()) {
+    return blink::NoVarySearch::New(
+        blink::SearchParamsVariance::NewNoVaryParams(
+            ConvertToBlink(in->search_variance->get_no_vary_params())),
+        in->vary_on_key_order);
+  }
+  return blink::NoVarySearch::New(
+      blink::SearchParamsVariance::NewVaryParams(
+          ConvertToBlink(in->search_variance->get_vary_params())),
+      in->vary_on_key_order);
+}
+
 blink::ParsedHeadersPtr ConvertToBlink(const ParsedHeadersPtr& in) {
   DCHECK(in);
   return blink::ParsedHeaders::New(
@@ -272,7 +290,8 @@
           : absl::nullopt,
       in->content_language.has_value()
           ? absl::make_optional(ConvertToBlink(in->content_language.value()))
-          : absl::nullopt);
+          : absl::nullopt,
+      ConvertToBlink(in->no_vary_search));
 }
 
 }  // namespace mojom
diff --git a/third_party/blink/renderer/platform/network/http_parsers_test.cc b/third_party/blink/renderer/platform/network/http_parsers_test.cc
index a296b55..668c1a57d 100644
--- a/third_party/blink/renderer/platform/network/http_parsers_test.cc
+++ b/third_party/blink/renderer/platform/network/http_parsers_test.cc
@@ -4,14 +4,21 @@
 
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
 
+#include "base/strings/string_piece.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
+#include "net/base/features.h"
+#include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/content_security_policy.mojom-blink-forward.h"
 #include "services/network/public/mojom/content_security_policy.mojom-blink.h"
 #include "services/network/public/mojom/parsed_headers.mojom-blink.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
 
@@ -851,4 +858,138 @@
   }
 }
 
+class NoVarySearchPrefetchDisabledTest
+    : public ::testing::Test,
+      public ::testing::WithParamInterface<base::StringPiece> {};
+
+TEST_P(NoVarySearchPrefetchDisabledTest, ParsingNVSReturnsDefaultURLVariance) {
+  const auto parsed_headers =
+      ParseHeaders(WTF::String::FromUTF8(GetParam()), KURL("https://a.com"));
+
+  EXPECT_TRUE(parsed_headers);
+  EXPECT_FALSE(parsed_headers->no_vary_search);
+}
+
+constexpr base::StringPiece no_vary_search_prefetch_disabled_data[] = {
+    // No No-Vary-Search header.
+    "HTTP/1.1 200 OK\r\n"
+    "Set-Cookie: a\r\n"
+    "Set-Cookie: b\r\n\r\n",
+    // No-Vary-Search header present.
+    "HTTP/1.1 200 OK\r\n"
+    R"(No-Vary-Search: params=("a"))"
+    "\r\n\r\n",
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    NoVarySearchPrefetchDisabledTest,
+    NoVarySearchPrefetchDisabledTest,
+    testing::ValuesIn(no_vary_search_prefetch_disabled_data));
+
+TEST(NoVarySearchPrefetchEnabledTest, ParsingNVSReturnsDefaultURLVariance) {
+  base::test::ScopedFeatureList feature_list(
+      network::features::kPrefetchNoVarySearch);
+  const base::StringPiece headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Set-Cookie: a\r\n"
+      "Set-Cookie: b\r\n\r\n";
+  const auto parsed_headers =
+      ParseHeaders(WTF::String::FromUTF8(headers), KURL("https://a.com"));
+
+  EXPECT_TRUE(parsed_headers);
+  EXPECT_FALSE(parsed_headers->no_vary_search);
+}
+
+struct NoVarySearchTestData {
+  const char* raw_headers;
+  const Vector<String> expected_no_vary_params;
+  const Vector<String> expected_vary_params;
+  const bool expected_vary_on_key_order;
+  const bool expected_vary_by_default;
+};
+
+class NoVarySearchPrefetchEnabledTest
+    : public ::testing::Test,
+      public ::testing::WithParamInterface<NoVarySearchTestData> {
+ public:
+  NoVarySearchPrefetchEnabledTest() {
+    feature_list_.InitAndEnableFeature(
+        network::features::kPrefetchNoVarySearch);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_P(NoVarySearchPrefetchEnabledTest, ParsingSuccess) {
+  const auto& test_data = GetParam();
+  const auto parsed_headers =
+      ParseHeaders(test_data.raw_headers, KURL("https://a.com"));
+
+  EXPECT_TRUE(parsed_headers);
+  ASSERT_TRUE(parsed_headers->no_vary_search);
+  ASSERT_TRUE(parsed_headers->no_vary_search->search_variance);
+  if (test_data.expected_vary_by_default) {
+    EXPECT_THAT(
+        parsed_headers->no_vary_search->search_variance->get_no_vary_params(),
+        test_data.expected_no_vary_params);
+  } else {
+    EXPECT_THAT(
+        parsed_headers->no_vary_search->search_variance->get_vary_params(),
+        test_data.expected_vary_params);
+  }
+  EXPECT_EQ(parsed_headers->no_vary_search->vary_on_key_order,
+            test_data.expected_vary_on_key_order);
+}
+
+Vector<NoVarySearchTestData> GetNoVarySearchParsingSuccessTestData() {
+  static Vector<NoVarySearchTestData> test_data = {
+      // params set to a list of strings with one element.
+      {
+          "HTTP/1.1 200 OK\r\n"
+          R"(No-Vary-Search: params=("a"))"
+          "\r\n\r\n",             // raw_headers
+          Vector<String>({"a"}),  // expected_no_vary_params
+          {},                     // expected_vary_params
+          true,                   // expected_vary_on_key_order
+          true                    // expected_vary_by_default
+      },
+      // params set to true.
+      {
+          "HTTP/1.1 200 OK\r\n"
+          "No-Vary-Search: params\r\n\r\n",  // raw_headers
+          {},                                // expected_no_vary_params
+          {},                                // expected_vary_params
+          true,                              // expected_vary_on_key_order
+          false                              // expected_vary_by_default
+      },
+      // Vary on one search param.
+      {
+          "HTTP/1.1 200 OK\r\n"
+          "No-Vary-Search: params\r\n"
+          R"(No-Vary-Search: except=("a"))"
+          "\r\n\r\n",             // raw_headers
+          {},                     // expected_no_vary_params
+          Vector<String>({"a"}),  // expected_vary_params
+          true,                   // expected_vary_on_key_order
+          false                   // expected_vary_by_default
+      },
+      // Don't vary on search params order.
+      {
+          "HTTP/1.1 200 OK\r\n"
+          "No-Vary-Search: key-order\r\n\r\n",  // raw_headers
+          {},                                   // expected_no_vary_params
+          {},                                   // expected_vary_params
+          false,                                // expected_vary_on_key_order
+          true                                  // expected_vary_by_default
+      },
+  };
+  return test_data;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    NoVarySearchPrefetchEnabledTest,
+    NoVarySearchPrefetchEnabledTest,
+    testing::ValuesIn(GetNoVarySearchParsingSuccessTestData()));
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 8ff77ca..ebf233cb 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1410,11 +1410,6 @@
         "default": "experimental",
       },
     },
-    {
-      name: "HidDeviceForget",
-      depends_on: ["WebHID"],
-      status: {"Android": "", "default": "stable"},
-    },
     // HighlightAPI's custom highlights use HighlightInheritance's behavior even
     // if the HighlightInheritance feature is not enabled.
     {
@@ -1597,6 +1592,15 @@
       status: "stable",
     },
     {
+      // Merge UpdateAfterLayout() calls for LayoutReplaced into one in
+      // CopyFragmentDataToLayoutBox(). crbug.com/1353190
+      name: "LayoutNGUnifyUpdateAfterLayout",
+      // This feature doesn't work in the legacy layout.
+      depends_on: ["LayoutNGPrinting"],
+      status: "stable",
+      base_feature: "LayoutNGUnifyUpdateAfterLayout",
+    },
+    {
       name: "LazyFrameLoading",
       public: true,
       status: "stable",
@@ -2449,10 +2453,6 @@
       status: {"Android": "", "default": "stable"},
     },
     {
-      name: "SerialPortForget",
-      status: {"Android": "", "default": "stable"},
-    },
-    {
       name: "ServiceWorkerClientLifecycleState",
       status: "experimental",
     },
@@ -3096,10 +3096,6 @@
       status: {"Android": "", "default": "stable"},
     },
     {
-      name: "WebHIDExclusionFiltersOption",
-      status: "stable",
-    },
-    {
       // It is only enabled in extension environment for now.
       name: "WebHIDOnServiceWorkers",
       depends_on: ["WebHID"],
@@ -3117,11 +3113,6 @@
       status: {"Android": "stable", "default": "test"},
     },
     {
-      name: "WebNFCMakeReadOnly",
-      depends_on: ["WebNFC"],
-      status: {"Android": "stable", "default": "test"},
-    },
-    {
       name: "WebOTP",
       public: true,
       status: "stable",
@@ -3159,10 +3150,6 @@
       status: "stable",
     },
     {
-      name: "WebUsbDeviceForget",
-      status: "stable",
-    },
-    {
       name: "WebUSBOnDedicatedWorkers",
       status: "stable",
       depends_on: ["WebUSB"],
diff --git a/third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h b/third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h
index bad3946..529bdaa 100644
--- a/third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h
+++ b/third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
 namespace blink {
+class ExecutionContext;
 class ScriptState;
 }  // namespace blink
 
@@ -51,6 +52,7 @@
   class Observer : public GarbageCollectedMixin {
    public:
     virtual void OnCreateTaskScope(const TaskAttributionId&) = 0;
+    virtual ExecutionContext* GetExecutionContext() = 0;
   };
 
   virtual ~TaskAttributionTracker() = default;
@@ -73,11 +75,10 @@
       ScriptState*,
       const WTF::HashSet<scheduler::TaskAttributionIdType>&) = 0;
 
-  // Register an observer to be notified when a task is started. Only one
-  // observer can be set at every point in time.
+  // Register an observer to be notified when a task is started.
   virtual void RegisterObserver(Observer* observer) = 0;
   // Unregister the observer.
-  virtual void UnregisterObserver() = 0;
+  virtual void UnregisterObserver(Observer* observer) = 0;
 };
 
 }  // namespace blink::scheduler
diff --git a/third_party/blink/renderer/platform/wtf/text/base64_test.cc b/third_party/blink/renderer/platform/wtf/text/base64_test.cc
index 10e41c12..f7f93a3 100644
--- a/third_party/blink/renderer/platform/wtf/text/base64_test.cc
+++ b/third_party/blink/renderer/platform/wtf/text/base64_test.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/wtf/text/base64.h"
 
+#include "base/containers/span.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -11,6 +12,29 @@
 
 namespace WTF {
 
+TEST(Base64Test, Encode) {
+  struct {
+    const char* in;
+    Vector<char> expected_out;
+  } kTestCases[] = {{"", {}},
+                    {"i", {'a', 'Q', '=', '='}},
+                    {"i\xB7", {'a', 'b', 'c', '='}},
+                    {"i\xB7\x1D", {'a', 'b', 'c', 'd'}}};
+
+  for (const auto& test : kTestCases) {
+    base::span<const uint8_t> in =
+        base::as_bytes(base::make_span(test.in, strlen(test.in)));
+
+    Vector<char> out_vec;
+    Base64Encode(in, out_vec);
+    EXPECT_EQ(out_vec, test.expected_out);
+
+    String out_str = Base64Encode(in);
+    EXPECT_EQ(out_str,
+              String(test.expected_out.data(), test.expected_out.size()));
+  }
+}
+
 TEST(Base64Test, DecodeNoPaddingValidation) {
   struct {
     const char* in;
diff --git a/third_party/blink/tools/run_wpt_tests.py b/third_party/blink/tools/run_wpt_tests.py
index 7530bf4..37cfcad0 100755
--- a/third_party/blink/tools/run_wpt_tests.py
+++ b/third_party/blink/tools/run_wpt_tests.py
@@ -575,8 +575,14 @@
     @property
     def wpt_args(self):
         wpt_args = list(super().wpt_args)
+        cwt_chromedriver_path = os.path.realpath(
+            os.path.join(
+                os.path.dirname(__file__),
+                '../../../ios/chrome/test/wpt/tools/'
+                'run_cwt_chromedriver_wrapper.py'))
         wpt_args.extend([
             '--processes=%d' % self._options.processes,
+            '--webdriver-binary=%s' % cwt_chromedriver_path,
         ])
         return wpt_args
 
@@ -851,7 +857,8 @@
                 instances.append(instance)
 
             SyncParallelizer(instances).Start(writable_system=True,
-                                              window=args.emulator_window)
+                                              window=args.emulator_window,
+                                              require_fast_start=True)
 
         #TODO(weizhong): when choose device, make sure abi matches with target
         yield device_utils.DeviceUtils.HealthyDevices()
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0142bb5..0528d75 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5736,7 +5736,7 @@
 crbug.com/1273541 fast/block/float/float-on-clean-line-subsequently-dirtied.html [ Failure Pass ]
 
 # Sheriff 2021-11-26
-crbug.com/1201879 [ Linux ] http/tests/inspector-protocol/issues/mixed-content-issue-creation-js-within-oopif.js [ Failure Pass Timeout ]
+crbug.com/1201879 http/tests/inspector-protocol/issues/mixed-content-issue-creation-js-within-oopif.js [ Failure Pass Timeout ]
 crbug.com/1274171 inspector-protocol/debugger/debugger-setTimeout-sourceUrl-dedicated-worker-loop.js [ Pass Timeout ]
 crbug.com/1271485 http/tests/inspector-protocol/network/load-network-resource-different-frame-cookie.js [ Failure Pass Timeout ]
 crbug.com/1228803 [ Linux ] fast/peerconnection/RTCPeerConnection-garbagecollected.html [ Failure Pass ]
@@ -6445,6 +6445,8 @@
 crbug.com/1380575 [ Linux ] virtual/scalefactor200/fast/forms/file/file-appearance-no-default-width.html [ Failure ]
 crbug.com/1376986 [ Mac11 ] virtual/compute-pressure/external/wpt/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.html [ Timeout ]
 crbug.com/1378078 [ Debug Linux ] media/controls/slow-doubletap.html [ Failure ]
+crbug.com/1384671 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Failure Timeout ]
+crbug.com/1384671 [ Linux ] external/wpt/speculation-rules/prerender/opt-out.html [ Failure Timeout ]
 
 # Sheriff 2022-10-07
 crbug.com/1372556 [ Linux ] external/wpt/css/css-text/text-transform/text-transform-capitalize-* [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/idlharness.window-expected.txt
index 16f27e1c..3d69232 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/idlharness.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/idlharness.window-expected.txt
@@ -29,8 +29,8 @@
 PASS ViewTimeline interface: existence and properties of interface prototype object's "constructor" property
 PASS ViewTimeline interface: existence and properties of interface prototype object's @@unscopables property
 PASS ViewTimeline interface: attribute subject
-FAIL ViewTimeline interface: attribute startOffset assert_true: The prototype object must have a property "startOffset" expected true got false
-FAIL ViewTimeline interface: attribute endOffset assert_true: The prototype object must have a property "endOffset" expected true got false
+PASS ViewTimeline interface: attribute startOffset
+PASS ViewTimeline interface: attribute endOffset
 PASS AnimationTimeline interface: existence and properties of interface object
 PASS AnimationTimeline interface object length
 PASS AnimationTimeline interface object name
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/testcommon.js b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/testcommon.js
index ba27576..41341cf6 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/testcommon.js
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/testcommon.js
@@ -1,5 +1,12 @@
 'use strict';
 
+function assert_px_equals(observed, expected, description) {
+  assert_equals(observed.unit, 'px',
+                `Unexpected unit type for '${description}'`);
+  assert_approx_equals(observed.value, expected, 0.0001,
+                       `Unexpected value for ${description}`);
+}
+
 function CreateViewTimelineOpacityAnimation(test, target, options) {
   const viewTimelineOptions = {
     subject: target,
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-delay.html b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-delay.html
index 8d28137..1377dc3 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-delay.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-delay.html
@@ -44,17 +44,29 @@
 </body>
 <script type="text/javascript">
   promise_test(async t => {
+    // Delays are associated with the animation and not with the timeline.
+    // Thus adjusting the delays has no effect on the timeline offsets.  The
+    // offsets always correspond to the 'cover' range.
+    const verifyTimelineOffsets = anim => {
+      const timeline = anim.timeline;
+      assert_px_equals(timeline.startOffset, 600, 'startOffset');
+      assert_px_equals(timeline.endOffset, 900, 'endOffset');
+    };
     await runTimelineDelayTest(t, {
       delay: { phase: 'cover', percent: CSS.percent(0) } ,
       endDelay: { phase: 'cover', percent: CSS.percent(100) },
       rangeStart: 600,
       rangeEnd: 900
+    }).then(anim => {
+      verifyTimelineOffsets(anim);
     });
     await runTimelineDelayTest(t, {
       delay: { phase: 'contain', percent: CSS.percent(0) } ,
       endDelay: { phase: 'contain', percent: CSS.percent(100) },
       rangeStart: 700,
       rangeEnd: 800
+    }).then(anim => {
+      verifyTimelineOffsets(anim);
     });
     await runTimelineDelayTest(t, {
       delay: { phase: 'enter', percent: CSS.percent(0) },
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-inset.html b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-inset.html
index 45e21f75..4864d63 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-inset.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/view-timeline-inset.html
@@ -51,6 +51,13 @@
   </div>
 </body>
 <script type="text/javascript">
+
+  function verifyTimelineOffsets(anim, start, end)  {
+    const timeline = anim.timeline;
+    assert_px_equals(timeline.startOffset, start, 'startOffset');
+    assert_px_equals(timeline.endOffset, end, 'endOffset');
+  };
+
   promise_test(async t => {
     // These tests are all based on the cover range, which has bounds
     // [600, 900] if there are no insets.
@@ -62,17 +69,17 @@
       inset: [ CSS.px(0), CSS.px(0) ],
       rangeStart: 600,
       rangeEnd: 900
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 600, 900));
     await runTimelineInsetTest(t, {
       inset: [ CSS.px(10), CSS.px(20) ],
       rangeStart: 620,
       rangeEnd: 890
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 620, 890));
     await runTimelineInsetTest(t, {
       inset: [ CSS.px(10) ],
       rangeStart: 610,
       rangeEnd: 890
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 610, 890));
   }, 'View timeline with px based inset.');
 
   promise_test(async t => {
@@ -84,17 +91,17 @@
       inset: [ CSS.percent(0), CSS.percent(0) ],
       rangeStart: 600,
       rangeEnd: 900
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 600, 900));
     await runTimelineInsetTest(t, {
       inset: [ CSS.percent(10), CSS.percent(20) ],
       rangeStart: 640,
       rangeEnd: 880
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 640, 880));
     await runTimelineInsetTest(t, {
       inset: [ CSS.percent(10) ],
       rangeStart: 620,
       rangeEnd: 880
-    });
+    }).then(anim => verifyTimelineOffsets(anim, 620, 880));
   }, 'View timeline with percent based inset.');
 
   promise_test(async t => {
@@ -106,12 +113,14 @@
       rangeStart: 600,
       rangeEnd: 900
     });
+    verifyTimelineOffsets(anim, 600, 900);
     container.classList.add('scroll-padded');
     await runTimelineRangeTest(t, {
       anim: anim,
       rangeStart: 620,
       rangeEnd: 890,
-    }, 'Adjust for scroll-padding');
+    }, 'Adjust for scroll-padding')
+        .then(anim => verifyTimelineOffsets(anim, 620, 890));
   }, 'view timeline with inset auto.');
 
 promise_test(async t => {
@@ -122,13 +131,15 @@
     inset: [ CSS.em(1), CSS.em(2) ],
     rangeStart: 632,
     rangeEnd: 884
-  });
+  })
+  verifyTimelineOffsets(anim, 632, 884);
   target.classList.add('big-font');
   await runTimelineRangeTest(t, {
     anim: anim,
     rangeStart: 640,
     rangeEnd: 880,
-  }, 'Adjust for font size increase');
+  }, 'Adjust for font size increase')
+      .then(anim => verifyTimelineOffsets(anim, 640, 880));
 }, 'view timeline with font relative inset.');
 
 promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/navigate-child.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/navigate-child.html
new file mode 100644
index 0000000..63a8adb2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/navigate-child.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Navigate a child window.</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="resources/soft-navigation-helper.js"></script>
+</head>
+<body>
+  <main id=main>
+  <a href="empty.html?2" rel=opener target=child id=link>Click me!</a>
+  </main>
+  <script>
+    promise_test(async t => {
+      const child = window.open("resources/empty.html?1", "child");
+      while (!child.document) {
+        await new Promise(r => t.step_timeout(r, 10));
+      }
+      const link = document.getElementById("link");
+      click(link);
+      while (!child.location.href.includes("2")) {
+        await new Promise(r => t.step_timeout(r, 10));
+      }
+    }, "Test that a navigated child window doesn't crash");
+  </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/resources/empty.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/resources/empty.html
new file mode 100644
index 0000000..5fa1cdf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/resources/empty.html
@@ -0,0 +1,2 @@
+<!DOCTYPE HTML>
+
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
index d56bb0b2..943de67 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
@@ -10,10 +10,11 @@
 var ENCODER_CONFIG = null;
 promise_setup(async () => {
   const config = {
-    '?av1': {codec: 'av01.0.04M.08'},
-    '?vp8': {codec: 'vp8'},
-    '?vp9_p0': {codec: 'vp09.00.10.08'},
-    '?vp9_p2': {codec: 'vp09.02.10.10'},
+    // FIXME: H.264 has embedded color space information too.
+    '?av1': {codec: 'av01.0.04M.08', hasEmbeddedColorSpace: true},
+    '?vp8': {codec: 'vp8', hasEmbeddedColorSpace: false},
+    '?vp9_p0': {codec: 'vp09.00.10.08', hasEmbeddedColorSpace: true},
+    '?vp9_p2': {codec: 'vp09.02.10.10', hasEmbeddedColorSpace: true},
     '?h264_avc': {codec: 'avc1.42001E', avc: {format: 'avc'}},
     '?h264_annexb': {codec: 'avc1.42001E', avc: {format: 'annexb'}}
   }[location.search];
@@ -26,7 +27,7 @@
   ENCODER_CONFIG = config;
 });
 
-promise_test(async t => {
+async function runFullCycleTest(t, options) {
   let encoder_config = { ...ENCODER_CONFIG };
   const w = encoder_config.width;
   const h = encoder_config.height;
@@ -41,6 +42,17 @@
       assert_equals(frame.visibleRect.width, w, "visibleRect.width");
       assert_equals(frame.visibleRect.height, h, "visibleRect.height");
       assert_equals(frame.timestamp, next_ts++, "decode timestamp");
+
+      // The encoder is allowed to change the color space to satisfy the
+      // encoder when readback is needed to send the frame for encoding, so
+      // just ensure we have something set on the frame.
+      assert_not_equals(
+          frame.colorSpace.primaries, null, 'colorSpace.primaries');
+      assert_not_equals(frame.colorSpace.transfer, null, 'colorSpace.transfer');
+      assert_not_equals(frame.colorSpace.matrix, null, 'colorSpace.matrix');
+      assert_not_equals(
+          frame.colorSpace.fullRange, null, 'colorSpace.fullRange');
+
       frames_decoded++;
       assert_true(validateBlackDots(frame, frame.timestamp),
         "frame doesn't match. ts: " + frame.timestamp);
@@ -57,6 +69,12 @@
       let config = metadata.decoderConfig;
       if (config) {
         config.hardwareAcceleration = encoder_config.hardwareAcceleration;
+
+        // Removes the color space provided by the encoder so that color space
+        // information in the underlying bitstream is exposed during decode.
+        if (options.stripDecoderConfigColorSpace)
+          config.colorSpace = {};
+
         decoder.configure(config);
       }
       decoder.decode(chunk);
@@ -73,6 +91,13 @@
 
   for (let i = 0; i < frames_to_encode; i++) {
     let frame = createDottedFrame(w, h, i);
+
+    // Frames should have a valid color space when created from canvas.
+    assert_not_equals(frame.colorSpace.primaries, null, 'colorSpace.primaries');
+    assert_not_equals(frame.colorSpace.transfer, null, 'colorSpace.transfer');
+    assert_not_equals(frame.colorSpace.matrix, null, 'colorSpace.matrix');
+    assert_not_equals(frame.colorSpace.fullRange, null, 'colorSpace.fullRange');
+
     let keyframe = (i % 5 == 0);
     encoder.encode(frame, { keyFrame: keyframe });
     frame.close();
@@ -83,5 +108,13 @@
   decoder.close();
   assert_equals(frames_encoded, frames_to_encode, "frames_encoded");
   assert_equals(frames_decoded, frames_to_encode, "frames_decoded");
+}
+
+promise_test(async t => {
+  return runFullCycleTest(t, {});
 }, 'Encoding and decoding cycle');
 
+promise_test(async t => {
+  if (ENCODER_CONFIG.hasEmbeddedColorSpace)
+    return runFullCycleTest(t, {stripDecoderConfigColorSpace: true});
+}, 'Encoding and decoding cycle w/ stripped color space');
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index b7cf07b3..92790107 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -9529,6 +9529,8 @@
     setter onremovetrack
 interface ViewTimeline : ScrollTimeline
     attribute @@toStringTag
+    getter endOffset
+    getter startOffset
     getter subject
     method constructor
 interface VirtualKeyboard : EventTarget
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js
index 994a4cf3..ee8e7775 100644
--- a/third_party/closure_compiler/externs/accessibility_private.js
+++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -471,8 +471,11 @@
  * Sends a fabricated key event.
  * @param {!chrome.accessibilityPrivate.SyntheticKeyboardEvent} keyEvent The
  *     event to send.
+ * @param {boolean=} useRewriters If true, uses rewriters for the key event;
+ *     only allowed if used from Dictation. Otherwise indicates that rewriters
+ *     should be skipped.
  */
-chrome.accessibilityPrivate.sendSyntheticKeyEvent = function(keyEvent) {};
+chrome.accessibilityPrivate.sendSyntheticKeyEvent = function(keyEvent, useRewriters) {};
 
 /**
  * Enables or disables mouse events in accessibility extensions
diff --git a/third_party/gvr-android-sdk/BUILD.gn b/third_party/gvr-android-sdk/BUILD.gn
index a3f11592..2a6ded8 100644
--- a/third_party/gvr-android-sdk/BUILD.gn
+++ b/third_party/gvr-android-sdk/BUILD.gn
@@ -55,7 +55,12 @@
   if (enable_chrome_android_internal && !is_official_build) {
     deps = [ "//clank/third_party/gvr_shim" ]
   } else {
-    library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}_Cr.a"
+    if (use_relative_vtables_abi) {
+      _vtables = "_vtables"
+    } else {
+      _vtables = ""
+    }
+    library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}${_vtables}.a"
     libs += [ library ]
 
     if (libcxx_is_shared) {
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1
new file mode 100644
index 0000000..91e38fb1
--- /dev/null
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1
@@ -0,0 +1 @@
+817acb93424936fbffef3fe76ac3b765de4988a0
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1
new file mode 100644
index 0000000..89d408b
--- /dev/null
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1
@@ -0,0 +1 @@
+de8672ff47439c95d8afffd4bd556af547b3ec1c
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
deleted file mode 100644
index 1fa351c..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-46d431c43591953ba29dc62d01eb5a999a0cde0e
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1
new file mode 100644
index 0000000..2ee9a03d6
--- /dev/null
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1
@@ -0,0 +1 @@
+a08c3591a536382538758d883b433d6e3914758a
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
deleted file mode 100644
index 2df24f2d..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-dfec094416354f624eef6db969a1b65f03cc91ac
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1
new file mode 100644
index 0000000..f7cebdb2
--- /dev/null
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1
@@ -0,0 +1 @@
+cd8523d28b256da836e47e6aae54d16d05a7f1b6
\ No newline at end of file
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium
index 30214b8..16e679c1 100644
--- a/third_party/libvpx/README.chromium
+++ b/third_party/libvpx/README.chromium
@@ -1,8 +1,8 @@
 Name: libvpx
 URL: https://chromium.googlesource.com/webm/libvpx
 Version: v1.12.0
-Date: Tuesday October 18 2022
-Revision: 5245f6e9cb7e6bb68ab45fe4d8b00bc9b16857e1
+Date: Tuesday November 15 2022
+Revision: 605350bd5b68ac47f595d60cc8ef346588e773c0
 CPEPrefix: cpe:/a:webmproject:libvpx:1.12.0
 License: BSD
 License File: source/libvpx/LICENSE
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni
index 5b9e3c981..3c85ec7 100644
--- a/third_party/libvpx/libvpx_srcs.gni
+++ b/third_party/libvpx/libvpx_srcs.gni
@@ -448,6 +448,7 @@
 libvpx_srcs_x86_ssse3 = [
   "//third_party/libvpx/source/libvpx/vp8/encoder/x86/vp8_quantize_ssse3.c",
   "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_frame_scale_ssse3.c",
+  "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_quantize_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_ssse3.c",
@@ -873,7 +874,6 @@
   "//third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm",
   "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm",
   "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_error_sse2.asm",
-  "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_quantize_ssse3_x86_64.asm",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/avg_ssse3_x86_64.asm",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm",
@@ -937,6 +937,7 @@
 libvpx_srcs_x86_64_ssse3 = [
   "//third_party/libvpx/source/libvpx/vp8/encoder/x86/vp8_quantize_ssse3.c",
   "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_frame_scale_ssse3.c",
+  "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_quantize_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_ssse3.c",
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
index c79821f..86bb94c 100644
--- a/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           int16_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             int16_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
diff --git a/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
index c79821f..86bb94c 100644
--- a/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           int16_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             int16_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
index 329ddcb..b38360d 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
@@ -914,7 +914,12 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           int16_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             int16_t* coeff);
+RTCD_EXTERN void (*vpx_hadamard_32x32)(const int16_t* src_diff,
+                                       ptrdiff_t src_stride,
+                                       int16_t* coeff);
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
@@ -3316,6 +3321,9 @@
   vpx_hadamard_16x16 = vpx_hadamard_16x16_c;
   if (flags & HAS_NEON)
     vpx_hadamard_16x16 = vpx_hadamard_16x16_neon;
+  vpx_hadamard_32x32 = vpx_hadamard_32x32_c;
+  if (flags & HAS_NEON)
+    vpx_hadamard_32x32 = vpx_hadamard_32x32_neon;
   vpx_hadamard_8x8 = vpx_hadamard_8x8_c;
   if (flags & HAS_NEON)
     vpx_hadamard_8x8 = vpx_hadamard_8x8_neon;
diff --git a/third_party/libvpx/source/config/linux/arm-neon-highbd/vp9_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon-highbd/vp9_rtcd.h
index 687f13e..f30a478 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-highbd/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon-highbd/vp9_rtcd.h
@@ -146,7 +146,11 @@
                          tran_low_t* output,
                          int stride,
                          int tx_type);
-#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_c
+void vp9_highbd_fht4x4_neon(const int16_t* input,
+                            tran_low_t* output,
+                            int stride,
+                            int tx_type);
+#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_neon
 
 void vp9_highbd_fht8x8_c(const int16_t* input,
                          tran_low_t* output,
diff --git a/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_dsp_rtcd.h
index 056199e..6e1bd4d 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           tran_low_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             tran_low_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
@@ -3530,7 +3533,10 @@
 void vpx_highbd_fdct32x32_c(const int16_t* input,
                             tran_low_t* output,
                             int stride);
-#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_c
+void vpx_highbd_fdct32x32_neon(const int16_t* input,
+                               tran_low_t* output,
+                               int stride);
+#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_neon
 
 void vpx_highbd_fdct32x32_1_c(const int16_t* input,
                               tran_low_t* output,
@@ -3543,7 +3549,10 @@
 void vpx_highbd_fdct32x32_rd_c(const int16_t* input,
                                tran_low_t* output,
                                int stride);
-#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_c
+void vpx_highbd_fdct32x32_rd_neon(const int16_t* input,
+                                  tran_low_t* output,
+                                  int stride);
+#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_neon
 
 void vpx_highbd_fdct4x4_c(const int16_t* input, tran_low_t* output, int stride);
 void vpx_highbd_fdct4x4_neon(const int16_t* input,
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
index c79821f..86bb94c 100644
--- a/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           int16_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             int16_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
diff --git a/third_party/libvpx/source/config/linux/arm64-highbd/vp9_rtcd.h b/third_party/libvpx/source/config/linux/arm64-highbd/vp9_rtcd.h
index 687f13e..f30a478 100644
--- a/third_party/libvpx/source/config/linux/arm64-highbd/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm64-highbd/vp9_rtcd.h
@@ -146,7 +146,11 @@
                          tran_low_t* output,
                          int stride,
                          int tx_type);
-#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_c
+void vp9_highbd_fht4x4_neon(const int16_t* input,
+                            tran_low_t* output,
+                            int stride,
+                            int tx_type);
+#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_neon
 
 void vp9_highbd_fht8x8_c(const int16_t* input,
                          tran_low_t* output,
diff --git a/third_party/libvpx/source/config/linux/arm64-highbd/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm64-highbd/vpx_dsp_rtcd.h
index 056199e..6e1bd4d 100644
--- a/third_party/libvpx/source/config/linux/arm64-highbd/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm64-highbd/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           tran_low_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             tran_low_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
@@ -3530,7 +3533,10 @@
 void vpx_highbd_fdct32x32_c(const int16_t* input,
                             tran_low_t* output,
                             int stride);
-#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_c
+void vpx_highbd_fdct32x32_neon(const int16_t* input,
+                               tran_low_t* output,
+                               int stride);
+#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_neon
 
 void vpx_highbd_fdct32x32_1_c(const int16_t* input,
                               tran_low_t* output,
@@ -3543,7 +3549,10 @@
 void vpx_highbd_fdct32x32_rd_c(const int16_t* input,
                                tran_low_t* output,
                                int stride);
-#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_c
+void vpx_highbd_fdct32x32_rd_neon(const int16_t* input,
+                                  tran_low_t* output,
+                                  int stride);
+#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_neon
 
 void vpx_highbd_fdct4x4_c(const int16_t* input, tran_low_t* output, int stride);
 void vpx_highbd_fdct4x4_neon(const int16_t* input,
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
index c79821f..86bb94c 100644
--- a/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           int16_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             int16_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
diff --git a/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h
index 1405481..8dd07057 100644
--- a/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h
@@ -397,6 +397,16 @@
                           uint16_t* eob_ptr,
                           const int16_t* scan,
                           const int16_t* iscan);
+void vp9_quantize_fp_ssse3(const tran_low_t* coeff_ptr,
+                           intptr_t n_coeffs,
+                           const int16_t* round_ptr,
+                           const int16_t* quant_ptr,
+                           tran_low_t* qcoeff_ptr,
+                           tran_low_t* dqcoeff_ptr,
+                           const int16_t* dequant_ptr,
+                           uint16_t* eob_ptr,
+                           const int16_t* scan,
+                           const int16_t* iscan);
 void vp9_quantize_fp_avx2(const tran_low_t* coeff_ptr,
                           intptr_t n_coeffs,
                           const int16_t* round_ptr,
@@ -428,6 +438,16 @@
                              uint16_t* eob_ptr,
                              const int16_t* scan,
                              const int16_t* iscan);
+void vp9_quantize_fp_32x32_ssse3(const tran_low_t* coeff_ptr,
+                                 intptr_t n_coeffs,
+                                 const int16_t* round_ptr,
+                                 const int16_t* quant_ptr,
+                                 tran_low_t* qcoeff_ptr,
+                                 tran_low_t* dqcoeff_ptr,
+                                 const int16_t* dequant_ptr,
+                                 uint16_t* eob_ptr,
+                                 const int16_t* scan,
+                                 const int16_t* iscan);
 void vp9_quantize_fp_32x32_avx2(const tran_low_t* coeff_ptr,
                                 intptr_t n_coeffs,
                                 const int16_t* round_ptr,
@@ -497,9 +517,13 @@
   if (flags & HAS_AVX2)
     vp9_highbd_quantize_fp_32x32 = vp9_highbd_quantize_fp_32x32_avx2;
   vp9_quantize_fp = vp9_quantize_fp_sse2;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp = vp9_quantize_fp_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp = vp9_quantize_fp_avx2;
   vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_avx2;
   vp9_scale_and_extend_frame = vp9_scale_and_extend_frame_c;
diff --git a/third_party/libvpx/source/config/linux/loongarch/vpx_config.h b/third_party/libvpx/source/config/linux/loongarch/vpx_config.h
index b1b517ce..b8839c2 100644
--- a/third_party/libvpx/source/config/linux/loongarch/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/loongarch/vpx_config.h
@@ -8,8 +8,8 @@
 /* This file automatically generated by configure. Do not edit! */
 #ifndef VPX_CONFIG_H
 #define VPX_CONFIG_H
-#define RESTRICT
-#define INLINE inline
+#define RESTRICT    
+#define INLINE      inline
 #define VPX_ARCH_ARM 0
 #define ARCH_ARM 0
 #define VPX_ARCH_MIPS 0
diff --git a/third_party/libvpx/source/config/linux/ppc64/vpx_config.h b/third_party/libvpx/source/config/linux/ppc64/vpx_config.h
index c5f05c81..2962008 100644
--- a/third_party/libvpx/source/config/linux/ppc64/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/ppc64/vpx_config.h
@@ -8,8 +8,8 @@
 /* This file automatically generated by configure. Do not edit! */
 #ifndef VPX_CONFIG_H
 #define VPX_CONFIG_H
-#define RESTRICT
-#define INLINE inline
+#define RESTRICT    
+#define INLINE      inline
 #define VPX_ARCH_ARM 0
 #define ARCH_ARM 0
 #define VPX_ARCH_MIPS 0
diff --git a/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h
index 1405481..8dd07057 100644
--- a/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h
@@ -397,6 +397,16 @@
                           uint16_t* eob_ptr,
                           const int16_t* scan,
                           const int16_t* iscan);
+void vp9_quantize_fp_ssse3(const tran_low_t* coeff_ptr,
+                           intptr_t n_coeffs,
+                           const int16_t* round_ptr,
+                           const int16_t* quant_ptr,
+                           tran_low_t* qcoeff_ptr,
+                           tran_low_t* dqcoeff_ptr,
+                           const int16_t* dequant_ptr,
+                           uint16_t* eob_ptr,
+                           const int16_t* scan,
+                           const int16_t* iscan);
 void vp9_quantize_fp_avx2(const tran_low_t* coeff_ptr,
                           intptr_t n_coeffs,
                           const int16_t* round_ptr,
@@ -428,6 +438,16 @@
                              uint16_t* eob_ptr,
                              const int16_t* scan,
                              const int16_t* iscan);
+void vp9_quantize_fp_32x32_ssse3(const tran_low_t* coeff_ptr,
+                                 intptr_t n_coeffs,
+                                 const int16_t* round_ptr,
+                                 const int16_t* quant_ptr,
+                                 tran_low_t* qcoeff_ptr,
+                                 tran_low_t* dqcoeff_ptr,
+                                 const int16_t* dequant_ptr,
+                                 uint16_t* eob_ptr,
+                                 const int16_t* scan,
+                                 const int16_t* iscan);
 void vp9_quantize_fp_32x32_avx2(const tran_low_t* coeff_ptr,
                                 intptr_t n_coeffs,
                                 const int16_t* round_ptr,
@@ -497,9 +517,13 @@
   if (flags & HAS_AVX2)
     vp9_highbd_quantize_fp_32x32 = vp9_highbd_quantize_fp_32x32_avx2;
   vp9_quantize_fp = vp9_quantize_fp_sse2;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp = vp9_quantize_fp_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp = vp9_quantize_fp_avx2;
   vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_avx2;
   vp9_scale_and_extend_frame = vp9_scale_and_extend_frame_c;
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h
index 76f408c..c08816d 100644
--- a/third_party/libvpx/source/config/vpx_version.h
+++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@
 #define VERSION_MAJOR 1
 #define VERSION_MINOR 12
 #define VERSION_PATCH 0
-#define VERSION_EXTRA "200-g5245f6e9c"
+#define VERSION_EXTRA "226-g605350bd5"
 #define VERSION_PACKED \
   ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH))
-#define VERSION_STRING_NOSP "v1.12.0-200-g5245f6e9c"
-#define VERSION_STRING " v1.12.0-200-g5245f6e9c"
+#define VERSION_STRING_NOSP "v1.12.0-226-g605350bd5"
+#define VERSION_STRING " v1.12.0-226-g605350bd5"
diff --git a/third_party/libvpx/source/config/win/arm64/vp9_rtcd.h b/third_party/libvpx/source/config/win/arm64/vp9_rtcd.h
index 687f13e..f30a478 100644
--- a/third_party/libvpx/source/config/win/arm64/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/win/arm64/vp9_rtcd.h
@@ -146,7 +146,11 @@
                          tran_low_t* output,
                          int stride,
                          int tx_type);
-#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_c
+void vp9_highbd_fht4x4_neon(const int16_t* input,
+                            tran_low_t* output,
+                            int stride,
+                            int tx_type);
+#define vp9_highbd_fht4x4 vp9_highbd_fht4x4_neon
 
 void vp9_highbd_fht8x8_c(const int16_t* input,
                          tran_low_t* output,
diff --git a/third_party/libvpx/source/config/win/arm64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/arm64/vpx_dsp_rtcd.h
index 056199e..6e1bd4d 100644
--- a/third_party/libvpx/source/config/win/arm64/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/win/arm64/vpx_dsp_rtcd.h
@@ -712,7 +712,10 @@
 void vpx_hadamard_32x32_c(const int16_t* src_diff,
                           ptrdiff_t src_stride,
                           tran_low_t* coeff);
-#define vpx_hadamard_32x32 vpx_hadamard_32x32_c
+void vpx_hadamard_32x32_neon(const int16_t* src_diff,
+                             ptrdiff_t src_stride,
+                             tran_low_t* coeff);
+#define vpx_hadamard_32x32 vpx_hadamard_32x32_neon
 
 void vpx_hadamard_8x8_c(const int16_t* src_diff,
                         ptrdiff_t src_stride,
@@ -3530,7 +3533,10 @@
 void vpx_highbd_fdct32x32_c(const int16_t* input,
                             tran_low_t* output,
                             int stride);
-#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_c
+void vpx_highbd_fdct32x32_neon(const int16_t* input,
+                               tran_low_t* output,
+                               int stride);
+#define vpx_highbd_fdct32x32 vpx_highbd_fdct32x32_neon
 
 void vpx_highbd_fdct32x32_1_c(const int16_t* input,
                               tran_low_t* output,
@@ -3543,7 +3549,10 @@
 void vpx_highbd_fdct32x32_rd_c(const int16_t* input,
                                tran_low_t* output,
                                int stride);
-#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_c
+void vpx_highbd_fdct32x32_rd_neon(const int16_t* input,
+                                  tran_low_t* output,
+                                  int stride);
+#define vpx_highbd_fdct32x32_rd vpx_highbd_fdct32x32_rd_neon
 
 void vpx_highbd_fdct4x4_c(const int16_t* input, tran_low_t* output, int stride);
 void vpx_highbd_fdct4x4_neon(const int16_t* input,
diff --git a/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h
index 1405481..8dd07057 100644
--- a/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h
+++ b/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h
@@ -397,6 +397,16 @@
                           uint16_t* eob_ptr,
                           const int16_t* scan,
                           const int16_t* iscan);
+void vp9_quantize_fp_ssse3(const tran_low_t* coeff_ptr,
+                           intptr_t n_coeffs,
+                           const int16_t* round_ptr,
+                           const int16_t* quant_ptr,
+                           tran_low_t* qcoeff_ptr,
+                           tran_low_t* dqcoeff_ptr,
+                           const int16_t* dequant_ptr,
+                           uint16_t* eob_ptr,
+                           const int16_t* scan,
+                           const int16_t* iscan);
 void vp9_quantize_fp_avx2(const tran_low_t* coeff_ptr,
                           intptr_t n_coeffs,
                           const int16_t* round_ptr,
@@ -428,6 +438,16 @@
                              uint16_t* eob_ptr,
                              const int16_t* scan,
                              const int16_t* iscan);
+void vp9_quantize_fp_32x32_ssse3(const tran_low_t* coeff_ptr,
+                                 intptr_t n_coeffs,
+                                 const int16_t* round_ptr,
+                                 const int16_t* quant_ptr,
+                                 tran_low_t* qcoeff_ptr,
+                                 tran_low_t* dqcoeff_ptr,
+                                 const int16_t* dequant_ptr,
+                                 uint16_t* eob_ptr,
+                                 const int16_t* scan,
+                                 const int16_t* iscan);
 void vp9_quantize_fp_32x32_avx2(const tran_low_t* coeff_ptr,
                                 intptr_t n_coeffs,
                                 const int16_t* round_ptr,
@@ -497,9 +517,13 @@
   if (flags & HAS_AVX2)
     vp9_highbd_quantize_fp_32x32 = vp9_highbd_quantize_fp_32x32_avx2;
   vp9_quantize_fp = vp9_quantize_fp_sse2;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp = vp9_quantize_fp_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp = vp9_quantize_fp_avx2;
   vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c;
+  if (flags & HAS_SSSE3)
+    vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3;
   if (flags & HAS_AVX2)
     vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_avx2;
   vp9_scale_and_extend_frame = vp9_scale_and_extend_frame_c;
diff --git a/tools/android/avd/avd.py b/tools/android/avd/avd.py
index cedec269..73167407 100755
--- a/tools/android/avd/avd.py
+++ b/tools/android/avd/avd.py
@@ -161,6 +161,11 @@
       'disable debug messages from specific parts of the emulator, e.g. '
       'init, snapshot. See "emulator -help-debug-tags" '
       'for a full list of tags.')
+  subparser.add_argument(
+      '--require-fast-start',
+      action='store_true',
+      help='Shortens the start-up timeout. Used by bots to avoid startup '
+      'regressions.')
 
   def start_cmd(args):
     avd_config = avd.AvdConfig(args.avd_config)
@@ -179,7 +184,8 @@
                writable_system=args.writable_system,
                gpu_mode=args.gpu_mode,
                wipe_data=args.wipe_data,
-               debug_tags=debug_tags)
+               debug_tags=debug_tags,
+               require_fast_start=args.require_fast_start)
     print('%s started (pid: %d)' % (str(inst), inst._emulator_proc.pid))
     return 0
 
diff --git a/tools/binary_size/libsupersize/dex_parser.py b/tools/binary_size/libsupersize/dex_parser.py
index 328ab05..4811a0e 100755
--- a/tools/binary_size/libsupersize/dex_parser.py
+++ b/tools/binary_size/libsupersize/dex_parser.py
@@ -13,7 +13,6 @@
 import argparse
 import collections
 import errno
-import itertools
 import os
 import re
 import struct
@@ -77,6 +76,8 @@
 _TypeIdItem = collections.namedtuple('TypeIdItem', 'descriptor_idx')
 _ProtoIdItem = collections.namedtuple(
     'ProtoIdItem', 'shorty_idx,return_type_idx,parameters_off')
+_FieldIdItem = collections.namedtuple('FieldIdItem',
+                                      'class_idx,type_idx,name_idx')
 _MethodIdItem = collections.namedtuple('MethodIdItem',
                                        'type_idx,proto_idx,name_idx')
 _ClassDefItem = collections.namedtuple(
@@ -257,6 +258,13 @@
     super().__init__(reader, offset, size, factory)
 
 
+class _FieldIdItemList(_MemoryItemList):
+  def __init__(self, reader, offset, size):
+    factory = (
+        lambda x: _FieldIdItem(x.NextUShort(), x.NextUShort(), x.NextUInt()))
+    super().__init__(reader, offset, size, factory)
+
+
 class _MethodIdItemList(_MemoryItemList):
   def __init__(self, reader, offset, size):
     factory = (
@@ -350,6 +358,7 @@
       referenced by index in other sections.
     type_id_item_list: _TypeIdItemList containing _TypeIdItems.
     proto_id_item_list: _ProtoIdItemList containing _ProtoIdItems.
+    field_id_item_list: _FieldIdItemList containing _FieldIdItems.
     method_id_item_list: _MethodIdItemList containing _MethodIdItems.
     type_list_item_list: _TypeListItemList containing _TypeListItems.
       _TypeListItems are referenced by their offsets from other DEX items.
@@ -376,6 +385,9 @@
     self.proto_id_item_list = _ProtoIdItemList(self.reader,
                                                self.header.proto_ids_off,
                                                self.header.proto_ids_size)
+    self.field_id_item_list = _FieldIdItemList(self.reader,
+                                               self.header.field_ids_off,
+                                               self.header.field_ids_size)
     self.method_id_item_list = _MethodIdItemList(self.reader,
                                                  self.header.method_ids_off,
                                                  self.header.method_ids_size)
@@ -448,14 +460,13 @@
         (class name, return type, method name, (parameter type, ...)).
     """
     for method_id_item in self.method_id_item_list:
-      class_name_string = self.GetTypeString(method_id_item.type_idx)
-      method_name_string = self.GetString(method_id_item.name_idx)
+      class_name = self.GetTypeString(method_id_item.type_idx)
+      method_name = self.GetString(method_id_item.name_idx)
       proto_id_item = self.proto_id_item_list[method_id_item.proto_idx]
-      return_type_string = self.GetTypeString(proto_id_item.return_type_idx)
+      return_type_name = self.GetTypeString(proto_id_item.return_type_idx)
       parameter_types = self.GetTypeListStringsByOffset(
           proto_id_item.parameters_off)
-      yield (class_name_string, return_type_string, method_name_string,
-             parameter_types)
+      yield (class_name, return_type_name, method_name, parameter_types)
 
   def __repr__(self):
     items = [
@@ -464,6 +475,7 @@
         self.string_data_item_list,
         self.type_id_item_list,
         self.proto_id_item_list,
+        self.field_id_item_list,
         self.method_id_item_list,
         self.type_list_item_list,
         self.class_def_item_list,
@@ -489,35 +501,48 @@
 
 class _DumpStrings(_DumpCommand):
   def Run(self):
-    for string_data_item in self._dexfile.string_data_item_list:
+    for (i, string_data_item) in enumerate(self._dexfile.string_data_item_list):
       # Some strings are likely to be non-ascii (vs. methods/classes).
-      print(string_data_item.data.encode('utf-8'))
+      s = string_data_item.data
+      rep_str = repr(s) if s.isprintable() else s.encode('utf-8')
+      print('string(%08X): %s' % (i, rep_str))
+
+
+class _DumpFields(_DumpCommand):
+  def Run(self):
+    dexfile = self._dexfile
+    for (i, field_id_item) in enumerate(dexfile.field_id_item_list):
+      class_name = dexfile.GetTypeString(field_id_item.class_idx)
+      type_name = dexfile.GetTypeString(field_id_item.type_idx)
+      name = dexfile.GetString(field_id_item.name_idx)
+      print('field(%08x): (class=%s, name=%s, type=%s)' %
+            (i, class_name, name, type_name))
 
 
 class _DumpMethods(_DumpCommand):
   def Run(self):
-    for parts in self._dexfile.IterMethodSignatureParts():
-      class_type, return_type, method_name, parameter_types = parts
-      print('{} {} (return type={}, parameters={})'.format(
-          class_type, method_name, return_type, parameter_types))
+    for (i, parts) in enumerate(self._dexfile.IterMethodSignatureParts()):
+      class_name, return_type_name, method_name, parameter_types = parts
+      print('method(%08x): (class=%s, name=%s, return_type=%s, params=%s)' %
+            (i, class_name, method_name, return_type_name, parameter_types))
 
 
 class _DumpClasses(_DumpCommand):
   def Run(self):
-    for class_item in self._dexfile.class_def_item_list:
-      class_string = self._dexfile.GetTypeString(class_item.class_idx)
-      superclass_string = self._dexfile.GetTypeString(class_item.superclass_idx)
-      interfaces = self._dexfile.GetTypeListStringsByOffset(
-          class_item.interfaces_off)
+    dexfile = self._dexfile
+    fmt = ('class(%08x): (name=%s, superclass=%s, interfaces=%s, ' +
+           'access_flags=%s)')
+    for (i, class_item) in enumerate(dexfile.class_def_item_list):
+      name = dexfile.GetTypeString(class_item.class_idx)
+      superclass_name = dexfile.GetTypeString(class_item.superclass_idx)
+      interfaces = dexfile.GetTypeListStringsByOffset(class_item.interfaces_off)
       access_flags = DexFile.ResolveClassAccessFlags(class_item.access_flags)
-      print('{} (superclass={}, interfaces={}, access_flags={})'.format(
-          class_string, superclass_string, interfaces, access_flags))
+      print(fmt % (i, name, superclass_name, interfaces, access_flags))
 
 
 class _DumpCodes(_DumpCommand):
   def Run(self):
     dexfile = self._dexfile
-
     total_insns_bytes = 0
     total_insns_count = 0
     total_code_bytes = 0
@@ -558,6 +583,7 @@
   cmds = {
       'summary': _DumpSummary,
       'strings': _DumpStrings,
+      'fields': _DumpFields,
       'methods': _DumpMethods,
       'classes': _DumpClasses,
       'codes': _DumpCodes,
@@ -575,8 +601,8 @@
   parser.add_argument('input',
                       help='Input (.dex, .jar, .zip, .aab, .apk) file path.')
   parser.add_argument('item',
-                      choices=('summary', 'strings', 'methods', 'classes',
-                               'codes'),
+                      choices=('summary', 'strings', 'fields', 'methods',
+                               'classes', 'codes'),
                       help='Item to dump',
                       nargs='?',
                       default='summary')
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
index 60684e9..c4fba0f 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -45,8 +45,6 @@
         options_.enable_members_on_stack_check = true;
       } else if (arg == "enable-extra-padding-check") {
         options_.enable_extra_padding_check = true;
-      } else if (arg == "fix-bugs-of-is-considered-abstract") {
-        // This flag is now always enabled. TODO(wangxianzhu): Remove this flag.
       } else {
         llvm::errs() << "Unknown blink-gc-plugin argument: " << arg << "\n";
         return false;
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py
index fb718eb2..320600c8 100755
--- a/tools/clang/scripts/build.py
+++ b/tools/clang/scripts/build.py
@@ -357,6 +357,12 @@
       '-DLLVM_ENABLE_LIBXML2=FORCE_ON',
       '-DLIBXML2_INCLUDE_DIR=' + libxml2_include_dir.replace('\\', '/'),
       '-DLIBXML2_LIBRARIES=' + libxml2_lib.replace('\\', '/'),
+      '-DLIBXML2_LIBRARY=' + libxml2_lib.replace('\\', '/'),
+
+      # This hermetic libxml2 has enough features enabled for lld-link, but not
+      # for the libxml2 usage in libclang. We don't need libxml2 support in
+      # libclang, so just turn that off.
+      '-DCLANG_ENABLE_LIBXML2=NO',
   ]
   extra_cflags = ['-DLIBXML_STATIC']
 
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 920de6ba..b110f90 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -36,7 +36,7 @@
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
 CLANG_REVISION = 'llvmorg-16-init-10467-g1239d37b'
-CLANG_SUB_REVISION = 1
+CLANG_SUB_REVISION = 2
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '16'
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 0641b25..8fa0d8e 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -163,7 +163,6 @@
       'linux-ash-chromium-generator-rel': 'chromeos_with_codecs_release_bot_reclient',
       'linux-cfm-rel': 'linux_cfm_release_bot_reclient',
       'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot_reclient',
-      'linux-chromeos-rel': 'chromeos_with_codecs_with_lacros_release_bot',
       'linux-chromeos-rel': 'chromeos_with_codecs_with_lacros_release_bot_reclient',
       'linux-lacros-builder-rel': 'lacros_on_linux_release_bot_reclient',
       'linux-lacros-dbg': 'lacros_on_linux_debug_bot_reclient',
@@ -1069,6 +1068,7 @@
       'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot',
       'linux-chromeos-inverse-fieldtrials-fyi-rel': 'chromeos_with_codecs_release_trybot_invert_fieldtrials',
       'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot_code_coverage',
+      'linux-chromeos-rel-reclient': 'chromeos_with_codecs_release_trybot_code_coverage_reclient',
       'linux-chromeos-rel-rts': 'chromeos_with_codecs_release_trybot_code_coverage', # should be kept in sync with linux-chromeos-rel
       'linux-lacros-dbg': 'lacros_on_linux_debug_bot',
       'linux-lacros-rel': 'lacros_on_linux_release_trybot',
@@ -1340,7 +1340,6 @@
       'win10_chromium_x64_dbg_ng': 'gpu_tests_debug_bot',
       'win10_chromium_x64_rel_ng': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
       'win10_chromium_x64_rel_ng-inverse-fyi': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
-      'win10_chromium_x64_rel_ng-reclient': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage_reclient',
       'win10_chromium_x64_rel_ng_exp': 'release_trybot',
       'win11-x64-fyi-rel': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
       'win7-rel': 'gpu_tests_release_trybot_x86_resource_allowlisting',
@@ -2294,6 +2293,12 @@
       'use_clang_coverage', 'partial_code_coverage_instrumentation',
     ],
 
+    # Keep in sync with chromeos_with_codecs_release_trybot.
+    'chromeos_with_codecs_release_trybot_code_coverage_reclient': [
+      'chromeos_with_codecs', 'release_trybot_reclient', 'no_symbols', 'also_build_lacros_chrome',
+      'use_clang_coverage', 'partial_code_coverage_instrumentation',
+    ],
+
     'chromeos_with_codecs_release_trybot_invert_fieldtrials': [
       'chromeos_with_codecs', 'release_trybot', 'no_symbols', 'invert_fieldtrials',
     ],
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
index cf890bf..4c26f98 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -331,6 +331,21 @@
       "use_goma": true
     }
   },
+  "linux-chromeos-rel-reclient": {
+    "gn_args": {
+      "also_build_lacros_chrome": true,
+      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
+      "dcheck_always_on": true,
+      "ffmpeg_branding": "ChromeOS",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "symbol_level": 0,
+      "target_os": "chromeos",
+      "use_clang_coverage": true,
+      "use_remoteexec": true
+    }
+  },
   "linux-chromeos-rel-rts": {
     "gn_args": {
       "also_build_lacros_chrome": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.win.json b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
index eb55316..2c27fcc 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.win.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
@@ -248,20 +248,6 @@
       "use_goma": true
     }
   },
-  "win10_chromium_x64_rel_ng-reclient": {
-    "gn_args": {
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "enable_resource_allowlist_generation": false,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "use_clang_coverage": true,
-      "use_remoteexec": true
-    }
-  },
   "win10_chromium_x64_rel_ng_exp": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 48213c71..80e7adc 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -564,6 +564,16 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Accel_Cycle_Same_App">
+  <owner>benbecker@chromium.org</owner>
+  <owner>andp@chromium.org</owner>
+  <owner>nupurjain@chromium.org</owner>
+  <description>
+    Starting a same app window selection cycle by pressing alt-backtick. Only
+    counts the initial alt-backtick, not each step in the cycle.
+  </description>
+</action>
+
 <action name="Accel_Desks_ActivateLeft">
   <owner>afakhry@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/PRESUBMIT.py b/tools/metrics/histograms/PRESUBMIT.py
index aab0a46..39c4080 100644
--- a/tools/metrics/histograms/PRESUBMIT.py
+++ b/tools/metrics/histograms/PRESUBMIT.py
@@ -36,19 +36,6 @@
     results.append(output_api.PresubmitError(error_msg))
 
 
-def GetObsoleteXmlErrors(input_api, output_api, cwd, results):
-  """Validates all histograms in the file are obsolete."""
-  exit_code = input_api.subprocess.call(
-      [input_api.python3_executable, 'validate_obsolete_histograms.py'],
-      cwd=cwd)
-
-  if exit_code != 0:
-    error_msg = (
-        'metadata/obsolete_histograms.xml contains non-obsolete '
-        'histograms, please run validate_obsolete_histograms.py to fix.')
-    results.append(output_api.PresubmitError(error_msg))
-
-
 def GetValidateHistogramsError(input_api, output_api, cwd, results):
   """Validates histograms format and index file."""
   exit_code = input_api.subprocess.call(
@@ -92,14 +79,6 @@
   if 'test_data' in filepath:
     return False
 
-  # If the changed file is obsolete_histograms.xml, validate all histograms
-  # inside are obsolete.
-  if 'obsolete_histograms.xml' in filepath:
-    GetObsoleteXmlErrors(input_api, output_api, cwd, results)
-    # Return false here because we don't need to validate format if users only
-    # change obsolete_histograms.xml.
-    return False
-
   # If the changed file is histograms.xml or histogram_suffixes_list.xml,
   # pretty-print and validate prefix it.
   elif ('histograms.xml' in filepath
@@ -125,7 +104,7 @@
   xml_changed = False
 
   # Only for changed files, do corresponding checks if the file is
-  # histograms.xml, enums.xml or obsolete_histograms.xml.
+  # histograms.xml or enums.xml.
   for file_obj in input_api.AffectedTextFiles():
     is_changed = ValidateSingleFile(
         input_api, output_api, file_obj, cwd, results)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d31e2a14..057103b 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -36614,6 +36614,8 @@
   <int value="1732" label="AUTOTESTPRIVATE_GETLAUNCHERSSEARCHBOXSTATE"/>
   <int value="1733" label="OS_DIAGNOSTICS_RUNSENSITIVESENSORROUTINE"/>
   <int value="1734" label="OS_DIAGNOSTICS_RUNNVMESELFTESTROUTINE"/>
+  <int value="1735" label="AUTOTESTPRIVATE_STARTFRAMECOUNTING"/>
+  <int value="1736" label="AUTOTESTPRIVATE_STOPFRAMECOUNTING"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -37512,7 +37514,7 @@
   <int value="0" label="Approved by parent">
     Request to allow visiting a host was approved by the parent i.e. the parent
     completed the verification flow and selected the (&quot;Approve&quot;
-    button).
+    button). Available on Android.
   </int>
   <int value="1" label="Denied by parent">
     Request to allow visiting a host was denied by the parent, i.e. the parent
@@ -37541,6 +37543,24 @@
   </int>
 </enum>
 
+<enum name="FamilyLinkUserLocalWebApprovalResult">
+  <summary>
+    The result of local web approval request. Reported by the browser once
+    platform specific approval flow finishes and returns the result.
+  </summary>
+  <int value="0" label="Approved">
+    Request was explicitely approved after parent verification.
+  </int>
+  <int value="1" label="Declined">
+    Request was explicitely declined after parent verification.
+  </int>
+  <int value="2" label="Canceled">
+    Request was canceled at any point (before, during or after parent
+    verification).
+  </int>
+  <int value="3" label="Error">An error occured during the request flow.</int>
+</enum>
+
 <enum name="FamilyLinkUserLogSegment">
   <summary>
     Filters family link user metrics into categories of interest. ChromeOS uses
@@ -43189,8 +43209,8 @@
   <int value="50" label="Show Unfollow Succeed Snackbar."/>
   <int value="51" label="Show Unfollow Failed Snackbar."/>
   <int value="52"
-      label="User tapped to go to feed using the snackbar 'go to feed'
-             option."/>
+      label="User tapped to go to Following feed using the snackbar 'go to
+             Following' option."/>
   <int value="53" label="User tapped the Crow button in the context menu."/>
   <int value="54" label="Show First Follow Sheet."/>
   <int value="55"
@@ -43213,6 +43233,9 @@
   <int value="62"
       label="User tapped the follow accelerator which is presented after a
              user taps on a recommendation that is in the feed."/>
+  <int value="63"
+      label="User requested to refresh the Following feed using the
+             post-follow snackbar 'refresh' action."/>
 </enum>
 
 <enum name="FeedUserCommandType">
@@ -49562,8 +49585,6 @@
       label="DataUse.MessageSize.AllServices.Downstream.Unknown.NotCellular"/>
   <int value="-1607339868"
       label="DataUse.MessageSize.AllServices.Upstream.Unknown.NotCellular"/>
-  <int value="-1592177888"
-      label="Bluetooth.MacOS.Errors.DidDiscoverPrimaryServices"/>
   <int value="-1561887015" label="MediaRouter.Cast.Channel.Error"/>
   <int value="-1554891874"
       label="PageLoad.PageTiming.NavigationToFailedProvisionalLoad"/>
@@ -49588,8 +49609,6 @@
   <int value="-1026485441"
       label="UMA.PersistentAllocator.CrashpadMetrics.Errors"/>
   <int value="-983723378" label="RendererScheduler.TaskDurationPerThreadType"/>
-  <int value="-970685679"
-      label="Bluetooth.MacOS.Errors.DidDiscoverDescriptors"/>
   <int value="-968816650"
       label="PasswordManager.Android.PasswordExceptionEntry.Website"/>
   <int value="-919977005" label="DevTools.DeveloperResourceLoaded"/>
@@ -49605,7 +49624,6 @@
   <int value="-657514887" label="DataUse.MessageSize.AllServices"/>
   <int value="-535820174"
       label="DataUse.MessageSize.AllServices.Downstream.Background.NotCellular"/>
-  <int value="-453454441" label="Bluetooth.MacOS.Errors.DidWriteValue"/>
   <int value="-445016785" label="Crashpad.ExceptionEncountered"/>
   <int value="-436781330"
       label="Net.URLLoaderThrottleExecutionTime.BeforeWillProcessResponse"/>
@@ -49651,8 +49669,6 @@
       label="Android.WebView.ComponentUpdater.CUSDirectorySize"/>
   <int value="628921860"
       label="Network.Shill.Ethernet.LinkMonitorResponseTimeSample"/>
-  <int value="656165878"
-      label="Bluetooth.MacOS.Errors.DidDiscoverCharacteristics"/>
   <int value="657786774" label="PartitionAlloc.CommittedSize"/>
   <int value="662206917"
       label="Network.Shill.Ethernet.ExpiredLeaseLengthSeconds"/>
@@ -49715,8 +49731,6 @@
   <int value="2050720559" label="LocalStorage.MojoTimeToPrime"/>
   <int value="2057863428"
       label="UMA.PersistentAllocator.BrowserMetrics.UsedPct"/>
-  <int value="2060836318"
-      label="Bluetooth.MacOS.Errors.DidDisconnectPeripheral"/>
   <int value="2147480259" label="Sqlite.Vfs_Fetch"/>
 </enum>
 
@@ -62158,6 +62172,8 @@
   <int value="410400234" label="WebAppEnableProtocolHandlers:disabled"/>
   <int value="411250226" label="AutoplayMutedVideos:disabled"/>
   <int value="411536809" label="AutofillAcrossIframes:enabled"/>
+  <int value="412185345"
+      label="DownloadServiceForegroundSessionIOSFeature:enabled"/>
   <int value="412957264" label="tab-close-buttons-hidden-with-touch"/>
   <int value="413062443" label="MessagesForAndroidInfrastructure:disabled"/>
   <int value="413081240" label="enable-new-md-input-view"/>
@@ -64828,6 +64844,8 @@
   <int value="2008878342" label="TouchToFillAndroid:disabled"/>
   <int value="2009097351" label="memlog-sampling-rate"/>
   <int value="2009362691" label="AllowStartingServiceManagerOnly:enabled"/>
+  <int value="2009697597"
+      label="DownloadServiceForegroundSessionIOSFeature:disabled"/>
   <int value="2013593624"
       label="HappinessTrackingSurveysForDesktopDemo:enabled"/>
   <int value="2014331873" label="NTPDownloadSuggestions:disabled"/>
@@ -65757,44 +65775,6 @@
   </int>
 </enum>
 
-<enum name="MacOSBluetoothOperationsResult">
-  <int value="-2" label="Unknown error domain"/>
-  <int value="-1" label="No error"/>
-  <int value="0" label="CBATTErrorSuccess"/>
-  <int value="1" label="CBATTErrorInvalidHandle"/>
-  <int value="2" label="CBATTErrorReadNotPermitted"/>
-  <int value="3" label="CBATTErrorWriteNotPermitted"/>
-  <int value="4" label="CBATTErrorInvalidPdu"/>
-  <int value="5" label="CBATTErrorInsufficientAuthentication"/>
-  <int value="6" label="CBATTErrorRequestNotSupported"/>
-  <int value="7" label="CBATTErrorInvalidOffset"/>
-  <int value="8" label="CBATTErrorInsufficientAuthorization"/>
-  <int value="9" label="CBATTErrorPrepareQueueFull"/>
-  <int value="10" label="CBATTErrorAttributeNotFound"/>
-  <int value="11" label="CBATTErrorAttributeNotLong"/>
-  <int value="12" label="CBATTErrorInsufficientEncryptionKeySize"/>
-  <int value="13" label="CBATTErrorInvalidAttributeValueLength"/>
-  <int value="14" label="CBATTErrorUnlikelyError"/>
-  <int value="15" label="CBATTErrorInsufficientEncryption"/>
-  <int value="16" label="CBATTErrorUnsupportedGroupType"/>
-  <int value="17" label="CBATTErrorInsufficientResources"/>
-  <int value="999" label="Unknown CBATTError code"/>
-  <int value="1000" label="CBErrorUnknown"/>
-  <int value="1001" label="CBErrorInvalidParameters"/>
-  <int value="1002" label="CBErrorInvalidHandle"/>
-  <int value="1003" label="CBErrorNotConnected"/>
-  <int value="1004" label="CBErrorOutOfSpace"/>
-  <int value="1005" label="CBErrorOperationCancelled"/>
-  <int value="1006" label="CBErrorConnectionTimeout"/>
-  <int value="1007" label="CBErrorPeripheralDisconnected"/>
-  <int value="1008" label="CBErrorUUIDNotAllowed"/>
-  <int value="1009" label="CBErrorAlreadyAdvertising"/>
-  <int value="1010" label="CBErrorConnectionFailed"/>
-  <int value="1011" label="CBErrorConnectionLimitReached"/>
-  <int value="1012" label="CBErrorUnknownDevice"/>
-  <int value="1999" label="Unknown CBError code"/>
-</enum>
-
 <enum name="MacThermalState">
   <int value="0" label="0-Nominal"/>
   <int value="1" label="1-Fair"/>
@@ -96432,6 +96412,11 @@
   <int value="2054" label="rsa_pss_sha512"/>
 </enum>
 
+<enum name="SSLSubresourceResponseType">
+  <int value="0" label="IGNORED_MESSAGE"/>
+  <int value="1" label="PROCESSED_MESSAGE"/>
+</enum>
+
 <enum name="SSLVersionInterferenceDetails">
   <obsolete>
     Removed April 2018.
diff --git a/tools/metrics/histograms/histogram_paths.py b/tools/metrics/histograms/histogram_paths.py
index 393a092b..dd5d399 100755
--- a/tools/metrics/histograms/histogram_paths.py
+++ b/tools/metrics/histograms/histogram_paths.py
@@ -37,10 +37,7 @@
 # of module import.
 HISTOGRAMS_XMLS_RELATIVE = (['tools/metrics/histograms/histograms.xml'] +
                             _FindHistogramsXmlFiles())
-OBSOLETE_XML_RELATIVE = ('tools/metrics/histograms/metadata/'
-                         'obsolete_histograms.xml')
-ALL_XMLS_RELATIVE = [ENUMS_XML_RELATIVE, OBSOLETE_XML_RELATIVE
-                     ] + HISTOGRAMS_XMLS_RELATIVE
+ALL_XMLS_RELATIVE = [ENUMS_XML_RELATIVE] + HISTOGRAMS_XMLS_RELATIVE
 
 HISTOGRAMS_PREFIX_LIST = [
     os.path.basename(os.path.dirname(f)) for f in HISTOGRAMS_XMLS_RELATIVE
@@ -49,7 +46,6 @@
 ENUMS_XML = path_util.GetInputFile(ENUMS_XML_RELATIVE)
 UKM_XML = path_util.GetInputFile('tools/metrics/ukm/ukm.xml')
 HISTOGRAMS_XMLS = [path_util.GetInputFile(f) for f in HISTOGRAMS_XMLS_RELATIVE]
-OBSOLETE_XML = path_util.GetInputFile(OBSOLETE_XML_RELATIVE)
 ALL_XMLS = [path_util.GetInputFile(f) for f in ALL_XMLS_RELATIVE]
 
 ALL_TEST_XMLS_RELATIVE = [
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index e47d752..5cf0dba 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2457,6 +2457,19 @@
   </token>
 </histogram>
 
+<histogram name="Ash.Float.FloatWindowCountsPerSession" units="windows"
+    expires_after="2023-11-20">
+  <owner>nupurjain@google.com</owner>
+  <owner>shidi@chromium.org</owner>
+  <owner>sammiequon@chromium.org</owner>
+  <summary>
+    The number of floating windows per session, which is from the time a user
+    logs in to the time they log off. This counts how many times any window
+    enters float state. If the same window is floated twice in the same session,
+    it will get recorded twice.
+  </summary>
+</histogram>
+
 <histogram name="Ash.Glanceables.SignoutScreenshotDuration" units="ms"
     expires_after="2023-04-30">
   <owner>jamescook@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index 9a799a1..4ce0ef99 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -1585,36 +1585,6 @@
   </summary>
 </histogram>
 
-<histogram name="Bluetooth.MacOS.Errors{WebBluetoothMacOSAPIs}"
-    enum="MacOSBluetoothOperationsResult" expires_after="2021-01-31">
-  <owner>reillyg@chromium.org</owner>
-  <owner>deviceapi-team@google.com</owner>
-  <summary>
-    Records how many times each macOS GATT error has occured. The results will
-    be used to determine how commun this errors are and if we need to provide
-    better error messages to the users. {WebBluetoothMacOSAPIs}
-  </summary>
-  <token key="WebBluetoothMacOSAPIs">
-    <variant name=".DidDisconnectPeripheral"
-        summary="Disconnected from peripheral"/>
-    <variant name=".DidDiscoverCharacteristics"
-        summary="Discovered characteristics"/>
-    <variant name=".DidDiscoverDescriptors" summary="Discovered descriptors"/>
-    <variant name=".DidDiscoverPrimaryServices"
-        summary="Discovered primary services"/>
-    <variant name=".DidFailToConnectToPeripheral"
-        summary="Failed to connect to peripheral"/>
-    <variant name=".DidUpdateNotificationState"
-        summary="Updated notification state"/>
-    <variant name=".DidUpdateValue" summary="Updated value for characteristic"/>
-    <variant name=".DidUpdateValueForDescriptor"
-        summary="Updated value for descriptor"/>
-    <variant name=".DidWriteValue" summary="Wrote value for characteristic"/>
-    <variant name=".DidWriteValueForDescriptor"
-        summary="Wrote value value for descriptor"/>
-  </token>
-</histogram>
-
 <histogram name="Bluetooth.Mojo.PendingConnectAtShutdown.DurationWaiting"
     units="ms" expires_after="2022-04-21">
   <owner>jonmann@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index b36ee396c..e3dd5f87 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -361,7 +361,7 @@
 </histogram>
 
 <histogram name="Cookie.FirstPartySets.ContextDelayedQueriesCount"
-    units="queries" expires_after="M110">
+    units="queries" expires_after="M115">
   <owner>shuuran@chromium.org</owner>
   <owner>kaustubhag@chromium.org</owner>
   <summary>
@@ -374,7 +374,7 @@
 </histogram>
 
 <histogram name="Cookie.FirstPartySets.ContextMostDelayedQueryDelta" units="ms"
-    expires_after="2023-03-26">
+    expires_after="M115">
   <owner>shuuran@chromium.org</owner>
   <owner>kaustubhag@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/families/histograms.xml b/tools/metrics/histograms/metadata/families/histograms.xml
index ba0720e1b..6a965131 100644
--- a/tools/metrics/histograms/metadata/families/histograms.xml
+++ b/tools/metrics/histograms/metadata/families/histograms.xml
@@ -219,8 +219,19 @@
   <owner>cros-families-eng@google.com</owner>
   <summary>
     The different outcomes that a user may come accross the local web approval
-    flow. Currently available on Android only (as the Chrome OS implementation
-    is not yet available).
+    flow. Available on Android only.
+  </summary>
+</histogram>
+
+<histogram name="FamilyLinkUser.LocalWebApprovalResult"
+    enum="FamilyLinkUserLocalWebApprovalResult" expires_after="2023-03-26">
+  <owner>agawronska@chromium.org</owner>
+  <owner>cros-families-eng@google.com</owner>
+  <owner>chrome-kids-eng@google.com</owner>
+  <summary>
+    Records the result of local web approval request on ChromeOS and Android.
+    Reported by the browser once platform specific approval flow finishes and
+    returns the result.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index ead4cd2d..1b3c512 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -22,14 +22,6 @@
 
 <histogram_suffixes_list>
 
-<histogram_suffixes name="AccessibilityScreenReaderImage" separator=".">
-  <suffix name="ExplicitlyUnlabeled" label="explicitly unlabeled image"/>
-  <suffix name="Labeled" label="labeled image"/>
-  <suffix name="Unlabeled" label="unlabeled image"/>
-  <affected-histogram name="Accessibility.ScreenReader.Image.MinSize"/>
-  <affected-histogram name="Accessibility.ScreenReader.Image.SizeRatio"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="AccessorySheetType" separator=".">
   <suffix name="Addresses" label="Address suggestions."/>
   <suffix name="CreditCards" label="Payment suggestions."/>
@@ -69,17 +61,6 @@
   <affected-histogram name="Privacy.AccuracyTip.NumDialogsShown"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ActiveNetworkState" separator="_">
-  <suffix name="Offline"
-      label="network manager thinks that the active network is offline"/>
-  <suffix name="Online"
-      label="network manager thinks that the active network is online"/>
-  <suffix name="RestrictedPool"
-      label="network manager thinks that the active network is behind portal"/>
-  <affected-histogram name="CaptivePortal.OOBE.DiscrepancyWithShill"/>
-  <affected-histogram name="CaptivePortal.Session.DiscrepancyWithShill"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ActivityType" separator=".">
   <suffix name="CustomTabs" label="CustomTabs"/>
   <suffix name="TabbedMode" label="TabbedMode"/>
@@ -124,9 +105,7 @@
       label="Resources identified by any mime type that did match any
              supported css, html, image, javascript, or video mime types."/>
   <suffix name="Video" label="Resources identified by video/*."/>
-  <affected-histogram name="Ads.ResourceUsage.Size.Cache.Mime"/>
   <affected-histogram name="Ads.ResourceUsage.Size.Cache2.Mime"/>
-  <affected-histogram name="Ads.ResourceUsage.Size.Mime"/>
   <affected-histogram name="Ads.ResourceUsage.Size.Network.Mime"/>
 </histogram_suffixes>
 
@@ -141,7 +120,6 @@
   <suffix name="Subframe.AdResource" label="Subframe resources tagged as ads."/>
   <suffix name="Subframe.VanillaResource"
       label="Subframe resources not tagged as ads."/>
-  <affected-histogram name="Ads.ResourceUsage.Size.Cache"/>
   <affected-histogram name="Ads.ResourceUsage.Size.Cache2"/>
   <affected-histogram name="Ads.ResourceUsage.Size.Network"/>
 </histogram_suffixes>
@@ -260,8 +238,6 @@
       label="Only includes ad frames that have a display != none style and
              have an area greater than 16 pixels."/>
   <affected-histogram
-      name="PageLoad.AdPaintTiming.NavigationToFirstContentfulPaint"/>
-  <affected-histogram
       name="PageLoad.AdPaintTiming.NavigationToFirstContentfulPaint3"/>
   <affected-histogram name="PageLoad.Bytes"/>
   <affected-histogram name="PageLoad.Cpu"/>
@@ -272,64 +248,18 @@
   <affected-histogram
       name="PageLoad.FrameCounts.AdFrames.PerFrame.OriginStatus"/>
   <affected-histogram
-      name="PageLoad.FrameCounts.AdFrames.PerFrame.SizeIntervention"/>
-  <affected-histogram
-      name="PageLoad.FrameCounts.AdFrames.PerFrame.SizeIntervention.MediaStatus"/>
-  <affected-histogram
-      name="PageLoad.FrameCounts.AdFrames.PerFrame.SmallestDimension"/>
-  <affected-histogram
-      name="PageLoad.FrameCounts.AdFrames.PerFrame.SqrtNumberOfPixels"/>
-  <affected-histogram
       name="PageLoad.FrameCounts.AdFrames.PerFrame.UserActivation"/>
   <affected-histogram name="PageLoad.FrameCounts.AdFrames.Total"/>
-  <affected-histogram name="PageLoad.FrameCounts.AnyParentFrame.AdFrames"/>
-  <affected-histogram name="PageLoad.HeavyAds.ComputedType"/>
   <affected-histogram name="PageLoad.HeavyAds.ComputedTypeWithThresholdNoise"/>
-  <affected-histogram name="PageLoad.HeavyAds.InterventionType"/>
   <affected-histogram name="PageLoad.HeavyAds.InterventionType2"/>
   <affected-histogram name="PageLoad.Memory.Aggregate.Max"/>
   <affected-histogram name="PageLoad.Memory.PerFrame.Max"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="AffiliationDummyData" separator=".">
-  <suffix name="OnStartup"
-      label="with the dummy data being requested shortly after start-up"/>
-  <suffix name="Periodic"
-      label="with the dummy data being requested periodically later"/>
-  <affected-histogram
-      name="PasswordManager.AffiliationDummyData.RequestResultCount"/>
-  <affected-histogram
-      name="PasswordManager.AffiliationDummyData.RequestSuccess"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="AlternateProtocol" separator="_">
-  <suffix name="AlternateProtocol_http"
-      label="(with alternate protocol available and spdy is used"/>
-  <suffix name="AlternateProtocol_spdy"
-      label="with alternate protocol available but http is used"/>
-  <affected-histogram name="PLT.StartToCommit_LinkLoadNormal"/>
-  <affected-histogram name="PLT.StartToCommit_NormalLoad"/>
-  <affected-histogram name="PLT.StartToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.StartToFinish_NormalLoad"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="AnchorElementMetrics" separator="." ordering="prefix">
   <suffix name="Clicked" label="Clicked by the user, on click"/>
   <suffix name="Visible" label="Intersects with the viewport, on page load"/>
-  <affected-histogram name="AnchorElementMetrics.ContainsImage"/>
-  <affected-histogram name="AnchorElementMetrics.DocumentEngagementScore"/>
-  <affected-histogram name="AnchorElementMetrics.HrefEngagementScore2"/>
-  <affected-histogram name="AnchorElementMetrics.HrefEngagementScoreExternal"/>
-  <affected-histogram name="AnchorElementMetrics.IsInIFrame"/>
   <affected-histogram name="AnchorElementMetrics.IsSameHost"/>
-  <affected-histogram name="AnchorElementMetrics.IsUrlIncrementedByOne"/>
-  <affected-histogram name="AnchorElementMetrics.RatioArea"/>
-  <affected-histogram
-      name="AnchorElementMetrics.RatioDistanceCenterToVisibleTop"/>
-  <affected-histogram name="AnchorElementMetrics.RatioDistanceRootBottom"/>
-  <affected-histogram name="AnchorElementMetrics.RatioDistanceRootTop"/>
-  <affected-histogram name="AnchorElementMetrics.RatioDistanceTopToVisibleTop"/>
-  <affected-histogram name="AnchorElementMetrics.RatioVisibleArea"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="AndroidBootTypes" separator=".">
@@ -359,10 +289,8 @@
   <suffix name="PendingDownload"
       label="Duration between request and download start"/>
   <affected-histogram name="Android.FeatureModules.CachedAwakeInstallDuration"/>
-  <affected-histogram name="Android.FeatureModules.CachedInstallDuration"/>
   <affected-histogram
       name="Android.FeatureModules.UncachedAwakeInstallDuration"/>
-  <affected-histogram name="Android.FeatureModules.UncachedInstallDuration"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="AndroidFeatureModuleName" separator=".">
@@ -392,13 +320,6 @@
       name="Android.FeatureModules.CachedAwakeInstallDuration.Installing"/>
   <affected-histogram
       name="Android.FeatureModules.CachedAwakeInstallDuration.PendingDownload"/>
-  <affected-histogram name="Android.FeatureModules.CachedInstallDuration"/>
-  <affected-histogram
-      name="Android.FeatureModules.CachedInstallDuration.Download"/>
-  <affected-histogram
-      name="Android.FeatureModules.CachedInstallDuration.Installing"/>
-  <affected-histogram
-      name="Android.FeatureModules.CachedInstallDuration.PendingDownload"/>
   <affected-histogram name="Android.FeatureModules.InstallingStatus"/>
   <affected-histogram name="Android.FeatureModules.InstallStatus"/>
   <affected-histogram
@@ -409,13 +330,6 @@
       name="Android.FeatureModules.UncachedAwakeInstallDuration.Installing"/>
   <affected-histogram
       name="Android.FeatureModules.UncachedAwakeInstallDuration.PendingDownload"/>
-  <affected-histogram name="Android.FeatureModules.UncachedInstallDuration"/>
-  <affected-histogram
-      name="Android.FeatureModules.UncachedInstallDuration.Download"/>
-  <affected-histogram
-      name="Android.FeatureModules.UncachedInstallDuration.Installing"/>
-  <affected-histogram
-      name="Android.FeatureModules.UncachedInstallDuration.PendingDownload"/>
   <affected-histogram name="Android.IsolatedSplits.ClassLoaderReplaced"/>
   <affected-histogram name="Android.IsolatedSplits.ContextCreateTime"/>
   <affected-histogram name="Android.IsolatedSplits.PreloadWaitTime"/>
@@ -459,7 +373,6 @@
   <suffix name="HomeFragment" label="This is for the home (default) page."/>
   <suffix name="Unknown"
       label="Unknown Fragment (the histogram may need to be updated)."/>
-  <affected-histogram name="Android.WebView.DevUi.SessionDuration"/>
   <affected-histogram name="Android.WebView.DevUi.SessionDuration2"/>
 </histogram_suffixes>
 
@@ -482,46 +395,6 @@
   <affected-histogram name="AppManagement.AppDetailViews"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="AssistantProactiveSuggestionsShowAttemptByCategory"
-    separator="." ordering="prefix,3">
-  <suffix name="AbortedByDuplicateSuppression"
-      label="The attempt was aborted due to duplicate suppression."/>
-  <suffix name="Success"
-      label="The attempt was successful in being presented to the user."/>
-  <affected-histogram
-      name="Assistant.ProactiveSuggestions.FirstShowAttempt.ByCategory"/>
-  <affected-histogram
-      name="Assistant.ProactiveSuggestions.ReshowAttempt.ByCategory"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="AssistantProactiveSuggestionsShowResultByCategory"
-    separator="." ordering="prefix,3">
-  <suffix name="Click"
-      label="The presentation resulted in a click by the user."/>
-  <suffix name="CloseByContextChange"
-      label="The presentation resulted in being closed due to a change in
-             context."/>
-  <suffix name="CloseByTimeout"
-      label="The presentation resulted in being closed due to timeout."/>
-  <suffix name="CloseByUser"
-      label="The presentation resulted in being closed by the user."/>
-  <suffix name="Teleport"
-      label="The presentation resulted in teleportation directly to a single
-             result."/>
-  <affected-histogram
-      name="Assistant.ProactiveSuggestions.FirstShowResult.ByCategory"/>
-  <affected-histogram
-      name="Assistant.ProactiveSuggestions.ReshowResult.ByCategory"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="AsyncSlowStart" separator="_">
-  <suffix name="AsyncSlowStart" label="Async Slow Start on"/>
-  <suffix name="AsyncSlowStart_off" label="Async Slow Start off"/>
-  <suffix name="AsyncSlowStart_on" label="Async Slow Start on"/>
-  <affected-histogram name="Net.Transaction_Connected_New"/>
-  <affected-histogram name="Renderer4.StartToFinish"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="AttestationOps" separator=".">
   <suffix name="ActivateAttestationKey" label=""/>
   <suffix name="AttestationVerify" label=""/>
@@ -531,31 +404,6 @@
   <affected-histogram name="Hwsec.Attestation.Status"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="AudioLatency" separator=".">
-  <suffix name="LatencyExactMs" label="Exact latency in milliseconds"/>
-  <suffix name="LatencyInteractive" label="Interactive latency"/>
-  <suffix name="LatencyPlayback" label="Playback latency"/>
-  <suffix name="LatencyRtc" label="RTC latency"/>
-  <affected-histogram name="Media.Audio.Render.BrowserCallbackRegularity"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="AudioSystemInfoRequest" separator=".">
-  <suffix name="GetAssociatedOutputDeviceID"
-      label="SystemInfo::GetAssociatedOutputDeviceID()"/>
-  <suffix name="GetInputDeviceDescriptions"
-      label="SystemInfo::GetInputDeviceDescriptions()"/>
-  <suffix name="GetInputDeviceInfo" label="SystemInfo::GetInputDeviceInfo()"/>
-  <suffix name="GetInputStreamParameters"
-      label="SystemInfo::GetInputStreamParameters()"/>
-  <suffix name="GetOutputDeviceDescriptions"
-      label="SystemInfo::GetOutputDeviceDescriptions()"/>
-  <suffix name="GetOutputStreamParameters"
-      label="SystemInfo::GetOutputStreamParameters()"/>
-  <suffix name="HasInputDevices" label="SystemInfo::HasInputDevices()"/>
-  <suffix name="HasOutputDevices" label="SystemInfo::HasOutputDevices()"/>
-  <affected-histogram name="Media.AudioService.SystemInfoClient"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="AutofillAddressFormType" separator=".">
   <suffix name="AddressOnly" label="Form has address and maybe name fields"/>
   <suffix name="AddressPlusContact"
@@ -582,9 +430,6 @@
   <suffix name="Local" label="Local"/>
   <suffix name="Server" label="Server (Google Payments)"/>
   <affected-histogram name="Autofill.DaysSinceLastUse.StoredCreditCard"/>
-  <affected-histogram name="Autofill.SaveCardReachedPersonalDataManager"/>
-  <affected-histogram name="Autofill.SaveCardWithFirstAndLastNameComplete"/>
-  <affected-histogram name="Autofill.SaveCardWithFirstAndLastNameOffered"/>
   <affected-histogram name="Autofill.StoredCreditCardCount"/>
   <affected-histogram name="Autofill.StoredCreditCardDisusedCount"/>
 </histogram_suffixes>
@@ -596,12 +441,6 @@
   <affected-histogram name="Autofill.FormEvents.CreditCard"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="AutofillPayloadCompressionType" separator=".">
-  <suffix name="Query" label="Query request compression"/>
-  <suffix name="Upload" label="Upload request compression"/>
-  <affected-histogram name="Autofill.PayloadCompressionRatio"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="AutofillSaveCreditCardPromptFromDynamicChangeForm"
     separator=".">
   <suffix name="FromDynamicChangeForm"
@@ -712,7 +551,6 @@
   <affected-histogram name="Autofill.DaysSinceLastUse.StoredCreditCard.Server"/>
   <affected-histogram name="Autofill.StoredCreditCardCount.Server"/>
   <affected-histogram name="Autofill.StoredCreditCardDisusedCount.Server"/>
-  <affected-histogram name="Autofill.StoredServerCreditCardCount"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="AutofillSyncState" separator=".">
@@ -764,19 +602,10 @@
   <affected-histogram name="Autofill.UnmaskPrompt.TimeBeforeAbandonUnmasking"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="AutofillWalletCardsDiff" separator=".">
-  <suffix name="Added" label="Added"/>
-  <suffix name="AddedOrRemoved" label="Added or removed"/>
-  <suffix name="Removed" label="Removed"/>
-  <affected-histogram name="Autofill.WalletAddresses2"/>
-  <affected-histogram name="Autofill.WalletCards2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="BackgroundDownload" separator=".">
   <suffix name="BackgroundDownload"
       label="Download that started in background."/>
   <affected-histogram name="Download.HttpResponseCode"/>
-  <affected-histogram name="Download.MapErrorNetworkFailed.NetworkService"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="BadBlockCounts" separator=".">
@@ -822,42 +651,6 @@
   <affected-histogram name="WebRTC.Stun.BatchSuccessPercent.UnknownNAT"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="BlinkCanvasOffscreenCommitType" separator=".">
-  <suffix name="GPUCanvasGPUCompositingMain" label=""/>
-  <suffix name="GPUCanvasGPUCompositingWorker" label=""/>
-  <suffix name="GPUCanvasSoftwareCompositingMain" label=""/>
-  <suffix name="GPUCanvasSoftwareCompositingWorker" label=""/>
-  <suffix name="SoftwareCanvasGPUCompositingMain" label=""/>
-  <suffix name="SoftwareCanvasGPUCompositingWorker" label=""/>
-  <suffix name="SoftwareCanvasSoftwareCompositingMain" label=""/>
-  <suffix name="SoftwareCanvasSoftwareCompositingWorker" label=""/>
-  <affected-histogram name="Blink.Canvas.OffscreenCommitTimer"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="BlinkGCReason" separator="_">
-  <suffix name="ConservativeGC" label="Conservative GC"/>
-  <suffix name="ForcedGC" label="Forced GC"/>
-  <suffix name="IdleGC" label="Idle GC"/>
-  <suffix name="IncrementalIdleGC" label="Idle GC with incremental marking"/>
-  <suffix name="IncrementalV8FollowupGC"
-      label="V8 follow-up GC with incremental marking"/>
-  <suffix name="MemoryPressureGC" label="Memory pressure GC"/>
-  <suffix name="PageNavigationGC" label="Page navigation GC"/>
-  <suffix name="PreciseGC" label="Precise GC"/>
-  <suffix name="Testing" label="Testing GC"/>
-  <suffix name="ThreadTerminationGC" label="Thread termination GC"/>
-  <suffix name="UnifiedHeapGC" label="Unified heap GC"/>
-  <affected-histogram name="BlinkGC.AtomicPhaseMarking"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" separator=".">
-  <suffix name="1msTo5ms" label="Ratio when main frame between 1ms and 5ms."/>
-  <suffix name="LessThan1ms" label="Ratio when main frame shorter than 1ms."/>
-  <suffix name="MoreThan5ms" label="Ratio when main frame longer than 5ms."/>
-  <affected-histogram name="Blink.MainFrame.ProxyCommitRatio"/>
-  <affected-histogram name="Blink.MainFrame.StyleAndLayoutRatio"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="BlinkUpdateTimeAggregatedSuffixes" separator=".">
   <suffix name="AggregatedPreFCP"
       label="All the time spent Pre First Contentful Paint in this component"/>
@@ -865,7 +658,6 @@
   <affected-histogram
       name="Blink.AnchorElementMetricsIntersectionObserver.UpdateTime"/>
   <affected-histogram name="Blink.Animate.UpdateTime"/>
-  <affected-histogram name="Blink.Compositing.UpdateTime"/>
   <affected-histogram name="Blink.CompositingCommit.UpdateTime"/>
   <affected-histogram name="Blink.CompositingInputs.UpdateTime"/>
   <affected-histogram name="Blink.ContentDocumentUpdate.UpdateTime"/>
@@ -888,11 +680,9 @@
   <affected-histogram name="Blink.Paint.UpdateTime"/>
   <affected-histogram name="Blink.ParseStyleSheet.UpdateTime"/>
   <affected-histogram name="Blink.PrePaint.UpdateTime"/>
-  <affected-histogram name="Blink.ProxyCommit.UpdateTime"/>
   <affected-histogram name="Blink.ScrollDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.ServiceDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.Style.UpdateTime"/>
-  <affected-histogram name="Blink.StyleAndLayout.UpdateTime"/>
   <affected-histogram name="Blink.UpdateViewportIntersection.UpdateTime"/>
   <affected-histogram name="Blink.UserDrivenDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.WaitForCommit.UpdateTime"/>
@@ -904,7 +694,6 @@
   <affected-histogram
       name="Blink.AnchorElementMetricsIntersectionObserver.UpdateTime"/>
   <affected-histogram name="Blink.Animate.UpdateTime"/>
-  <affected-histogram name="Blink.Compositing.UpdateTime"/>
   <affected-histogram name="Blink.CompositingCommit.UpdateTime"/>
   <affected-histogram name="Blink.CompositingInputs.UpdateTime"/>
   <affected-histogram name="Blink.ContentDocumentUpdate.UpdateTime"/>
@@ -927,11 +716,9 @@
   <affected-histogram name="Blink.Paint.UpdateTime"/>
   <affected-histogram name="Blink.ParseStyleSheet.UpdateTime"/>
   <affected-histogram name="Blink.PrePaint.UpdateTime"/>
-  <affected-histogram name="Blink.ProxyCommit.UpdateTime"/>
   <affected-histogram name="Blink.ScrollDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.ServiceDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.Style.UpdateTime"/>
-  <affected-histogram name="Blink.StyleAndLayout.UpdateTime"/>
   <affected-histogram name="Blink.UpdateViewportIntersection.UpdateTime"/>
   <affected-histogram name="Blink.UserDrivenDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.WaitForCommit.UpdateTime"/>
@@ -943,7 +730,6 @@
   <affected-histogram
       name="Blink.AnchorElementMetricsIntersectionObserver.UpdateTime"/>
   <affected-histogram name="Blink.Animate.UpdateTime"/>
-  <affected-histogram name="Blink.Compositing.UpdateTime"/>
   <affected-histogram name="Blink.CompositingCommit.UpdateTime"/>
   <affected-histogram name="Blink.CompositingInputs.UpdateTime"/>
   <affected-histogram name="Blink.ContentDocumentUpdate.UpdateTime"/>
@@ -966,11 +752,9 @@
   <affected-histogram name="Blink.Paint.UpdateTime"/>
   <affected-histogram name="Blink.ParseStyleSheet.UpdateTime"/>
   <affected-histogram name="Blink.PrePaint.UpdateTime"/>
-  <affected-histogram name="Blink.ProxyCommit.UpdateTime"/>
   <affected-histogram name="Blink.ScrollDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.ServiceDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.Style.UpdateTime"/>
-  <affected-histogram name="Blink.StyleAndLayout.UpdateTime"/>
   <affected-histogram name="Blink.UpdateViewportIntersection.UpdateTime"/>
   <affected-histogram name="Blink.UserDrivenDocumentUpdate.UpdateTime"/>
   <affected-histogram name="Blink.WaitForCommit.UpdateTime"/>
@@ -1052,102 +836,26 @@
   <affected-histogram name="SimpleCache.DiskCreateLatency"/>
   <affected-histogram name="SimpleCache.DiskDoomLatency"/>
   <affected-histogram name="SimpleCache.DiskOpenLatency"/>
-  <affected-histogram name="SimpleCache.DiskOpenStream2NonTinyLatency"/>
-  <affected-histogram name="SimpleCache.DiskOpenStream2TinyLatency"/>
   <affected-histogram name="SimpleCache.DiskWriteLatency"/>
-  <affected-histogram name="SimpleCache.EntryCreatedAndStream2Omitted"/>
-  <affected-histogram name="SimpleCache.EntryCreationResult"/>
   <affected-histogram name="SimpleCache.EntryCreationTime"/>
-  <affected-histogram name="SimpleCache.EntryOpenedAndStream2Removed"/>
-  <affected-histogram name="SimpleCache.EntryOperationsPending"/>
-  <affected-histogram name="SimpleCache.EntryTrailerSize"/>
-  <affected-histogram name="SimpleCache.Eviction.CacheSizeOnStart"/>
   <affected-histogram name="SimpleCache.Eviction.EntryCount"/>
-  <affected-histogram name="SimpleCache.Eviction.MaxCacheSizeOnStart"/>
-  <affected-histogram name="SimpleCache.Eviction.SizeOfEvicted"/>
-  <affected-histogram name="SimpleCache.Eviction.SizeWhenDone"/>
   <affected-histogram name="SimpleCache.Eviction.TimeToDone"/>
   <affected-histogram name="SimpleCache.Eviction.TimeToSelectEntries"/>
-  <affected-histogram name="SimpleCache.GlobalOpenEntryCount"/>
   <affected-histogram name="SimpleCache.HeaderSize"/>
-  <affected-histogram name="SimpleCache.HeaderSizeChange"/>
-  <affected-histogram name="SimpleCache.HeaderSizeDecreaseAbsolute"/>
-  <affected-histogram name="SimpleCache.HeaderSizeDecreasePercentage"/>
-  <affected-histogram name="SimpleCache.HeaderSizeIncreaseAbsolute"/>
-  <affected-histogram name="SimpleCache.HeaderSizeIncreasePercentage"/>
-  <affected-histogram name="SimpleCache.IndexCorrupt"/>
   <affected-histogram name="SimpleCache.IndexCreatedEntryCount"/>
-  <affected-histogram name="SimpleCache.IndexEntriesLoaded"/>
-  <affected-histogram name="SimpleCache.IndexEntriesRestored"/>
   <affected-histogram name="SimpleCache.IndexFileStateOnLoad"/>
-  <affected-histogram name="SimpleCache.IndexInitializationWaiters"/>
   <affected-histogram name="SimpleCache.IndexInitializeMethod"/>
-  <affected-histogram name="SimpleCache.IndexLoadTime"/>
   <affected-histogram name="SimpleCache.IndexNumEntriesOnInit"/>
   <affected-histogram name="SimpleCache.IndexRestoreTime"/>
-  <affected-histogram name="SimpleCache.IndexWriteInterval.Background"/>
-  <affected-histogram name="SimpleCache.IndexWriteInterval.Foreground"/>
-  <affected-histogram name="SimpleCache.IndexWriteToDiskTime.Background"/>
-  <affected-histogram name="SimpleCache.IndexWriteToDiskTime.Foreground"/>
-  <affected-histogram name="SimpleCache.KeyMatchedOnOpen"/>
-  <affected-histogram name="SimpleCache.LastClusterLossPercent"/>
-  <affected-histogram name="SimpleCache.LastClusterSize"/>
   <affected-histogram name="SimpleCache.MaxCacheSizeOnInit"/>
-  <affected-histogram name="SimpleCache.NumOpsBlockedByPendingDoom"/>
   <affected-histogram name="SimpleCache.OpenEntryIndexState"/>
   <affected-histogram
       name="SimpleCache.OriginalConsistencyResultBeforeSuccessfulRetry"/>
-  <affected-histogram name="SimpleCache.QueueLatency.CreateEntry"/>
-  <affected-histogram name="SimpleCache.QueueLatency.OpenEntry"/>
-  <affected-histogram name="SimpleCache.QueueLatency.OpenOrCreateEntry"/>
-  <affected-histogram name="SimpleCache.QueueLatency.PendingDoom"/>
-  <affected-histogram name="SimpleCache.ReadIsParallelizable"/>
-  <affected-histogram name="SimpleCache.ReadResult"/>
-  <affected-histogram name="SimpleCache.ReadStream1FromPrefetched"/>
   <affected-histogram name="SimpleCache.RetryConsistencyResult"/>
   <affected-histogram name="SimpleCache.StaleIndexExtraEntryCount"/>
   <affected-histogram name="SimpleCache.StaleIndexMissedEntryCount"/>
   <affected-histogram name="SimpleCache.StaleIndexQuality"/>
-  <affected-histogram name="SimpleCache.SyncCheckEOFHasCrc"/>
-  <affected-histogram name="SimpleCache.SyncCreateResult"/>
-  <affected-histogram name="SimpleCache.SyncKeySHA256Result"/>
-  <affected-histogram name="SimpleCache.SyncOpenDidPrefetch"/>
-  <affected-histogram name="SimpleCache.SyncOpenEntryAge"/>
   <affected-histogram name="SimpleCache.SyncOpenPrefetchMode"/>
-  <affected-histogram name="SimpleCache.WriteDependencyType"/>
-  <affected-histogram name="SimpleCache.WriteResult"/>
-  <affected-histogram name="SimpleCache.WriteResult2"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="CacheSensitivityHistograms" separator="_">
-  <suffix name="CacheSensitivity" label="Cache Sensivitiy Analysis"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.BeginToFirstPaint"/>
-  <affected-histogram name="PLT.CommitToFirstPaint"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="CacheSensitivityHistograms" separator="_">
-  <suffix name="CacheSensitivity" label="Cache Sensivitiy Analysis"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.BeginToFirstPaint"/>
-  <affected-histogram name="PLT.CommitToFirstPaint"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="CacheThrottle" separator="_">
-  <suffix name="CacheThrottle_Off" label="Control group."/>
-  <suffix name="CacheThrottle_On" label="Throttling payload requests."/>
-  <affected-histogram name="DiskCache.TotalIOTime"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinish_HistoryLoad"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadCacheOnly"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="PLT.BeginToFinish_Reload"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="CancelableTaskTrackerDurationTypes" separator="_">
@@ -1246,15 +954,6 @@
   <affected-histogram name="SoftwareReporter.Cleaner.TimeToCompleteDownload"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ChromeContentBrowserClientMetricSuffixes"
-    separator=".">
-  <suffix name="docs" label="Custom histogram for Google Docs"/>
-  <suffix name="search"
-      label="Custom histogram for the Google Search results page"/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ChromeOS_Camera_JpegProcessMethod" separator=".">
   <suffix name="Hardware" label=""/>
   <suffix name="Software" label=""/>
@@ -1326,60 +1025,11 @@
   <affected-histogram name="ChromeOS.USB.DeviceAttached"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="Clients_StaleWhileRevalidateExperiment" separator="."
-    ordering="prefix">
-  <suffix name="Clients.StaleWhileRevalidateExperiment"
-      label="Timing was recorded on one of the domains of focus for
-             stale-while-revalidate"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstLayout"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstTextPaint"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToLoadEventFired"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="CompositorPendingTreeType" separator=".">
-  <suffix name="Impl" label="Impl side invalidation initiated pending tree"/>
-  <suffix name="Main" label="Commit initiated pending tree"/>
-  <affected-histogram
-      name="Scheduling.Renderer.ReadyToActivateToActivationDuration2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="CompositorTimingHistoryProcess" separator="."
     ordering="prefix">
   <suffix name="Browser" label=""/>
   <suffix name="Renderer" label=""/>
   <affected-histogram name="Scheduling.BeginImplFrameLatency2"/>
-  <affected-histogram name="Scheduling.BeginMainFrameStartToCommitDuration2"/>
-  <affected-histogram
-      name="Scheduling.DrawIntervalWithMainThreadCompositableAnimations2"/>
-  <affected-histogram name="Scheduling.SwapAckWasFast"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="CompositorTimingHistoryProcess2" separator="."
-    ordering="prefix">
-  <suffix name="Browser" label=""/>
-  <suffix name="Renderer" label=""/>
-  <affected-histogram name="Scheduling.ImageInvalidationUpdateDuration"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="ConnCountImpact" separator="_">
-  <suffix name="conn_count_4" label="with 4 persistent connections per host"/>
-  <suffix name="conn_count_5" label="with 5 persistent connections per host"/>
-  <suffix name="conn_count_6" label="with 6 persistent connections per host"/>
-  <suffix name="conn_count_7" label="with 7 persistent connections per host"/>
-  <suffix name="conn_count_8" label="with 8 persistent connections per host"/>
-  <suffix name="conn_count_9" label="with 9 persistent connections per host"/>
-  <suffix name="conn_count_16" label="with 16 persistent connections per host"/>
-  <affected-histogram name="Net.Transaction_Connected_New"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="Renderer4.Abandoned"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="Renderer4.BeginToFinish_NormalLoad"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="ConnectionMigrationCause" separator=".">
@@ -1396,18 +1046,6 @@
   <affected-histogram name="Net.QuicSession.PathValidationSuccess"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ConnnectBackupJobs" separator="_">
-  <suffix name="ConnectBackupJobsDisabled" label=""/>
-  <suffix name="ConnectBackupJobsEnabled" label=""/>
-  <affected-histogram name="Net.PreconnectUtilization"/>
-  <affected-histogram name="Net.PreconnectUtilization2"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="PLT.LoadType"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ContentIndexDatabaseTask" separator=".">
   <suffix name="Add" label="Register content"/>
   <suffix name="ClearCorruptedData" label="Clear data in SW"/>
@@ -1474,7 +1112,6 @@
   <affected-histogram name="NewTabPage.ContentSuggestions.DismissedVisited"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.MenuOpened"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.MenuOpenedAge"/>
-  <affected-histogram name="NewTabPage.ContentSuggestions.MenuOpenedScore"/>
   <affected-histogram
       name="NewTabPage.ContentSuggestions.MenuOpenedScoreNormalized"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.MoreButtonClicked"/>
@@ -1483,12 +1120,10 @@
   <affected-histogram name="NewTabPage.ContentSuggestions.Opened"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.OpenedAge"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.OpenedCategoryIndex"/>
-  <affected-histogram name="NewTabPage.ContentSuggestions.OpenedScore"/>
   <affected-histogram
       name="NewTabPage.ContentSuggestions.OpenedScoreNormalized"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.Shown"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.ShownAge"/>
-  <affected-histogram name="NewTabPage.ContentSuggestions.ShownScore"/>
   <affected-histogram
       name="NewTabPage.ContentSuggestions.ShownScoreNormalized"/>
   <affected-histogram name="NewTabPage.ContentSuggestions.VisitDuration"/>
@@ -1807,7 +1442,6 @@
       label="For tabs in background and not shown to user."/>
   <suffix name="Initial" label="For a tab that is just being created."/>
   <affected-histogram name="Tabs.StateTransfer.Target"/>
-  <affected-histogram name="Tabs.StateTransfer.Time"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="CustomHttpClientType" separator=".">
@@ -1831,178 +1465,6 @@
   <affected-histogram name="CustomTabs.DetachedResourceRequest.RedirectsCount"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="DataReductionProxy_TamperingFingerprints"
-    separator="_">
-  <suffix name="ChromeProxy"
-      label="for each carrier, number of tamperings detected on Chrome-Proxy
-             header"/>
-  <suffix name="CompressionRatio_Image"
-      label="the histogram of compression ratio of images"/>
-  <suffix name="CompressionRatio_Image_0_10KB"
-      label="the histogram of compression ratio of images whose sizes are in
-             the range of 0-10KB"/>
-  <suffix name="CompressionRatio_Image_10_100KB"
-      label="the histogram of compression ratio of images whose sizes are in
-             the range of 10-100KB"/>
-  <suffix name="CompressionRatio_Image_100_500KB"
-      label="the histogram of compression ratio of images whose sizes are in
-             the range of 100-500KB"/>
-  <suffix name="CompressionRatio_Image_500KB"
-      label="the histogram of compression ratio of images whose sizes are
-             larger than 500KB"/>
-  <suffix name="CompressionRatio_Image_GIF"
-      label="the histogram of compression ratio of GIF images"/>
-  <suffix name="CompressionRatio_Image_JPG"
-      label="the histogram of compression ratio of JPG images"/>
-  <suffix name="CompressionRatio_Image_PNG"
-      label="the histogram of compression ratio of PNG images"/>
-  <suffix name="CompressionRatio_Image_WEBP"
-      label="the histogram of compression ratio of WEBP images"/>
-  <suffix name="CompressionRatio_Video"
-      label="the histogram of compression ratio of videos"/>
-  <suffix name="ContentLength"
-      label="for each carrier, total number of responses whose Content-Length
-             header has been tampered with"/>
-  <suffix name="ContentLength_CSS"
-      label="for each carrier, number of CSS responses whose Content-Length
-             header has been tampered with"/>
-  <suffix name="ContentLength_Image"
-      label="for each carrier, number of image responses whose Content-Length
-             header has been tampered with"/>
-  <suffix name="ContentLength_Image_GIF"
-      label="for each carrier, number of GIF image responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_Image_JPG"
-      label="for each carrier, number of JPEG image responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_Image_PNG"
-      label="for each carrier, number of PNG image responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_Image_WEBP"
-      label="for each carrier, number of WebP image responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_JS"
-      label="for each carrier, number of JavaScript responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_Other"
-      label="for each carrier, number of other type responses whose
-             Content-Length header has been tampered with"/>
-  <suffix name="ContentLength_Video"
-      label="for each carrier, number of video responses whose Content-Length
-             header has been tampered with"/>
-  <suffix name="OtherHeaders"
-      label="for each carrier, number of tamperings detected on a list of
-             headers"/>
-  <suffix name="Via"
-      label="for each carrier, number of tamperings detected on Via header"/>
-  <suffix name="Via_Missing"
-      label="for each carrier, number of responses whose data reduction
-             proxy's Via header is missing"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTPS"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="DataReductionProxy_TamperingTotal" separator="_">
-  <suffix name="Total" label="total number of tamperings detected"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP_CSS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_0_10KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_100_500KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_10_100KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_500KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_GIF"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_JPG"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_PNG"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Image_WEBP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP_JS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTP_Video"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS_CSS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_0_10KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_100_500KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_10_100KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_500KB"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_GIF"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_JPG"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_PNG"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Image_WEBP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS_JS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperDetectionHTTPS_Video"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTPS"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTP_ChromeProxy"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_ContentLength"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_ContentLength_CSS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_ContentLength_Image"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_ContentLength_JS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_ContentLength_Other"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTP_OtherHeaders"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTP_Via"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTP_Via_Missing"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ChromeProxy"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ContentLength"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ContentLength_CSS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ContentLength_Image"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ContentLength_JS"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_ContentLength_Other"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_OtherHeaders"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperedHTTPS_Via"/>
-  <affected-histogram
-      name="DataReductionProxy.HeaderTamperedHTTPS_Via_Missing"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="DataReductionProxy_TotalCounts" separator="_">
-  <suffix name="CSS" label="CSS count"/>
-  <suffix name="Image" label="image count"/>
-  <suffix name="Image_0_10KB" label="image counts of 0-10KB"/>
-  <suffix name="Image_10_100KB" label="image counts of 10-100KB"/>
-  <suffix name="Image_100_500KB" label="image counts of 100-500KB"/>
-  <suffix name="Image_500KB" label="image counts of more than 500KB"/>
-  <suffix name="Image_GIF" label="GIF image count"/>
-  <suffix name="Image_JPG" label="JPG image count"/>
-  <suffix name="Image_PNG" label="PNG image count"/>
-  <suffix name="Image_WEBP" label="WEBP image count"/>
-  <suffix name="JS" label="JavaScript count"/>
-  <suffix name="Video" label="Video count"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTP"/>
-  <affected-histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="DataReductionProxyBypassedBytes" separator=".">
   <suffix name="Current" label="Bypass due to explicit instruction"/>
   <suffix name="CurrentApplicationOctetStream"
@@ -2050,37 +1512,6 @@
   <affected-histogram name="DataReductionProxy.BypassedBytes"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="DataReductionProxyRequestCompletionErrorCodes"
-    separator=".">
-  <suffix name="Fallback" label="Fallback data reduction proxy"/>
-  <suffix name="Primary" label="Primary data reduction proxy"/>
-  <affected-histogram name="DataReductionProxy.RequestCompletionErrorCodes"/>
-</histogram_suffixes>
-
-<histogram_suffixes
-    name="DataReductionProxyRequestCompletionErrorCodesMainFrame" separator=".">
-  <suffix name="Fallback" label="Fallback data reduction proxy"/>
-  <suffix name="Primary" label="Primary data reduction proxy"/>
-  <affected-histogram
-      name="DataReductionProxy.RequestCompletionErrorCodes.MainFrame"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="DataUsageReportSubmissionBytes" separator=".">
-  <suffix name="Failed"
-      label="Platform external data use observer reported the submission as
-             failed"/>
-  <suffix name="Lost"
-      label="Lost before it could be submitted to platform external data use
-             observer"/>
-  <suffix name="Successful"
-      label="Platform external data use observer reported the submission as
-             successful"/>
-  <suffix name="TimedOut"
-      label="Submission of the report to the platform external data use
-             observer timed out"/>
-  <affected-histogram name="DataUsage.ReportSubmission.Bytes"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="DataUse_AppTabState_Dimensions" separator=".">
   <suffix name="Downstream.AppBackground" label=""/>
   <suffix name="Downstream.AppForeground.TabBackground" label=""/>
@@ -2122,7 +1553,6 @@
   <suffix name="Upstream.Foreground.NotCellular" label=""/>
   <suffix name="Upstream.Unknown.Cellular" label=""/>
   <suffix name="Upstream.Unknown.NotCellular" label=""/>
-  <affected-histogram name="DataUse.TrafficSize.System"/>
   <affected-histogram name="DataUse.TrafficSize.User"/>
 </histogram_suffixes>
 
@@ -2205,21 +1635,12 @@
   <suffix name="3" label="Experiment group 3 (10% clients)"/>
   <suffix name="4" label="Experiment group 4 (10% clients)"/>
   <affected-histogram name="DiskCache.0.Entries"/>
-  <affected-histogram name="DiskCache.0.MaxSize"/>
-  <affected-histogram name="DiskCache.0.Size"/>
   <affected-histogram name="DiskCache.0.TrimAge"/>
   <affected-histogram name="DiskCache.2.Entries"/>
-  <affected-histogram name="DiskCache.2.MaxSize"/>
-  <affected-histogram name="DiskCache.2.Size"/>
   <affected-histogram name="DiskCache.2.TrimAge"/>
   <affected-histogram name="DiskCache.3.Entries"/>
-  <affected-histogram name="DiskCache.3.MaxSize"/>
   <affected-histogram name="DiskCache.3.Size"/>
   <affected-histogram name="DiskCache.3.TrimAge"/>
-  <affected-histogram name="DiskCache.Entries"/>
-  <affected-histogram name="DiskCache.MaxSize"/>
-  <affected-histogram name="DiskCache.Size"/>
-  <affected-histogram name="DiskCache.TrimAge"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="DiskCacheExperiment2" separator="_">
@@ -2278,35 +1699,6 @@
   <affected-histogram name="DiskCache.2.LargeEntriesRatio"/>
   <affected-histogram name="DiskCache.3.HitRatio"/>
   <affected-histogram name="DiskCache.3.LargeEntriesRatio"/>
-  <affected-histogram name="DiskCache.HitRatio"/>
-  <affected-histogram name="DiskCache.LargeEntriesRatio"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="DiskUsagePerUserCount" separator=".">
-  <suffix name="1User" label="Only 1 user exists on device."/>
-  <suffix name="2Users" label="2 users exist on device."/>
-  <suffix name="3Users" label="3 users exist on device."/>
-  <suffix name="4Users" label="4 users exist on device."/>
-  <suffix name="5Users" label="5 users exist on device."/>
-  <suffix name="6Users" label="6 users exist on device."/>
-  <suffix name="7OrMoreUsers" label="7 or more users exist on device."/>
-  <affected-histogram name="Platform.DiskUsage.Cache_Avg"/>
-  <affected-histogram name="Platform.DiskUsage.Cache_Max"/>
-  <affected-histogram name="Platform.DiskUsage.Downloads_Avg"/>
-  <affected-histogram name="Platform.DiskUsage.Downloads_Max"/>
-  <affected-histogram name="Platform.DiskUsage.GCache_Avg"/>
-  <affected-histogram name="Platform.DiskUsage.GCache_Max"/>
-  <affected-histogram name="Platform.DiskUsage.LeastUsedAccountDays"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="DNS_HostCache_UpdateStale_AddressListDeltaType"
-    separator="_">
-  <suffix name="Disjoint" label="All different addresses."/>
-  <suffix name="Identical" label="Same addresses, in the same order."/>
-  <suffix name="Overlap" label="Some same addreses, some different."/>
-  <suffix name="Reordered" label="Same addresses, in a different order."/>
-  <affected-histogram name="DNS.HostCache.UpdateStale.ExpiredBy"/>
-  <affected-histogram name="DNS.HostCache.UpdateStale.NetworkChanges"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="DnsDropdownSelectionEvent" separator=".">
@@ -2327,75 +1719,7 @@
   <suffix name="parallel_4_prefetch"
       label="DNS pre-resolving was only doing 4 concurrent speculative
              resolutions in this test"/>
-  <affected-histogram name="Net.Dns_Resolution_And_TCP_Connection_Latency"/>
-  <affected-histogram name="Net.TCP_Connection_Idle_Sockets">
-    <with-suffix name="disabled_prefetch"/>
-    <with-suffix name="disabled_prefetch_4_connections"/>
-    <with-suffix name="enabled_prefetch_4_connections"/>
-  </affected-histogram>
   <affected-histogram name="Net.TCP_Connection_Latency"/>
-  <affected-histogram name="Net.Transaction_Connected"/>
-  <affected-histogram name="Net.Transaction_Connected_New"/>
-  <affected-histogram name="Net.Transaction_Connected_New_b"/>
-  <affected-histogram name="Net.Transaction_Connected_Under_10"/>
-  <affected-histogram name="Net.Transaction_Latency"/>
-  <affected-histogram name="Net.Transaction_Latency_b"/>
-  <affected-histogram name="Net.Transaction_Latency_Total"/>
-  <affected-histogram name="Net.Transaction_Latency_Total_New_Connection"/>
-  <affected-histogram
-      name="Net.Transaction_Latency_Total_New_Connection_Under_10"/>
-  <affected-histogram name="Net.Transaction_Latency_Total_Under_10"/>
-  <affected-histogram name="Net.Transaction_Latency_Under_10"/>
-  <affected-histogram name="PLT.RequestToFinish">
-    <with-suffix name="parallel_4_prefetch"/>
-  </affected-histogram>
-</histogram_suffixes>
-
-<histogram_suffixes name="DnsImpact3" separator="_">
-  <suffix name="disabled_prefetch" label="with DNS pre-resolving disabled"/>
-  <suffix name="parallel_4_prefetch"
-      label="with only 4 concurrent speculative resolutions done in parallel"/>
-  <affected-histogram name="Net.Transaction_Connected_New">
-    <with-suffix name="disabled_prefetch"/>
-  </affected-histogram>
-  <affected-histogram name="Renderer2.FinishDocToFinish"/>
-  <affected-histogram name="Renderer2.RequestToFinish"/>
-  <affected-histogram name="Renderer2.RequestToFinish_L">
-    <with-suffix name="disabled_prefetch"/>
-  </affected-histogram>
-  <affected-histogram name="Renderer2.RequestToFirstLayout"/>
-  <affected-histogram name="Renderer2.RequestToStart"/>
-  <affected-histogram name="Renderer2.StartToFinish"/>
-  <affected-histogram name="Renderer2.StartToFinishDoc"/>
-  <affected-histogram name="Renderer2.StartToFirstLayout"/>
-  <affected-histogram name="Renderer4.RequestToFinish">
-    <with-suffix name="parallel_4_prefetch"/>
-  </affected-histogram>
-  <affected-histogram name="Renderer4.StartToFinish">
-    <with-suffix name="parallel_4_prefetch"/>
-  </affected-histogram>
-</histogram_suffixes>
-
-<histogram_suffixes name="DnsParallelism" separator="_">
-  <suffix name="parallel_6"
-      label="with only 6 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_7"
-      label="with only 7 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_8"
-      label="with only 8 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_9"
-      label="with only 9 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_10"
-      label="with only 10 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_14"
-      label="with only 14 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_20"
-      label="with only 20 concurrent resolutions done in parallel"/>
-  <suffix name="parallel_default"
-      label="with the default number of concurrent resolutions done in
-             parallel"/>
-  <affected-histogram name="DNS.ResolveCategory"/>
-  <affected-histogram name="DNS.ResolveSuccess"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="DohProviderId" separator="." ordering="prefix,4">
@@ -2439,12 +1763,6 @@
       name="Net.DNS.DnsTransaction.SecureValidated.SuccessTime"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="DomainGoogle" separator="">
-  <suffix name="Google" label="only Google cookies are recorded."/>
-  <suffix name="Other" label="only NON-Google cookies are recorded."/>
-  <affected-histogram name="Cookie.ReinstatedCookies"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="DOMStorageCachePurgeReason" separator=".">
   <suffix name="AggressivePurgeTriggered"
       label="Aggressive purge was triggered on memory pressure."/>
@@ -2482,10 +1800,7 @@
   <suffix name="OptimizationGuidePredictionModels"
       label="Optimization Guide prediction models."/>
   <suffix name="PluginVmImage" label="PluginVm image."/>
-  <affected-histogram name="Download.Service.Clients.InflatedFullBrowser"/>
   <affected-histogram name="Download.Service.Request.ClientAction"/>
-  <affected-histogram name="Download.Service.Request.StartResponse"/>
-  <affected-histogram name="Download.Service.Request.StartResult"/>
   <affected-histogram name="Download.Service.Upload.HasUploadData"/>
 </histogram_suffixes>
 
@@ -2510,14 +1825,6 @@
   <affected-histogram name="Download.Service.TaskScheduler.Status"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="DownloadableStringsTimeouts" separator=".">
-  <suffix name="RetryLater" label="Failed with RETRY_LATER error."/>
-  <suffix name="ServiceError" label="Failed with SERVICE_ERROR error."/>
-  <suffix name="UpdateCheckError"
-      label="Failed with UPDATE_CHECK_ERROR error."/>
-  <affected-histogram name="DownloadableStrings.Timeout"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="DownloadDangerPromptResponse" separator=".">
   <suffix name="Proceed"
       label="The user clicked through and recovered the download."/>
@@ -2605,20 +1912,6 @@
   <affected-histogram name="Download.PathValidationResult"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="DownloadWithUnsupportedScheme" separator=".">
-  <suffix name="ContentIdScheme" label="downloads with cid scheme"/>
-  <suffix name="ContentScheme" label="downloads with content scheme"/>
-  <suffix name="FileSystemScheme" label="downloads with filesystem scheme"/>
-  <suffix name="FtpScheme" label="downloads with ftp scheme"/>
-  <suffix name="GopherScheme" label="downloads with gopher scheme"/>
-  <suffix name="JavaScriptScheme" label="downloads with javascript scheme"/>
-  <suffix name="LocalFileScheme" label="downloads with file:/// scheme"/>
-  <suffix name="OtherUnsupportedScheme" label="Other unsupported schemes"/>
-  <suffix name="RemoteFileScheme" label="downloads with file:// scheme"/>
-  <suffix name="WSOrWSSScheme" label="downloads with ws or wss scheme"/>
-  <affected-histogram name="SBClientDownload.UnsupportedScheme"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="DriveCommonTimings" separator=".">
   <suffix name="FailTime" label=""/>
   <suffix name="SuccessTime" label=""/>
@@ -2662,17 +1955,9 @@
   <affected-histogram name="SiteEngagementService.EngagementScoreBucket"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ExtensionsDatabaseRestore" separator=".">
-  <suffix name="Rules" label="Rules backing stores"/>
-  <suffix name="Settings" label="Settings backing stores"/>
-  <suffix name="State" label="State backing stores"/>
-  <affected-histogram name="Extensions.Database.Restore"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ExtensionSource" separator="_" ordering="prefix">
   <suffix name="OffStore" label="Extension hosted off the Chrome Web Store"/>
   <suffix name="WebStore" label="Extension from the Chrome Web Store"/>
-  <affected-histogram name="Extensions.ForceInstalledFailureReason2"/>
   <affected-histogram name="Extensions.ForceInstalledFailureReason3"/>
 </histogram_suffixes>
 
@@ -2794,25 +2079,6 @@
       name="Autofill.FieldPredictionQuality.ByFieldType.Server"/>
   <affected-histogram
       name="Autofill.NumberOfEditedAutofilledFieldsAtSubmission"/>
-  <affected-histogram name="Autofill.Quality.HeuristicType"/>
-  <affected-histogram name="Autofill.Quality.HeuristicType.ByFieldType"/>
-  <affected-histogram name="Autofill.Quality.PredictedType"/>
-  <affected-histogram name="Autofill.Quality.PredictedType.ByFieldType"/>
-  <affected-histogram name="Autofill.Quality.ServerType"/>
-  <affected-histogram name="Autofill.Quality.ServerType.ByFieldType"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="FirstPacketSplit" separator="_">
-  <suffix name="first_packet_intact"
-      label="with GET/POST headers often using only 1 packet"/>
-  <suffix name="first_packet_split"
-      label="with all GET/POST requests using at least 2 packets"/>
-  <affected-histogram name="Renderer4.Abandoned"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="Renderer4.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="Renderer4.LoadType"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="FirstUserActionType" separator="">
@@ -2854,19 +2120,6 @@
   <suffix name="FromGWS"
       label="Only page loads that are a result of a navigation from a web
              search are considered."/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.BeginToFirstPaint"/>
-  <affected-histogram name="PLT.CommitToFirstPaint"/>
-  <affected-histogram name="PLT.PT_BeginToCommit"/>
-  <affected-histogram name="PLT.PT_BeginToFinish"/>
-  <affected-histogram name="PLT.PT_BeginToFinishDoc"/>
-  <affected-histogram name="PLT.PT_CommitToFinish"/>
-  <affected-histogram name="PLT.PT_CommitToFinishDoc"/>
-  <affected-histogram name="PLT.PT_RequestToCommit"/>
-  <affected-histogram name="PLT.PT_RequestToDomContentLoaded"/>
-  <affected-histogram name="PLT.PT_RequestToFinish"/>
-  <affected-histogram name="PLT.PT_RequestToFinishDoc"/>
   <affected-histogram name="PLT.PT_RequestToStart"/>
   <affected-histogram name="PLT.PT_StartToCommit"/>
   <affected-histogram name="PLT.PT_StartToFinish"/>
@@ -2881,14 +2134,6 @@
   <affected-histogram name="Geolocation.SettingsDialog.SuppressEvent"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="Gesture" separator="_">
-  <suffix name="Touch"
-      label="Measure the size of scroller that users touch scroll"/>
-  <suffix name="Wheel"
-      label="Measure the size of scroller that users wheel scroll"/>
-  <affected-histogram name="Event.Scroll.ScrollerSize.OnScroll"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="GetAuthTokenType" separator=".">
   <suffix name="RemoteConsentApproved"
       label="The remote consent has been approved for the getAuthToken()
@@ -2902,21 +2147,6 @@
   <affected-histogram name="GPU.Error"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="GoogleSearchVariations" separator="_">
-  <owner>kmadhusu@chromium.org</owner>
-  <suffix name="_PrerenderDisabled"
-      label="Counts number of Google searches from various access points in
-             the Android Chrome browser when prerendering is disabled via
-             &quot;Bandwidth management&quot; settings or &quot;Privacy&quot;
-             settings. Only recorded on Android."/>
-  <suffix name="_PrerenderEnabled"
-      label="Counts number of Google searches from various access points in
-             the Android Chrome browser when prerendering is enabled via
-             &quot;Bandwidth management&quot; settings or &quot;Privacy&quot;
-             settings. Only recorded on Android."/>
-  <affected-histogram name="GoogleSearch.AccessPoint"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="GoogleUpdate_Result_UpdateType" separator=".">
   <suffix base="true" name="Intent" label="Intent Updates"/>
   <suffix base="true" name="Unknown" label="Unknown Update Type"/>
@@ -2940,8 +2170,6 @@
   <suffix name="BGRA" label="BGRA"/>
   <suffix name="NV12" label="NV12"/>
   <suffix name="YUY2" label="YUY2"/>
-  <affected-histogram name="GPU.DirectComposition.OverlaySupportFlags2"/>
-  <affected-histogram name="GPU.DirectComposition.SwapChainCreationResult"/>
   <affected-histogram name="GPU.DirectComposition.SwapChainCreationResult2"/>
 </histogram_suffixes>
 
@@ -2975,7 +2203,6 @@
   <suffix name="HardwareProtected" label="HardwareProtected"/>
   <suffix name="SoftwareProtected" label="SoftwareProtected"/>
   <affected-histogram name="GPU.DirectComposition.DCLayerResult.Video"/>
-  <affected-histogram name="GPU.DirectComposition.DCLayerResult2"/>
   <affected-histogram name="GPU.DirectComposition.SwapChainCreationResult3"/>
 </histogram_suffixes>
 
@@ -2992,7 +2219,6 @@
   <suffix name="GpuRasterization" label="GpuRasterization"/>
   <suffix name="Webgl" label="Webgl"/>
   <suffix name="Webgl2" label="Webgl2"/>
-  <affected-histogram name="GPU.BlacklistFeatureTestResultsWindows"/>
   <affected-histogram name="GPU.BlocklistFeatureTestResults"/>
 </histogram_suffixes>
 
@@ -3023,17 +2249,6 @@
   <affected-histogram name="GwpAsan.CrashAnalysisResult"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="GwpAsanPerProcessOom" separator=".">
-  <suffix name="Browser" label="for the browser process."/>
-  <suffix name="Extension" label="for the extension process."/>
-  <suffix name="Gpu" label="for the gpu-process."/>
-  <suffix name="Ppapi" label="for the ppapi process."/>
-  <suffix name="Renderer" label="for the renderer process."/>
-  <suffix name="Utility" label="for the utility process."/>
-  <affected-histogram name="GwpAsan.AllocatorOom.Malloc"/>
-  <affected-histogram name="GwpAsan.AllocatorOom.PartitionAlloc"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="GWSChromeJointExperiment" separator="_">
   <suffix name="Experiment1"
       label="Only page loads that are a result of a navigation from a web
@@ -3115,19 +2330,6 @@
       label="Only page loads that are a result of a navigation from a web
              search under a specific web search/Chrome joint experiment.
              Unused at this moment."/>
-  <affected-histogram name="PLT.BeginToFinish_FromGWS"/>
-  <affected-histogram name="PLT.BeginToFinishDoc_FromGWS"/>
-  <affected-histogram name="PLT.BeginToFirstPaint_FromGWS"/>
-  <affected-histogram name="PLT.CommitToFirstPaint_FromGWS"/>
-  <affected-histogram name="PLT.PT_BeginToCommit_FromGWS"/>
-  <affected-histogram name="PLT.PT_BeginToFinish_FromGWS"/>
-  <affected-histogram name="PLT.PT_BeginToFinishDoc_FromGWS"/>
-  <affected-histogram name="PLT.PT_CommitToFinish_FromGWS"/>
-  <affected-histogram name="PLT.PT_CommitToFinishDoc_FromGWS"/>
-  <affected-histogram name="PLT.PT_RequestToCommit_FromGWS"/>
-  <affected-histogram name="PLT.PT_RequestToDomContentLoaded_FromGWS"/>
-  <affected-histogram name="PLT.PT_RequestToFinish_FromGWS"/>
-  <affected-histogram name="PLT.PT_RequestToFinishDoc_FromGWS"/>
   <affected-histogram name="PLT.PT_RequestToStart_FromGWS"/>
   <affected-histogram name="PLT.PT_StartToCommit_FromGWS"/>
   <affected-histogram name="PLT.PT_StartToFinish_FromGWS"/>
@@ -3220,17 +2422,6 @@
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="HstsState" separator=".">
-  <suffix name="HSTSNotEnabled" label="The HSTS is not enabled."/>
-  <suffix name="WithHSTSEnabled" label="The HSTS is enabled."/>
-  <affected-histogram
-      name="PasswordManager.HttpCredentialsWithConflictingHttpsCredential"/>
-  <affected-histogram
-      name="PasswordManager.HttpCredentialsWithEquivalentHttpsCredential"/>
-  <affected-histogram
-      name="PasswordManager.HttpCredentialsWithoutMatchingHttpsCredential"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="HttpCacheAccessToDoneCases" separator=".">
   <suffix name="SentRequest" label="The request was sent over the network."/>
   <suffix name="Used"
@@ -3248,7 +2439,6 @@
   <suffix name="Validated"
       label="A cached resource existed and was validated over the network."/>
   <affected-histogram name="HttpCache.BeforeSend"/>
-  <affected-histogram name="HttpCache.PercentBeforeSend"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="HttpJobBytes" separator=".">
@@ -3257,66 +2447,12 @@
   <affected-histogram name="Net.HttpJob.PrefilterBytesRead"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="HttpPipeliningCompatibility" separator="_">
-  <suffix name="disable_test" label="Do nothing"/>
-  <suffix name="enable_test" label="Test connection for HTTP pipelining"/>
-  <affected-histogram name="NetConnectivity.Pipeline.0.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.0.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.0.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.1.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.1.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.1.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.2.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.2.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.2.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.3.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.3.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.3.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.4.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.4.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.4.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.5.NetworkError"/>
-  <affected-histogram name="NetConnectivity.Pipeline.5.ResponseCode"/>
-  <affected-histogram name="NetConnectivity.Pipeline.5.Status"/>
-  <affected-histogram name="NetConnectivity.Pipeline.AllHTTP11"/>
-  <affected-histogram name="NetConnectivity.Pipeline.CanarySuccess"/>
-  <affected-histogram name="NetConnectivity.Pipeline.Depth"/>
-  <affected-histogram name="NetConnectivity.Pipeline.Success"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="IdleSktToImpact" separator="_">
-  <suffix name="idle_timeout_5"
-      label="with 5-second unused idle socket timeout"/>
-  <suffix name="idle_timeout_10"
-      label="with 10-second unused idle socket timeout"/>
-  <suffix name="idle_timeout_20"
-      label="with 20-second unused idle socket timeout"/>
-  <suffix name="idle_timeout_60"
-      label="with 60-second unused idle socket timeout"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="IgnoredWriteResultOperation" separator=".">
-  <suffix name="AddInstanceIDData" label="When calling AddInstanceIDData()."/>
-  <suffix name="RemoveInstanceIDData"
-      label="When calling RemoveInstanceIDData()."/>
-  <suffix name="SetLastTokenFetchTime"
-      label="When calling SetLastTokenFetchTime()."/>
-  <affected-histogram name="GCM.IgnoredWriteResult"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="IMEAutoCorrect" separator=".">
   <suffix name="AC0" label="The auto-correct level is 0"/>
   <suffix name="AC1" label="The auto-correct level is 1"/>
   <suffix name="AC2" label="The auto-correct level is 2"/>
   <affected-histogram name="InputMethod.Commit.Index.FR"/>
   <affected-histogram name="InputMethod.Commit.Index.US"/>
-  <affected-histogram name="InputMethod.Commit.Type.FR"/>
-  <affected-histogram name="InputMethod.Commit.Type.US"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="IMEMajorNames" separator=".">
@@ -3324,59 +2460,6 @@
   <suffix name="Pinyin" label="The Chinse Pinyin input method"/>
   <suffix name="US" label="The US keyboard input method"/>
   <affected-histogram name="InputMethod.Commit.Index"/>
-  <affected-histogram name="InputMethod.Commit.Type"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="IndexedDBLevelDBErrnoMethods" separator=".">
-  <suffix name="NewLogger" label="ChromiumEnv::NewLogger"/>
-  <suffix name="NewSequentialFile" label="ChromiumEnv::NewSequentialFile"/>
-  <suffix name="NewWritableFile" label="ChromiumEnv::NewWritableFile"/>
-  <suffix name="SequentialFileRead" label="ChromiumSequentialFile::Read"/>
-  <suffix name="SequentialFileSkip" label="ChromiumSequentialFile::Skip"/>
-  <suffix name="WritableFileAppend" label="ChromiumWritableFile::Append"/>
-  <suffix name="WritableFileClose" label="ChromiumWritableFile::Close"/>
-  <suffix name="WritableFileFlush" label="ChromiumWritableFile::Flush"/>
-  <suffix name="WritableFileSync" label="ChromiumWritableFile::Sync"/>
-  <suffix name="WritableFileSyncParent"
-      label="ChromiumWritableFile::SyncParent"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBOpenErrors.Errno"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBReadErrors.Errno"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBWriteErrors.Errno"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="IndexedDBLevelDBPFEMethods" separator=".">
-  <suffix name="CreateDir" label="ChromiumEnv::CreateDir"/>
-  <suffix name="GetChildren" label="ChromiumEnv::GetChildren"/>
-  <suffix name="GetFileSize" label="ChromiumEnv::GetFileSize"/>
-  <suffix name="LockFile" label="ChromiumEnv::LockFile"/>
-  <suffix name="NewAppendableFile" label="ChromiumEnv::NewAppendableFile"/>
-  <suffix name="NewRandomAccessFile" label="ChromiumEnv::NewRandomAccessFile"/>
-  <suffix name="RandomAccessFileRead" label="ChromiumRandomAccessFile::Read"/>
-  <suffix name="RemoveFile" label="ChromiumEnv::RemoveFile"/>
-  <suffix name="RenameFile" label="ChromiumEnv::RenameFile"/>
-  <suffix name="UnlockFile" label="ChromiumEnv::UnlockFile"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBOpenErrors.PFE"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBReadErrors.PFE"/>
-  <affected-histogram name="WebCore.IndexedDB.LevelDBWriteErrors.PFE"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="InputEventPredictionAccuracy" separator=".">
-  <suffix name="Long" label="predicted time between 20 to 35ms."/>
-  <suffix name="Middle" label="predicted time between 10 to 20ms."/>
-  <suffix name="Short" label="predicted time less than 10ms."/>
-  <affected-histogram name="Event.InputEventPrediction.Accuracy.Mouse"/>
-  <affected-histogram name="Event.InputEventPrediction.Accuracy.Scroll"/>
-  <affected-histogram
-      name="Event.InputEventPrediction.Accuracy.Scroll.OverPredict"/>
-  <affected-histogram
-      name="Event.InputEventPrediction.Accuracy.Scroll.UnderPredict"/>
-  <affected-histogram name="Event.InputEventPrediction.Accuracy.Touch"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="Instant" separator="_">
-  <suffix name="Extended" label="Suggestions + Results"/>
-  <suffix name="Instant" label="Results"/>
-  <affected-histogram name="Instant.SessionsStorageNamespace"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="IntentToFirstCommitZoom" separator=".">
@@ -3386,14 +2469,9 @@
   <suffix name="ZoomedOut"
       label="Zoomed out view: longer time range, less buckets."/>
   <affected-histogram
-      name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime2"/>
-  <affected-histogram
       name="ChromeGeneratedCustomTab.IntentToFirstNavigationStartTime"/>
-  <affected-histogram name="CustomTabs.IntentToFirstCommitNavigationTime2"/>
   <affected-histogram name="CustomTabs.IntentToFirstCommitNavigationTime3"/>
   <affected-histogram name="CustomTabs.IntentToFirstNavigationStartTime"/>
-  <affected-histogram name="Startup.FirstCommitNavigationTime2"/>
-  <affected-histogram name="Startup.FirstCommitNavigationTime3"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="IOMode" separator=".">
@@ -3424,34 +2502,8 @@
   <suffix name="BeforeUnload" label="dialog caused by window.onbeforeunload"/>
   <suffix name="Confirm" label="window.confirm() dialog"/>
   <suffix name="Prompt" label="window.prompt() dialog"/>
-  <affected-histogram name="JSDialogs.DismissalCause"/>
-  <affected-histogram name="JSDialogs.IsForemost"/>
   <affected-histogram name="JSDialogs.OriginRelationship"/>
   <affected-histogram name="JSDialogs.Scheme"/>
-  <affected-histogram name="JSDialogs.SiteEngagementOfDialogs"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="LateBindingExperiment" separator="_">
-  <suffix name="disable_late_binding" label="socket late binding is disabled"/>
-  <suffix name="enable_late_binding" label="socket late binding is enabled"/>
-  <affected-histogram name="Net.SocketIdleTimeBeforeNextUse_ReusedSocket"/>
-  <affected-histogram name="Net.SocketIdleTimeBeforeNextUse_UnusedSocket"/>
-  <affected-histogram name="Net.SocketIdleTimeOnIOError2_ReusedSocket"/>
-  <affected-histogram name="Net.SocketIdleTimeOnIOError2_UnusedSocket"/>
-  <affected-histogram name="Net.TCPSocketType"/>
-  <affected-histogram name="Net.Transaction_Connected"/>
-  <affected-histogram name="Net.Transaction_Connected_Under_10"/>
-  <affected-histogram name="Net.TransportSocketRequestTime"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoad"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="Renderer4.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="Renderer4.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc_LinkLoad"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc_LinkLoadNormal"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc_LinkLoadReload"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc_NormalLoad"/>
-  <affected-histogram name="Renderer4.RequestToFinish"/>
-  <affected-histogram name="Renderer4.StartToFinish"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="LCDTextDisallowedReasonSuffixes" separator=".">
@@ -3504,75 +2556,17 @@
   <suffix name="WritableFileClose" label="ChromiumWritableFile::Close"/>
   <suffix name="WritableFileFlush" label="ChromiumWritableFile::Flush"/>
   <suffix name="WritableFileSync" label="ChromiumWritableFile::Sync"/>
-  <affected-histogram name="LevelDBEnv.IDB.IOError.BFE"/>
-  <affected-histogram name="LevelDBEnv.IOError.BFE"/>
-  <affected-histogram name="LevelDBEnv.ServiceWorker.IOError.BFE"/>
-  <affected-histogram name="MojoLevelDBEnv.IOError.BFE"/>
   <affected-histogram name="WebCore.IndexedDB.LevelDBOpenErrors.BFE"/>
   <affected-histogram name="WebCore.IndexedDB.LevelDBReadErrors.BFE"/>
   <affected-histogram name="WebCore.IndexedDB.LevelDBWriteErrors.BFE"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="LevelDBEnvPlatformFileErrors" separator="">
-  <suffix name="CreateDir" label="ChromiumEnv::CreateDir"/>
-  <suffix name="GetChildren" label="ChromiumEnv::GetChildren"/>
-  <suffix name="LockFile" label="ChromiumEnv::LockFile"/>
-  <suffix name="NewRandomAccessFile" label="ChromiumEnv::NewRandomAccessFile"/>
-  <suffix name="RenameFile" label="ChromiumEnv::RenameFile"/>
-  <affected-histogram name="LevelDBEnv.IDB.IOError."/>
-  <affected-histogram name="LevelDBEnv.IOError."/>
-  <affected-histogram name="LevelDBEnv.ServiceWorker.IOError."/>
-</histogram_suffixes>
-
-<histogram_suffixes name="LevelDBEnvRetry" separator="">
-  <suffix name="CreateDir" label="CreateDir"/>
-  <suffix name="LockFile" label="LockFile"/>
-  <suffix name="RenameFile" label="RenameFile"/>
-  <affected-histogram name="LevelDBEnv.IDB.RetryRecoveredFromErrorIn"/>
-  <affected-histogram name="LevelDBEnv.IDB.TimeUntilSuccessFor"/>
-  <affected-histogram name="LevelDBEnv.RetryRecoveredFromErrorIn"/>
-  <affected-histogram
-      name="LevelDBEnv.ServiceWorker.RetryRecoveredFromErrorIn"/>
-  <affected-histogram name="LevelDBEnv.ServiceWorker.TimeUntilSuccessFor"/>
-  <affected-histogram name="LevelDBEnv.TimeUntilSuccessFor"/>
-  <affected-histogram name="MojoLevelDBEnv.RetryRecoveredFromErrorIn"/>
-  <affected-histogram name="MojoLevelDBEnv.TimeUntilSuccessFor"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="LevelDBEnvTypes" separator="." ordering="prefix">
   <suffix name="IDB" label="Restricted to IndexedDB LevelDB environments"/>
   <suffix name="ServiceWorker"
       label="Restricted to ServiceWorker LevelDB environments"/>
   <affected-histogram name="LevelDBEnv.IOError"/>
-  <affected-histogram name="LevelDBEnv.IOError."/>
-  <affected-histogram name="LevelDBEnv.IOError.BFE"/>
-  <affected-histogram name="LevelDBEnv.IOError.NewLogger"/>
-  <affected-histogram name="LevelDBEnv.IOError.NewSequentialFile"/>
-  <affected-histogram name="LevelDBEnv.IOError.RandomAccessFile"/>
-  <affected-histogram name="LevelDBEnv.IOError.WritableFileAppend"/>
-  <affected-histogram name="LevelDBEnv.IOError.WritableFileFlush"/>
-  <affected-histogram name="LevelDBEnv.LockFileAncestorsNotFound"/>
-  <affected-histogram name="LevelDBEnv.MaxFDs"/>
   <affected-histogram name="LevelDBEnv.MissingFiles"/>
-  <affected-histogram name="LevelDBEnv.RetryRecoveredFromErrorIn"/>
-  <affected-histogram name="LevelDBEnv.Table"/>
-  <affected-histogram name="LevelDBEnv.TimeTo"/>
-  <affected-histogram name="LevelDBEnv.TimeUntilSuccessFor"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="LevelDBSharedCache" separator=".">
-  <owner>cmumford@chromium.org</owner>
-  <suffix name="Browser"
-      label="Cache shared databases whose access pattern is dictated by
-             browser code."/>
-  <suffix name="InMemory" label="Cache shared all in-memory databases."/>
-  <suffix name="Unified" label="Cache shared by both web and browser."/>
-  <suffix name="Web"
-      label="whose access pattern is directly influenced by Web APIs, like
-             Indexed DB, etc."/>
-  <affected-histogram name="LevelDB.SharedCache.BytesUsed"/>
-  <affected-histogram name="LevelDB.SharedCache.DBCount"/>
-  <affected-histogram name="LevelDB.SharedCache.KBUsed"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="LiveTabCountMetrics" separator=".">
@@ -3664,8 +2658,6 @@
       prerendered pages.
     </obsolete>
   </suffix>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay2"/>
   <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay4"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
@@ -3825,15 +2817,6 @@
   <affected-histogram name="Media.Audio.InputStartupSuccessMac"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="MainFrameNavigation" separator="_">
-  <suffix name="MainFrame" label="Main frame navigation."/>
-  <affected-histogram name="ServiceWorker.NavPreload.ConcurrentTime"/>
-  <affected-histogram name="ServiceWorker.NavPreload.FinishedFirst"/>
-  <affected-histogram name="ServiceWorker.NavPreload.ResponseTime"/>
-  <affected-histogram name="ServiceWorker.NavPreload.WorkerPreparationType"/>
-  <affected-histogram name="ServiceWorker.NavPreload.WorkerWaitTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ManifestProperties" separator=".">
   <suffix name="description" label=""/>
   <suffix name="display" label=""/>
@@ -3906,18 +2889,6 @@
   <affected-histogram name="Media.PepperVideoDecoderOutputPictureCount"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="MediaLearningDroppedFrameRatioTask" separator=".">
-  <suffix name="BaseTable" label="Basic features, lookup table model"/>
-  <suffix name="BaseTree" label="Basic features, ExtraTrees model"/>
-  <suffix name="BinarySmoothnessTree"
-      label="Basic+extra features, pre-thresholded ExtraTrees model"/>
-  <suffix name="EnhancedTree" label="Basic+extra features, ExtraTrees model"/>
-  <suffix name="EnhancedUnweightedTree"
-      label="Basic+extra features, unweighted ExtraTrees model"/>
-  <affected-histogram
-      name="Media.Learning.MediaCapabilities.DroppedFrameRatioTask"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="MediaRebufferingCategories" separator=".">
   <suffix name="Audio.EME" label="Metric for EME media with an audio track."/>
   <suffix name="Audio.MSE" label="Metric for MSE media with an audio track."/>
@@ -3949,14 +2920,6 @@
   <affected-histogram name="MediaRouter.Cast.App.Availability"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="MediaSessionSource" separator=".">
-  <suffix name="Arc" label="ARC++ app"/>
-  <suffix name="Web" label="Website"/>
-  <affected-histogram name="Media.Session.AudioFocus.Abandon"/>
-  <affected-histogram name="Media.Session.AudioFocus.Request"/>
-  <affected-histogram name="Media.Session.AudioFocus.Type"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="MediaStreamAndDecoderType" separator=".">
   <suffix name="Audio.HW" label="Platform audio decoder"/>
   <suffix name="Audio.SW" label="Software audio decoder"/>
@@ -4154,17 +3117,6 @@
       name="Memory.Experimental.Renderer.WebpageCount.AtHighestPrivateMemoryFootprint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="MemoryStateTransition" separator=".">
-  <suffix name="NormalToSuspended" label=""/>
-  <suffix name="NormalToThrottled" label=""/>
-  <suffix name="SuspendedToNormal" label=""/>
-  <suffix name="SuspendedToThrottled" label=""/>
-  <suffix name="ThrottledToNormal" label=""/>
-  <suffix name="ThrottledToSuspended" label=""/>
-  <affected-histogram name="Memory.Coordinator.StateDuration"/>
-  <affected-histogram name="Memory.Coordinator.TotalPrivate"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="MimeTypeBucket" separator=".">
   <suffix name="OtherMimeType"
       label="A MIME type that doesn't fall into either of the other two
@@ -4234,37 +3186,6 @@
   <affected-histogram name="Mobile.Messages.Passwords.Modal.Present"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="MobileDownloadBytesDownloadedTypes" separator=".">
-  <suffix name="ChromeNetworkStack.Failure" label=""/>
-  <suffix name="ChromeNetworkStack.Success" label=""/>
-  <suffix name="DownloadManager.Failure" label=""/>
-  <suffix name="DownloadManager.Success" label=""/>
-  <affected-histogram name="MobileDownload.BytesDownloaded"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="MobileDownloadBytesWastedTypes" separator=".">
-  <suffix name="Cancel" label="Recorded upon download Cancel."/>
-  <suffix name="Failure" label="Recorded upon download failure."/>
-  <suffix name="Success" label="Recorded upon download success."/>
-  <affected-histogram name="MobileDownload.BytesWasted.ChromeNetworkStack"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="MobileDownloadDownloadTimeTypes" separator=".">
-  <suffix name="ChromeNetworkStack.Cancel" label=""/>
-  <suffix name="ChromeNetworkStack.Failure" label=""/>
-  <suffix name="ChromeNetworkStack.Success" label=""/>
-  <suffix name="DownloadManager.Failure" label=""/>
-  <suffix name="DownloadManager.Success" label=""/>
-  <affected-histogram name="MobileDownload.DownloadTime"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="MobileDownloadInterruptionsCountTypes" separator=".">
-  <suffix name="ChromeNetworkStack.Cancel" label=""/>
-  <suffix name="ChromeNetworkStack.Failure" label=""/>
-  <suffix name="ChromeNetworkStack.Success" label=""/>
-  <affected-histogram name="MobileDownload.InterruptionsCount"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="MobileDownloadResumptionsCountTypes" separator=".">
   <suffix name="Automatic" label=""/>
   <suffix name="Manual" label=""/>
@@ -4290,21 +3211,6 @@
       label="The version of the Module Integrity Verifier that doesn't use a
              hash set to track relocations."/>
   <affected-histogram name="ModuleIntegrityVerification.BytesModified"/>
-  <affected-histogram name="ModuleIntegrityVerification.Difference"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NavigationCharacteristic" separator="_">
-  <suffix name="ExistingRenderer_BeforeUnloadDiscounted"
-      label="Navigation reused an existing renderer process. Time spent in
-             beforeunload subtracted."/>
-  <suffix name="NewRenderer_BeforeUnloadDiscounted"
-      label="Navigation spawned a new renderer process. Time spent in
-             beforeunload subtracted."/>
-  <suffix name="SessionRestored_BeforeUnloadDiscounted"
-      label="Navigation caused by restoring a tab from a previous session
-             (whether from a crash or a continued session) either spawning or
-             reusing a renderer. Time spent in beforeunload subtracted."/>
-  <affected-histogram name="Navigation.TimeToCommit"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NavigationFrameType" separator=".">
@@ -4314,7 +3220,6 @@
   <affected-histogram name="Navigation.StartToCommit"/>
   <affected-histogram name="Navigation.StartToCommit.CrossProcess"/>
   <affected-histogram name="Navigation.StartToCommit.SameProcess"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit"/>
   <affected-histogram name="Navigation.TimeToReadyToCommit2"/>
 </histogram_suffixes>
 
@@ -4346,32 +3251,10 @@
   <affected-histogram name="Session.WebStates.NavigationItem"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NavigationPredictor_DSEAffix" separator="."
-    ordering="prefix">
-  <suffix name="OnDSE"
-      label="Recorded only for pages whose URL matches the URL of the search
-             results page of the user's default search engine."/>
-  <suffix name="OnNonDSE"
-      label="Recorded only for pages whose URL does not match the URL of the
-             search results page of the user's default search engine."/>
-  <affected-histogram name="NavigationPredictor.AccuracyActionTaken"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NavigationPreloadEnabled" separator="_">
-  <suffix name="NavigationPreloadEnabled" label="Navigation preload occurred."/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time"/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time_WorkerStartOccurred"/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="NavigationProcessType" separator=".">
   <suffix name="CrossProcess" label="Cross process navigation."/>
   <suffix name="SameProcess" label="Same process navigation."/>
   <affected-histogram name="Navigation.StartToCommit"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit"/>
   <affected-histogram name="Navigation.TimeToReadyToCommit2"/>
 </histogram_suffixes>
 
@@ -4384,9 +3267,7 @@
   <suffix name="NewNavigation" label="New navigation"/>
   <suffix name="Reload" label="Reload"/>
   <affected-histogram name="Navigation.IsSameProcess"/>
-  <affected-histogram name="Navigation.ReadyToCommitUntilCommit"/>
   <affected-histogram name="Navigation.ReadyToCommitUntilCommit2"/>
-  <affected-histogram name="Navigation.Renderer.ReadyToCommitUntilCommit"/>
   <affected-histogram name="Navigation.StartToCommit"/>
   <affected-histogram name="Navigation.StartToCommit.CrossProcess"/>
   <affected-histogram name="Navigation.StartToCommit.CrossProcess.MainFrame"/>
@@ -4396,11 +3277,6 @@
   <affected-histogram name="Navigation.StartToCommit.SameProcess.MainFrame"/>
   <affected-histogram name="Navigation.StartToCommit.SameProcess.Subframe"/>
   <affected-histogram name="Navigation.StartToCommit.Subframe"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit.CrossProcess"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit.MainFrame"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit.SameProcess"/>
-  <affected-histogram name="Navigation.TimeToReadyToCommit.Subframe"/>
   <affected-histogram name="Navigation.TimeToReadyToCommit2"/>
   <affected-histogram name="Navigation.TimeToReadyToCommit2.CrossProcess"/>
   <affected-histogram name="Navigation.TimeToReadyToCommit2.MainFrame"/>
@@ -4408,17 +3284,6 @@
   <affected-histogram name="Navigation.TimeToReadyToCommit2.Subframe"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="Net_DNS_Priorities" separator=".">
-  <suffix name="HIGHEST" label="Jobs with priority HIGHEST."/>
-  <suffix name="IDLE" label="Jobs with priority IDLE."/>
-  <suffix name="LOW" label="Jobs with priority LOW."/>
-  <suffix name="LOWEST" label="Jobs with priority LOWEST."/>
-  <suffix name="MEDIUM" label="Jobs with priority MEDIUM."/>
-  <suffix name="THROTTLED" label="Jobs with priority THROTTLED."/>
-  <affected-histogram name="Net.DNS.JobQueueTime"/>
-  <affected-histogram name="Net.DNS.JobQueueTimeAfterChange"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Net_HttpJob_TotalTimeSuccess_Priorities"
     separator=".">
   <suffix name="Priority0" label="THROTTLED or MINIMUM_PRIORITY"/>
@@ -4432,46 +3297,6 @@
   <affected-histogram name="ResourceScheduler.RequestQueuingDuration"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="Net_QuicSession_21CumulativePackets" separator="_">
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <suffix name="First21"
-      label="Only the first group of 21 packets in a connection via"/>
-  <suffix name="Some21s"
-      label="After the first 21, this records data for some groups of 21
-             consecutive sequence nmubers, arriving via."/>
-  <affected-histogram name="Net.QuicSession.21CumulativePacketsReceived"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="Net_QuicSession_6PacketPatterns" separator="_">
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <suffix name="First6"
-      label="Only the first group of 6 packets in a connection via"/>
-  <suffix name="Some6s"
-      label="After the first 6, this records patterns for some groups of 6
-             consecutive sequence numbers, arriving via."/>
-  <affected-histogram name="Net.QuicSession.6PacketsPatternsReceived"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="Net_QuicSession_PacketReceived" separator="_">
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <suffix name="Ack"
-      label="Only packets that were received by Chrome as well being part of
-             connections via"/>
-  <suffix name="IsAnAck"
-      label="Only packets that were probably solo ACK packets when received
-             by Chrome as well being part of connections via"/>
-  <suffix name="IsNotAck"
-      label="Only packets that were probably NOT solo ACK packets when
-             received by Chrome as well being part of connections via"/>
-  <suffix name="Nack"
-      label="Only packets that were missed by Chrome as well being part of
-             connections via"/>
-  <affected-histogram name="Net.QuicSession.PacketReceived"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Net_QuicSession_PacketReceived_CONNECTION_TYPE"
     separator="_">
   <owner>dschinazi@chromium.org</owner>
@@ -4498,1210 +3323,14 @@
   <suffix name="CONNECTION_WIFI_802.11n" label="802.11n are tallied."/>
   <suffix name="CONNECTION_WIFI_ANCIENT"
       label="802.11 that are no longer standard are tallied."/>
-  <affected-histogram
-      name="Net.QuicSession.21CumulativePacketsReceived_First21"/>
-  <affected-histogram
-      name="Net.QuicSession.21CumulativePacketsReceived_Some21s"/>
-  <affected-histogram name="Net.QuicSession.6PacketsPatternsReceived_First6"/>
-  <affected-histogram name="Net.QuicSession.6PacketsPatternsReceived_Some6s"/>
   <affected-histogram name="Net.QuicSession.PacketLossRate"/>
-  <affected-histogram name="Net.QuicSession.PacketReceived_Ack"/>
-  <affected-histogram name="Net.QuicSession.PacketReceived_IsAnAck"/>
-  <affected-histogram name="Net.QuicSession.PacketReceived_IsNotAck"/>
-  <affected-histogram name="Net.QuicSession.PacketReceived_Nack"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity" separator=".">
-  <suffix name="53.1K" label="1K bytes of data on port 53."/>
-  <suffix name="53.1K.NoProxy"
-      label="1K bytes of data on port 53 with no proxy."/>
-  <suffix name="53.1K.RTT" label="1K bytes of data on port 53 successfully."/>
-  <suffix name="53.1K.RTT.NoProxy"
-      label="1K bytes of data on port 53 successfully with no proxy."/>
-  <suffix name="53.100B" label="100 bytes of data on port 53."/>
-  <suffix name="53.100B.NoProxy"
-      label="100 bytes of data on port 53 with no proxy."/>
-  <suffix name="53.100B.RTT"
-      label="100 bytes of data on port 53 successfully."/>
-  <suffix name="53.100B.RTT.NoProxy"
-      label="100 bytes of data on port 53 successfully with no proxy."/>
-  <suffix name="80.1K" label="1K bytes of data on port 80."/>
-  <suffix name="80.1K.NoProxy"
-      label="1K bytes of data on port 80 with no proxy."/>
-  <suffix name="80.1K.RTT" label="1K bytes of data on port 80 successfully."/>
-  <suffix name="80.1K.RTT.NoProxy"
-      label="1K bytes of data on port 80 successfully with no proxy."/>
-  <suffix name="80.100B" label="100 bytes of data on port 80."/>
-  <suffix name="80.100B.NoProxy"
-      label="100 bytes of data on port 80 with no proxy."/>
-  <suffix name="80.100B.RTT"
-      label="100 bytes of data on port 80 successfully."/>
-  <suffix name="80.100B.RTT.NoProxy"
-      label="100 bytes of data on port 80 successfully with no proxy."/>
-  <suffix name="587.1K" label="1K bytes of data on port 587."/>
-  <suffix name="587.1K.NoProxy"
-      label="1K bytes of data on port 587 with no proxy."/>
-  <suffix name="587.1K.RTT" label="1K bytes of data on port 587 successfully."/>
-  <suffix name="587.1K.RTT.NoProxy"
-      label="1K bytes of data on port 587 successfully with no proxy."/>
-  <suffix name="587.100B" label="100 bytes of data on port 587."/>
-  <suffix name="587.100B.NoProxy"
-      label="100 bytes of data on port 587 with no proxy."/>
-  <suffix name="587.100B.RTT"
-      label="100 bytes of data on port 587 successfully."/>
-  <suffix name="587.100B.RTT.NoProxy"
-      label="100 bytes of data on port 587 successfully with no proxy."/>
-  <suffix name="6121.1K" label="1K bytes of data on port 6121."/>
-  <suffix name="6121.1K.NoProxy"
-      label="1K bytes of data on port 6121 with no proxy."/>
-  <suffix name="6121.1K.RTT"
-      label="1K bytes of data on port 6121 successfully."/>
-  <suffix name="6121.1K.RTT.NoProxy"
-      label="1K bytes of data on port 6121 successfully with no proxy."/>
-  <suffix name="6121.100B" label="100 bytes of data on port 6121."/>
-  <suffix name="6121.100B.NoProxy"
-      label="100 bytes of data on port 6121 with no proxy."/>
-  <suffix name="6121.100B.RTT"
-      label="100 bytes of data on port 6121 successfully."/>
-  <suffix name="6121.100B.RTT.NoProxy"
-      label="100 bytes of data on port 6121 successfully with no proxy."/>
-  <suffix name="8080.1K" label="1K bytes of data on port 8080."/>
-  <suffix name="8080.1K.NoProxy"
-      label="1K bytes of data on port 8080 with no proxy."/>
-  <suffix name="8080.1K.RTT"
-      label="1K bytes of data on port 8080 successfully."/>
-  <suffix name="8080.1K.RTT.NoProxy"
-      label="1K bytes of data on port 8080 successfully with no proxy."/>
-  <suffix name="8080.100B" label="100 bytes of data on port 8080."/>
-  <suffix name="8080.100B.NoProxy"
-      label="100 bytes of data on port 8080 with no proxy."/>
-  <suffix name="8080.100B.RTT"
-      label="100 bytes of data on port 8080 successfully."/>
-  <suffix name="8080.100B.RTT.NoProxy"
-      label="100 bytes of data on port 8080 successfully with no proxy."/>
-  <affected-histogram name="NetConnectivity.TCP.Status"/>
-  <affected-histogram name="NetConnectivity.TCP.Success"/>
-  <affected-histogram name="NetConnectivity.UDP.PacketLoss"/>
-  <affected-histogram name="NetConnectivity.UDP.PacketLoss6"/>
-  <affected-histogram name="NetConnectivity.UDP.Status"/>
-  <affected-histogram name="NetConnectivity.UDP.Success"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2" separator=".">
-  <suffix name="AcksReceivedFromFirst2Packets" label="2 packets."/>
-  <suffix name="AcksReceivedFromFirst3Packets" label="3 packets."/>
-  <suffix name="AcksReceivedFromFirst4Packets" label="4 packets."/>
-  <suffix name="AcksReceivedFromFirst5Packets" label="5 packets."/>
-  <suffix name="AcksReceivedFromFirst6Packets" label="6 packets."/>
-  <suffix name="AcksReceivedFromFirst7Packets" label="7 packets."/>
-  <suffix name="AcksReceivedFromFirst8Packets" label="8 packets."/>
-  <suffix name="AcksReceivedFromFirst9Packets" label="9 packets."/>
-  <suffix name="AcksReceivedFromFirst10Packets" label="10 packets."/>
-  <suffix name="AcksReceivedFromFirst11Packets" label="11 packets."/>
-  <suffix name="AcksReceivedFromFirst12Packets" label="12 packets."/>
-  <suffix name="AcksReceivedFromFirst13Packets" label="13 packets."/>
-  <suffix name="AcksReceivedFromFirst14Packets" label="14 packets."/>
-  <suffix name="AcksReceivedFromFirst15Packets" label="15 packets."/>
-  <suffix name="AcksReceivedFromFirst16Packets" label="16 packets."/>
-  <suffix name="AcksReceivedFromFirst17Packets" label="17 packets."/>
-  <suffix name="AcksReceivedFromFirst18Packets" label="18 packets."/>
-  <suffix name="AcksReceivedFromFirst19Packets" label="19 packets."/>
-  <suffix name="AcksReceivedFromFirst20Packets" label="20 packets."/>
-  <suffix name="AcksReceivedFromFirst21Packets" label="21 packets."/>
-  <affected-histogram name="NetConnectivity.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2a" separator=".">
-  <suffix name="6121.1K" label="1K bytes of data is sent on port 6121."/>
-  <suffix name="6121.100B" label="100 bytes of data is sent on port 6121."/>
-  <suffix name="6121.500B" label="500 bytes of data is sent on port 6121."/>
-  <affected-histogram name="NetConnectivity2.Sent21.AckReceivedForNthPacket"/>
-  <affected-histogram name="NetConnectivity2.Sent21.GotAnAck"/>
-  <affected-histogram name="NetConnectivity2.Sent21.PacketsSent"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2b" separator=".">
-  <suffix name="AcksReceivedFromFirst2Packets.6121.100B"
-      label="2 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst3Packets.6121.100B"
-      label="3 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst4Packets.6121.100B"
-      label="4 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst5Packets.6121.100B"
-      label="5 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst6Packets.6121.100B"
-      label="6 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst7Packets.6121.100B"
-      label="7 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst8Packets.6121.100B"
-      label="8 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst9Packets.6121.100B"
-      label="9 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst10Packets.6121.100B"
-      label="10 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst11Packets.6121.100B"
-      label="11 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst12Packets.6121.100B"
-      label="12 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst13Packets.6121.100B"
-      label="13 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst14Packets.6121.100B"
-      label="14 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst15Packets.6121.100B"
-      label="15 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst16Packets.6121.100B"
-      label="16 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst17Packets.6121.100B"
-      label="17 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst18Packets.6121.100B"
-      label="18 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst19Packets.6121.100B"
-      label="19 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst20Packets.6121.100B"
-      label="20 packets. 100 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst21Packets.6121.100B"
-      label="21 packets. 100 bytes of data is sent on port 6121."/>
-  <affected-histogram name="NetConnectivity2.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2c" separator=".">
-  <suffix name="6121.1K" label="1K bytes of data is sent on port 6121."/>
-  <suffix name="6121.1K.NoProxy"
-      label="1K bytes of data is sent on port 6121 with no proxy."/>
-  <suffix name="6121.100B" label="100 bytes of data is sent on port 6121."/>
-  <suffix name="6121.100B.NoProxy"
-      label="100 bytes of data is sent on port 6121 with no proxy."/>
-  <suffix name="6121.500B" label="500 bytes of data is sent on port 6121."/>
-  <suffix name="6121.500B.NoProxy"
-      label="500 bytes of data is sent on port 6121 with no proxy."/>
-  <affected-histogram name="NetConnectivity2.Send6.PacketsSent"/>
-  <affected-histogram name="NetConnectivity2.Send6.SeriesAcked"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2d" separator=".">
-  <suffix name="AcksReceivedFromFirst2Packets.6121.500B"
-      label="2 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst3Packets.6121.500B"
-      label="3 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst4Packets.6121.500B"
-      label="4 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst5Packets.6121.500B"
-      label="5 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst6Packets.6121.500B"
-      label="6 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst7Packets.6121.500B"
-      label="7 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst8Packets.6121.500B"
-      label="8 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst9Packets.6121.500B"
-      label="9 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst10Packets.6121.500B"
-      label="10 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst11Packets.6121.500B"
-      label="11 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst12Packets.6121.500B"
-      label="12 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst13Packets.6121.500B"
-      label="13 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst14Packets.6121.500B"
-      label="14 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst15Packets.6121.500B"
-      label="15 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst16Packets.6121.500B"
-      label="16 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst17Packets.6121.500B"
-      label="17 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst18Packets.6121.500B"
-      label="18 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst19Packets.6121.500B"
-      label="19 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst20Packets.6121.500B"
-      label="20 packets. 500 bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst21Packets.6121.500B"
-      label="21 packets. 500 bytes of data is sent on port 6121."/>
-  <affected-histogram name="NetConnectivity2.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity2e" separator=".">
-  <suffix name="AcksReceivedFromFirst2Packets.6121.1K"
-      label="2 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst3Packets.6121.1K"
-      label="3 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst4Packets.6121.1K"
-      label="4 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst5Packets.6121.1K"
-      label="5 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst6Packets.6121.1K"
-      label="6 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst7Packets.6121.1K"
-      label="7 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst8Packets.6121.1K"
-      label="8 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst9Packets.6121.1K"
-      label="9 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst10Packets.6121.1K"
-      label="10 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst11Packets.6121.1K"
-      label="11 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst12Packets.6121.1K"
-      label="12 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst13Packets.6121.1K"
-      label="13 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst14Packets.6121.1K"
-      label="14 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst15Packets.6121.1K"
-      label="15 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst16Packets.6121.1K"
-      label="16 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst17Packets.6121.1K"
-      label="17 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst18Packets.6121.1K"
-      label="18 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst19Packets.6121.1K"
-      label="19 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst20Packets.6121.1K"
-      label="20 packets. 1K bytes of data is sent on port 6121."/>
-  <suffix name="AcksReceivedFromFirst21Packets.6121.1K"
-      label="21 packets. 1K bytes of data is sent on port 6121."/>
-  <affected-histogram name="NetConnectivity2.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3a" separator=".">
-  <suffix name="NonPacedPacket"
-      label="In this histogram results are only shown if at least two packets
-             were ACKed in the Startup Test. Packets were sent as rapidly as
-             possible."/>
-  <suffix name="PacedPacket"
-      label="In this histogram results are only shown if at least two packets
-             were ACKed in the Startup Test. Packets are sent at equal
-             intervals. The interval is selected to match the bandwidth
-             discovered during the StartPacket test."/>
-  <suffix name="StartPacket"
-      label="Packets are sent as rapidly as possible, just after successfully
-             sending an UMA upload. Each packet was numbered, as was its ACK
-             sent back by Google. If no packets (of the 21) were ever ACKed,
-             then the port is assumed to be blocked, and no data is recorded
-             in this histogram."/>
-  <affected-histogram name="NetConnectivity3"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3aa" separator=".">
-  <suffix name="Sent21"
-      label="This histogram shows the number of echo responses received from
-             the first"/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3AckReceivedForNthPacket"
-    separator=".">
-  <suffix name="Sent21.AckReceivedForNthPacket"
-      label="Each packet was numbered, as was its ACK sent back by Google.
-             This histogram records, for each packet number, how often we
-             received an ACK for that packet."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3AcksReceivedFromFirst" separator=".">
-  <suffix name="AcksReceivedFromFirst02Packets" label="2 packets."/>
-  <suffix name="AcksReceivedFromFirst03Packets" label="3 packets."/>
-  <suffix name="AcksReceivedFromFirst04Packets" label="4 packets."/>
-  <suffix name="AcksReceivedFromFirst05Packets" label="5 packets."/>
-  <suffix name="AcksReceivedFromFirst06Packets" label="6 packets."/>
-  <suffix name="AcksReceivedFromFirst07Packets" label="7 packets."/>
-  <suffix name="AcksReceivedFromFirst08Packets" label="8 packets."/>
-  <suffix name="AcksReceivedFromFirst09Packets" label="9 packets."/>
-  <suffix name="AcksReceivedFromFirst10Packets" label="10 packets."/>
-  <suffix name="AcksReceivedFromFirst11Packets" label="11 packets."/>
-  <suffix name="AcksReceivedFromFirst12Packets" label="12 packets."/>
-  <suffix name="AcksReceivedFromFirst13Packets" label="13 packets."/>
-  <suffix name="AcksReceivedFromFirst14Packets" label="14 packets."/>
-  <suffix name="AcksReceivedFromFirst15Packets" label="15 packets."/>
-  <suffix name="AcksReceivedFromFirst16Packets" label="16 packets."/>
-  <suffix name="AcksReceivedFromFirst17Packets" label="17 packets."/>
-  <suffix name="AcksReceivedFromFirst18Packets" label="18 packets."/>
-  <suffix name="AcksReceivedFromFirst19Packets" label="19 packets."/>
-  <suffix name="AcksReceivedFromFirst20Packets" label="20 packets."/>
-  <suffix name="AcksReceivedFromFirst21Packets" label="21 packets."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3GotAnAck" separator=".">
-  <suffix name="Sent21.GotAnAck"
-      label="The histogram shows if we ever got an ACK for a packet in our
-             series of 21."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3PacketDelay1" separator=".">
-  <suffix name="Sent21.443"
-      label="This histogram shows the difference between the time when we
-             have received 1st byte from the server and the last time when we
-             have received data from the server on port 443."/>
-  <suffix name="Sent21.6121"
-      label="This histogram shows the difference between the time when we
-             have received 1st byte from the server and the last time when we
-             have received data from the server on port 6121."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3PacketDelay2" separator=".">
-  <suffix name="443.100B.PacketDelay"
-      label="100 bytes of data is sent on port 443."/>
-  <suffix name="443.500B.PacketDelay"
-      label="500 bytes of data is sent on port 443."/>
-  <suffix name="443.1200B.PacketDelay"
-      label="1200 bytes of data is sent on port 443."/>
-  <suffix name="6121.100B.PacketDelay"
-      label="100 bytes of data is sent on port 6121."/>
-  <suffix name="6121.500B.PacketDelay"
-      label="500 bytes of data is sent on port 6121."/>
-  <suffix name="6121.1200B.PacketDelay"
-      label="1200 bytes of data is sent on port 6121."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3PacketRTT" separator=".">
-  <suffix name="Sent21.Success.RTT" label="The histogram shows the RTT for"/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3Packets" separator=".">
-  <suffix name="Packet01" label="1st packet."/>
-  <suffix name="Packet02" label="2nd packet."/>
-  <suffix name="Packet03" label="3rd packet."/>
-  <suffix name="Packet10" label="10th packet."/>
-  <suffix name="Packet20" label="20th packet."/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Sent21.Success.RTT"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3PacketsSent" separator=".">
-  <suffix name="Send6.SeriesAcked"
-      label="Chrome sends 6 UDP packets in a row to test to see if there is a
-             probabalistic dependency in packet loss for consecutive packets.
-             We record a bit vector of packets received, where the least
-             significant bit is a 1 if the first packet was received, etc.
-             For example, if all packets other than packet 2 and 4 are
-             responded to, then we'd have a sample (in binary) of 110101B, or
-             53."/>
-  <suffix name="Sent21.PacketsSent"
-      label="This histogram records how many packets (out of 21 attempted)
-             were sent to the server via UDP."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket"/>
-  <affected-histogram name="NetConnectivity3.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3PacketsSentBytes" separator=".">
-  <suffix name="443.100B" label="100 bytes of data is sent on port 443."/>
-  <suffix name="443.500B" label="500 bytes of data is sent on port 443."/>
-  <suffix name="443.1200B" label="1200 bytes of data is sent on port 443."/>
-  <suffix name="6121.100B" label="100 bytes of data is sent on port 6121."/>
-  <suffix name="6121.500B" label="500 bytes of data is sent on port 6121."/>
-  <suffix name="6121.1200B" label="1200 bytes of data is sent on port 6121."/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AckReceivedForNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.AcksReceivedFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket.Sent21.GotAnAck"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.PacketsSent"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AckReceivedForNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.AcksReceivedFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Sent21.GotAnAck"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Sent21.PacketsSent"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity3.PacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AckReceivedForNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.AcksReceivedFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Sent21.GotAnAck"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Sent21.PacketsSent"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity3.StartPacket.Sent21.Success.RTT.Packet20"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity3Send6Acked" separator=".">
-  <suffix name="443.100B" label="100 bytes of data is sent on port 443."/>
-  <suffix name="443.100B.NoProxy"
-      label="100 bytes of data is sent on port 443 with no proxy."/>
-  <suffix name="443.500B" label="500 bytes of data is sent on port 443."/>
-  <suffix name="443.500B.NoProxy"
-      label="500 bytes of data is sent on port 443 with no proxy."/>
-  <suffix name="443.1200B" label="1200 bytes of data is sent on port 443."/>
-  <suffix name="443.1200B.NoProxy"
-      label="1200 bytes of data is sent on port 443 with no proxy."/>
-  <suffix name="6121.100B" label="100 bytes of data is sent on port 6121."/>
-  <suffix name="6121.100B.NoProxy"
-      label="100 bytes of data is sent on port 6121 with no proxy."/>
-  <suffix name="6121.500B" label="500 bytes of data is sent on port 6121."/>
-  <suffix name="6121.500B.NoProxy"
-      label="500 bytes of data is sent on port 6121 with no proxy."/>
-  <suffix name="6121.1200B" label="1200 bytes of data is sent on port 6121."/>
-  <suffix name="6121.1200B.NoProxy"
-      label="1200 bytes of data is sent on port 6121 with no proxy."/>
-  <affected-histogram name="NetConnectivity3.NonPacedPacket.Send6.SeriesAcked"/>
-  <affected-histogram name="NetConnectivity3.PacedPacket.Send6.SeriesAcked"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Send6.PacketsSent"/>
-  <affected-histogram name="NetConnectivity3.StartPacket.Send6.SeriesAcked"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4a" separator=".">
-  <suffix name="NATBind.Sent2"
-      label="Two packets were sent spreading over a random period, to test if
-             the NAT dropped the binding. Afterwords, an extra (short) packet
-             was sent with renewed NAT binding to test whether the network
-             that was used to deliver the first packet is still connected.
-             Results are only shown in this histogram if at least ten packets
-             were received in the StartPacket test."/>
-  <suffix name="NonPacedPacket"
-      label="21 Packets were sent as rapidly as possible. Results are only
-             shown in this histogram if at least two packets were received in
-             the StartPacket Test."/>
-  <suffix name="PacedPacket"
-      label="21 Packets were sent at equal intervals, which were selected to
-             match the bandwidth discovered during the StartPacket test.
-             Results are only shown in this histogram if at least two packets
-             were received in the StartPacket Test."/>
-  <suffix name="StartPacket"
-      label="21 Packets were sent as rapidly as possible, just after the
-             client successfully sent a UMA upload. Each packet was numbered
-             when it was sent by Google."/>
-  <affected-histogram name="NetConnectivity4"/>
-  <affected-histogram name="NetConnectivity5"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4NATBindPacketReceives" separator=".">
-  <suffix name="Bind.Failure"
-      label="Only when the second packet never arrived (we wait for 10 extra
-             seconds) and the first and the extra (short) packets arrived did
-             we record the duration in seconds between the sendings of the
-             first two packets in this histogram."/>
-  <suffix name="Bind.Success"
-      label="Only when all three packets including the extra (short) packet
-             arrived did we record the duration in seconds between the
-             sendings of the first two packets in this histogram."/>
-  <suffix name="Connectivity.Failure"
-      label="Only when the extra (short) packet (with renewed NAT binding)
-             never arrived (we wait for 10 extra seconds) did we record the
-             duration in seconds between the sendings of the first two
-             packets in this histogram."/>
-  <suffix name="Connectivity.Success"
-      label="Only when the extra (short) packet arrived did we record the
-             duration in seconds between the sendings of the first two
-             packets in this histogram."/>
-  <suffix name="SendToLastRecvDelay"
-      label="This histogram records the time duration (in milliseconds)
-             between the client sending the request and the receiving of the
-             second packet sent from the server, excluding the idle time
-             between sendings of the first two packets. Results are only
-             shown if the first two packets are both received."/>
-  <affected-histogram name="NetConnectivity4.NATBind.Sent2"/>
-  <affected-histogram name="NetConnectivity5.NATBind.Sent2"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketFirst6" separator=".">
-  <suffix name="First6.SeriesRecv"
-      label="This histogram records a bit vector of the first 6 packets sent,
-             where the least significant bit is a 1 if the first packet was
-             received, etc. For example, if all packets other than packet 2
-             and 4 are received, then we'd have a sample (in binary) of
-             110101B, or 53."/>
-  <suffix name="Sent21"
-      label="This histogram shows the number of packets received from the
-             first"/>
-  <affected-histogram name="NetConnectivity4.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket"/>
-  <affected-histogram name="NetConnectivity4.StartPacket"/>
-  <affected-histogram name="NetConnectivity5.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket"/>
-  <affected-histogram name="NetConnectivity5.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketReceives" separator=".">
-  <suffix name="NumRecvFromFirst01Packets" label="1 packet."/>
-  <suffix name="NumRecvFromFirst02Packets" label="2 packets."/>
-  <suffix name="NumRecvFromFirst03Packets" label="3 packets."/>
-  <suffix name="NumRecvFromFirst04Packets" label="4 packets."/>
-  <suffix name="NumRecvFromFirst05Packets" label="5 packets."/>
-  <suffix name="NumRecvFromFirst06Packets" label="6 packets."/>
-  <suffix name="NumRecvFromFirst07Packets" label="7 packets."/>
-  <suffix name="NumRecvFromFirst08Packets" label="8 packets."/>
-  <suffix name="NumRecvFromFirst09Packets" label="9 packets."/>
-  <suffix name="NumRecvFromFirst10Packets" label="10 packets."/>
-  <suffix name="NumRecvFromFirst11Packets" label="11 packets."/>
-  <suffix name="NumRecvFromFirst12Packets" label="12 packets."/>
-  <suffix name="NumRecvFromFirst13Packets" label="13 packets."/>
-  <suffix name="NumRecvFromFirst14Packets" label="14 packets."/>
-  <suffix name="NumRecvFromFirst15Packets" label="15 packets."/>
-  <suffix name="NumRecvFromFirst16Packets" label="16 packets."/>
-  <suffix name="NumRecvFromFirst17Packets" label="17 packets."/>
-  <suffix name="NumRecvFromFirst18Packets" label="18 packets."/>
-  <suffix name="NumRecvFromFirst19Packets" label="19 packets."/>
-  <suffix name="NumRecvFromFirst20Packets" label="20 packets."/>
-  <suffix name="NumRecvFromFirst21Packets" label="21 packets."/>
-  <affected-histogram name="NetConnectivity4.NonPacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity5.NonPacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketRTT" separator=".">
-  <suffix name="Sent21.GotAPacket"
-      label="The histogram shows if we ever got at least one packet in our
-             series of 21."/>
-  <suffix name="Sent21.PacketDelay"
-      label="The histogram shows the average inter-arrival time between every
-             two consecutive packets we receive in our series of 21
-             multiplied by 20 (so this is essentially the time duration
-             between the first and the last received packets)."/>
-  <suffix name="Sent21.PacketsRecv"
-      label="The histogram shows how many packets we receive in our series of
-             21."/>
-  <suffix name="Sent21.RecvNthPacket"
-      label="Each packet was numbered when it was sent by Google. This
-             histogram records, for each packet number, how often we received
-             that packet."/>
-  <suffix name="Sent21.SendToLastRecvDelay"
-      label="This histogram records the time duration between the client
-             sending the request and the receiving of the last packet sent
-             from the server, excluding the total pacing time requested by
-             the client. Results are only shown if at least two packets are
-             received."/>
-  <suffix name="Sent21.Success.RTT"
-      label="The histogram shows the RTT for the"/>
-  <affected-histogram name="NetConnectivity4.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket"/>
-  <affected-histogram name="NetConnectivity4.StartPacket"/>
-  <affected-histogram name="NetConnectivity5.NonPacedPacket"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket"/>
-  <affected-histogram name="NetConnectivity5.StartPacket"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketRTTSeries" separator=".">
-  <suffix name="Packet01" label="1st packet."/>
-  <suffix name="Packet02" label="2nd packet."/>
-  <suffix name="Packet03" label="3rd packet."/>
-  <suffix name="Packet10" label="10th packet."/>
-  <suffix name="Packet20" label="20th packet."/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21.Success.RTT"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21.Success.RTT"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21.Success.RTT"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketsAll" separator=".">
-  <suffix name="80.100B" label="100 bytes of data is sent on port 80."/>
-  <suffix name="80.500B" label="500 bytes of data is sent on port 80."/>
-  <suffix name="80.1200B" label="1200 bytes of data is sent on port 80."/>
-  <suffix name="443.100B" label="100 bytes of data is sent on port 443."/>
-  <suffix name="443.500B" label="500 bytes of data is sent on port 443."/>
-  <suffix name="443.1200B" label="1200 bytes of data is sent on port 443."/>
-  <affected-histogram name="NetConnectivity4.NATBind.Sent2.Bind.Failure"/>
-  <affected-histogram name="NetConnectivity4.NATBind.Sent2.Bind.Success"/>
-  <affected-histogram
-      name="NetConnectivity4.NATBind.Sent2.Connectivity.Failure"/>
-  <affected-histogram
-      name="NetConnectivity4.NATBind.Sent2.Connectivity.Success"/>
-  <affected-histogram
-      name="NetConnectivity4.NATBind.Sent2.SendToLastRecvDelay"/>
-  <affected-histogram name="NetConnectivity4.NonPacedPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.PacketDelay"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.PacketsRecv"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity4.NonPacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21.PacketDelay"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21.PacketsRecv"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity4.PacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21.PacketDelay"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21.PacketsRecv"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity4.StartPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram name="NetConnectivity5.NATBind.Sent2.Bind.Failure"/>
-  <affected-histogram name="NetConnectivity5.NATBind.Sent2.Bind.Success"/>
-  <affected-histogram
-      name="NetConnectivity5.NATBind.Sent2.Connectivity.Failure"/>
-  <affected-histogram
-      name="NetConnectivity5.NATBind.Sent2.Connectivity.Success"/>
-  <affected-histogram
-      name="NetConnectivity5.NATBind.Sent2.SendToLastRecvDelay"/>
-  <affected-histogram name="NetConnectivity5.NonPacedPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.PacketDelay"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.PacketsRecv"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity5.NonPacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21.PacketDelay"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21.PacketsRecv"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity5.PacedPacket.Sent21.Success.RTT.Packet20"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21.GotAPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst01Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst02Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst03Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst04Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst05Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst06Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst07Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst08Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst09Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst10Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst11Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst12Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst13Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst14Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst15Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst16Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst17Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst18Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst19Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst20Packets"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.NumRecvFromFirst21Packets"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21.PacketDelay"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21.PacketsRecv"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.Sent21.RecvNthPacket"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.SendToLastRecvDelay"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.Success.RTT.Packet01"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.Success.RTT.Packet02"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.Success.RTT.Packet03"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.Success.RTT.Packet10"/>
-  <affected-histogram
-      name="NetConnectivity5.StartPacket.Sent21.Success.RTT.Packet20"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketSizeTest" separator=".">
-  <suffix name="PacketSizeTest.Connectivity.Failure"
-      label="This histogram records the size of the packet size that was not
-             received from the server."/>
-  <suffix name="PacketSizeTest.Connectivity.Success"
-      label="This histogram records the size of the packet size that was
-             received from the server."/>
-  <affected-histogram name="NetConnectivity4"/>
-  <affected-histogram name="NetConnectivity5"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4PacketSizeTestPort" separator=".">
-  <suffix name="80" label="Packet is sent on port 80."/>
-  <suffix name="443" label="Packet is sent on port 443."/>
-  <affected-histogram
-      name="NetConnectivity4.PacketSizeTest.Connectivity.Failure"/>
-  <affected-histogram
-      name="NetConnectivity4.PacketSizeTest.Connectivity.Success"/>
-  <affected-histogram
-      name="NetConnectivity5.PacketSizeTest.Connectivity.Failure"/>
-  <affected-histogram
-      name="NetConnectivity5.PacketSizeTest.Connectivity.Success"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetConnectivity4SeriesRecv" separator=".">
-  <suffix name="80.100B" label="100 bytes of data is sent on port 80."/>
-  <suffix name="80.100B.NoProxy"
-      label="100 bytes of data is sent on port 80 with no proxy."/>
-  <suffix name="80.500B" label="500 bytes of data is sent on port 80."/>
-  <suffix name="80.500B.NoProxy"
-      label="500 bytes of data is sent on port 80 with no proxy."/>
-  <suffix name="80.1200B" label="1200 bytes of data is sent on port 80."/>
-  <suffix name="80.1200B.NoProxy"
-      label="1200 bytes of data is sent on port 80 with no proxy."/>
-  <suffix name="443.100B" label="100 bytes of data is sent on port 443."/>
-  <suffix name="443.100B.NoProxy"
-      label="100 bytes of data is sent on port 443 with no proxy."/>
-  <suffix name="443.500B" label="500 bytes of data is sent on port 443."/>
-  <suffix name="443.500B.NoProxy"
-      label="500 bytes of data is sent on port 443 with no proxy."/>
-  <suffix name="443.1200B" label="1200 bytes of data is sent on port 443."/>
-  <suffix name="443.1200B.NoProxy"
-      label="1200 bytes of data is sent on port 443 with no proxy."/>
-  <affected-histogram name="NetConnectivity4.NonPacedPacket.First6.SeriesRecv"/>
-  <affected-histogram name="NetConnectivity4.PacedPacket.First6.SeriesRecv"/>
-  <affected-histogram name="NetConnectivity4.StartPacket.First6.SeriesRecv"/>
-  <affected-histogram name="NetConnectivity5.NonPacedPacket.First6.SeriesRecv"/>
-  <affected-histogram name="NetConnectivity5.PacedPacket.First6.SeriesRecv"/>
-  <affected-histogram name="NetConnectivity5.StartPacket.First6.SeriesRecv"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NetErrorCodeSubtype" separator="." ordering="prefix">
-  <owner>csharrison@chromium.org</owner>
-  <suffix name="NTP.Google" label="The Google web NTP"/>
-  <suffix name="NTP.Local" label="The local NTP"/>
-  <suffix name="NTP.ThirdParty"
-      label="The NTP served by a third party (e.g. Bing)"/>
-  <affected-histogram name="Net.RequestTime2.ErrAborted"/>
-  <affected-histogram name="Net.RequestTime2.Success"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NetHttpContentLengthType" separator=".">
   <suffix name="Http" label=""/>
   <suffix name="Https" label=""/>
   <suffix name="Video" label=""/>
-  <affected-histogram name="Net.HttpContentLength"/>
   <affected-histogram name="Net.HttpContentLengthV2"/>
-  <affected-histogram name="Net.HttpOriginalContentLength"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2"/>
 </histogram_suffixes>
 
@@ -5716,26 +3345,14 @@
              Net.HttpContentLength"/>
   <suffix name="ViaDRP"
       label="Bytes of traffic that passed through the Data Reduction Proxy"/>
-  <affected-histogram name="Net.HttpContentLength.Http"/>
-  <affected-histogram name="Net.HttpContentLength.Https"/>
   <affected-histogram name="Net.HttpContentLengthV2.Http"/>
   <affected-histogram name="Net.HttpContentLengthV2.Https"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Http"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Https"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2.Http"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2.Https"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NetHttpContentLengthType3" separator=".">
   <suffix name="Video" label="Bytes of video traffic"/>
-  <affected-histogram name="Net.HttpContentLength.Http.BypassedDRP"/>
-  <affected-histogram name="Net.HttpContentLength.Http.Direct"/>
-  <affected-histogram name="Net.HttpContentLength.Http.Other"/>
-  <affected-histogram name="Net.HttpContentLength.Http.ViaDRP"/>
-  <affected-histogram name="Net.HttpContentLength.Https.BypassedDRP"/>
-  <affected-histogram name="Net.HttpContentLength.Https.Direct"/>
-  <affected-histogram name="Net.HttpContentLength.Https.Other"/>
-  <affected-histogram name="Net.HttpContentLength.Https.ViaDRP"/>
   <affected-histogram name="Net.HttpContentLengthV2.Http.BypassedDRP"/>
   <affected-histogram name="Net.HttpContentLengthV2.Http.Direct"/>
   <affected-histogram name="Net.HttpContentLengthV2.Http.Other"/>
@@ -5744,14 +3361,6 @@
   <affected-histogram name="Net.HttpContentLengthV2.Https.Direct"/>
   <affected-histogram name="Net.HttpContentLengthV2.Https.Other"/>
   <affected-histogram name="Net.HttpContentLengthV2.Https.ViaDRP"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Http.BypassedDRP"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Http.Direct"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Http.Other"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Http.ViaDRP"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Https.BypassedDRP"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Https.Direct"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Https.Other"/>
-  <affected-histogram name="Net.HttpOriginalContentLength.Https.ViaDRP"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.BypassedDRP"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.Direct"/>
   <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.Other"/>
@@ -5778,14 +3387,6 @@
   <affected-histogram name="Net.HttpProxy.ConnectLatency.Secure"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NetProxyResolverExecutionTime" separator="_">
-  <suffix name="UrlOver2K" label="URL length was over 2K"/>
-  <suffix name="UrlOver4K" label="URL length was over 4K"/>
-  <suffix name="UrlOver8K" label="URL length was over 8K"/>
-  <suffix name="UrlOver128K" label="URL length was over 128K"/>
-  <affected-histogram name="Net.ProxyResolver.ExecutionTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="NetQuicDiskCacheBackend" separator=".">
   <owner>dschinazi@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
@@ -5797,23 +3398,9 @@
       label="Tracks the last failure reason until WaitForDataReady or its
              callback is executed. This is recorded when data is ready in
              WaitForDataReady or when the callback is executed"/>
-  <affected-histogram name="Net.QuicDiskCache.APICall"/>
   <affected-histogram name="Net.QuicDiskCache.FailureReason"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NetRequestTime" separator=".">
-  <suffix name="ErrAborted" label="Request aborted"/>
-  <suffix name="ErrConnectionReset" label="Connection reset"/>
-  <suffix name="ErrConnectionTimedOut" label="Request connection timed out"/>
-  <suffix name="ErrInternetDisconnected" label="Internet disconnected"/>
-  <suffix name="ErrNameNotResolved" label="Request domain not resolved"/>
-  <suffix name="ErrTimedOut" label="Request timed out"/>
-  <suffix name="MiscError" label="Uncategorized error"/>
-  <suffix name="Success" label="Success"/>
-  <affected-histogram name="Net.RequestTime"/>
-  <affected-histogram name="Net.RequestTime2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="NewTabPage_BackgroundService_RequestLatency"
     separator=".">
   <suffix name="Failure" label="Failed to fetch data from background service"/>
@@ -5916,20 +3503,6 @@
   <affected-histogram name="NewTabPage.LoadTime"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NextTabState" separator="_">
-  <suffix name="Active"
-      label="For a tab active which is shown foreground in a browser window."/>
-  <suffix name="Closed" label="For a tab that is about to be closed."/>
-  <suffix name="Detached"
-      label="For a tab that is being dragged by user to outside of the
-             browser window."/>
-  <suffix name="Inactive"
-      label="For tabs in background and not shown to user."/>
-  <affected-histogram name="Tabs.StateTransfer.Time_Active"/>
-  <affected-histogram name="Tabs.StateTransfer.Time_Detached"/>
-  <affected-histogram name="Tabs.StateTransfer.Time_Inactive"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="NotificationSchedulerClientType" separator=".">
   <suffix name="__Test__" label=""/>
   <suffix name="ChromeUpdate" label=""/>
@@ -5945,60 +3518,6 @@
   <affected-histogram name="Notifications.Scheduler.UserAction"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NQE_Accuracy_Metric_Accuracy_DiffPositiveOrNegative"
-    separator=".">
-  <suffix name="Negative"
-      label="Estimate of the metric was lower than observed metric"/>
-  <suffix name="Positive"
-      label="Estimate of the metric was higher than observed metric"/>
-  <affected-histogram
-      name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff"/>
-  <affected-histogram
-      name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff"/>
-  <affected-histogram name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff"/>
-  <affected-histogram name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff"/>
-  <affected-histogram
-      name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff"/>
-  <affected-histogram
-      name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff"/>
-  <affected-histogram
-      name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NQE_Accuracy_Metric_AccuracyRecordingIntervals"
-    separator=".">
-  <suffix name="15"
-      label="Recorded approximately 15 seconds after navigation start"/>
-  <affected-histogram
-      name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Positive"/>
-  <affected-histogram
-      name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Negative"/>
-  <affected-histogram
-      name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Positive"/>
-</histogram_suffixes>
-
 <histogram_suffixes
     name="NQE_Accuracy_Metric_EffectiveConnectionType_ObservedIntervals"
     separator=".">
@@ -6012,10 +3531,6 @@
   <suffix name="Slow2G" label="Observed effective connection type was Slow2G"/>
   <suffix name="Unknown"
       label="Observed effective connection type was Unknown"/>
-  <affected-histogram
-      name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff.Positive.15"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NQE_Accuracy_RTT_ObservedIntervals" separator=".">
@@ -6037,45 +3552,6 @@
       label="Observed metric was between 2540 and 51000 (inclusive) units"/>
   <suffix name="5100_Infinity"
       label="Observed metric was greater than 5100 (inclusive) units"/>
-  <affected-histogram
-      name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff.Positive.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff.Positive.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff.Positive.15"/>
-  <affected-histogram
-      name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff.Positive.15"/>
-  <affected-histogram
-      name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Positive.15"/>
-  <affected-histogram
-      name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Negative.15"/>
-  <affected-histogram
-      name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff.Positive.15"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="NQE_ObservationSources" separator=".">
-  <suffix name="Http" label="Observed from HTTP requests"/>
-  <suffix name="HttpCachedEstimate" label="Cached HTTP layer observation"/>
-  <suffix name="HttpExternalEstimate" label="From external estimate provider"/>
-  <suffix name="HttpPlatform" label="Synthetic HTTP layer observation"/>
-  <suffix name="Quic" label="Observed from QUIC"/>
-  <suffix name="Tcp" label="Observed from TCP sockets"/>
-  <suffix name="TransportCachedEstimate"
-      label="Cached transport layer observation"/>
-  <suffix name="TransportPlatform"
-      label="Synthetic transport layer observation"/>
-  <affected-histogram name="NQE.Kbps.RawObservation"/>
-  <affected-histogram name="NQE.RTT.RawObservation"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NQE_SignalStrengthQueried" separator=".">
@@ -6104,8 +3580,6 @@
   <suffix name="suggested_articles" label="Prefetched NTP suggestions"/>
   <affected-histogram name="OfflinePages.AccessEntryPoint"/>
   <affected-histogram
-      name="OfflinePages.Background.BackgroundLoadingFailedCode"/>
-  <affected-histogram
       name="OfflinePages.Background.EffectiveConnectionType.OffliningStartType"/>
   <affected-histogram
       name="OfflinePages.Background.EffectiveConnectionType.SavePageLater"/>
@@ -6117,17 +3591,8 @@
   <affected-histogram name="OfflinePages.Background.TimeToSaved"/>
   <affected-histogram name="OfflinePages.Background.TimeToStart"/>
   <affected-histogram name="OfflinePages.Background.TimeToStart.Svelte"/>
-  <affected-histogram name="OfflinePages.ClearStoragePreRunUsage"/>
   <affected-histogram name="OfflinePages.ClearStoragePreRunUsage2"/>
-  <affected-histogram name="OfflinePages.DeletePage.AccessCount"/>
-  <affected-histogram name="OfflinePages.DeletePage.LastOpenToCreated"/>
-  <affected-histogram name="OfflinePages.DeletePage.PageSize"/>
-  <affected-histogram name="OfflinePages.DeletePage.TimeSinceLastOpen"/>
-  <affected-histogram name="OfflinePages.ExpirePage.PageLifetime"/>
-  <affected-histogram name="OfflinePages.ExpirePage.TimeSinceLastAccess"/>
-  <affected-histogram name="OfflinePages.FirstOpenSinceCreated"/>
   <affected-histogram name="OfflinePages.MhtmlLoadResult"/>
-  <affected-histogram name="OfflinePages.OpenSinceLastOpen"/>
   <affected-histogram name="OfflinePages.PageAccessInterval"/>
   <affected-histogram name="OfflinePages.PageLifetime"/>
   <affected-histogram name="OfflinePages.PageSize"/>
@@ -6137,7 +3602,6 @@
   <affected-histogram name="OfflinePages.SavePage.ComputeDigestTime"/>
   <affected-histogram name="OfflinePages.SavePage.CreateArchiveTime"/>
   <affected-histogram name="OfflinePages.SavePage.PublishArchiveTime"/>
-  <affected-histogram name="OfflinePages.SavePageResult"/>
   <affected-histogram name="OfflinePages.SavePageTime"/>
 </histogram_suffixes>
 
@@ -6155,7 +3619,6 @@
       label="Action: GeneratePageBundle request."/>
   <suffix name="GetOperation" label="Action: GetOperation request."/>
   <affected-histogram name="OfflinePages.Prefetching.ActionAttempts"/>
-  <affected-histogram name="OfflinePages.Prefetching.ActionRetryAttempts"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="Omnibox_BitmapFetchLatencyCacheSplit" separator=".">
@@ -6210,16 +3673,6 @@
   <affected-histogram
       name="PageLoad.Clients.DocWrite.Block.ParseTiming.ParseDuration"/>
   <affected-histogram
-      name="PageLoad.Clients.DocWrite.Block.Timing2.ParseBlockedOnScriptLoad"/>
-  <affected-histogram
-      name="PageLoad.Clients.DocWrite.Block.Timing2.ParseBlockedOnScriptLoad.ParseComplete"/>
-  <affected-histogram
-      name="PageLoad.Clients.DocWrite.Block.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite"/>
-  <affected-histogram
-      name="PageLoad.Clients.DocWrite.Block.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite.ParseComplete"/>
-  <affected-histogram
-      name="PageLoad.Clients.DocWrite.Block.Timing2.ParseDuration"/>
-  <affected-histogram
       name="PageLoad.Clients.MultiTabLoading.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
   <affected-histogram
       name="PageLoad.Clients.MultiTabLoading.DocumentTiming.NavigationToLoadEventFired"/>
@@ -6229,16 +3682,12 @@
       name="PageLoad.Clients.ServiceWorker2.ParseTiming.NavigationToParseStart"/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
-  <affected-histogram name="PageLoad.DocumentTiming.NavigationToFirstLayout"/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
-  <affected-histogram name="PageLoad.Events.Committed"/>
-  <affected-histogram name="PageLoad.Events.Provisional"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstImagePaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/>
-  <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstTextPaint"/>
   <affected-histogram
       name="PageLoad.PaintTiming.ParseStartToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.ParseTiming.NavigationToParseStart"/>
@@ -6246,49 +3695,6 @@
   <affected-histogram
       name="PageLoad.ParseTiming.ParseBlockedOnScriptLoadFromDocumentWrite"/>
   <affected-histogram name="PageLoad.ParseTiming.ParseDuration"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToCommit"/>
-  <affected-histogram
-      name="PageLoad.Timing2.NavigationToDOMContentLoadedEventFired"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstContentfulPaint"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstImagePaint"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstLayout"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstPaint"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstTextPaint"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToLoadEventFired"/>
-  <affected-histogram name="PageLoad.Timing2.ParseBlockedOnScriptLoad"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoad.ParseComplete"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite.ParseComplete"/>
-  <affected-histogram name="PageLoad.Timing2.ParseDuration"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PageLoadEventConditions" separator=".">
-  <suffix name="AfterCommit.BeforePaint" label=""/>
-  <suffix base="true" name="AfterPaint.Before1sDelayedInteraction" label=""/>
-  <suffix base="true" name="AfterPaint.BeforeInteraction" label=""/>
-  <suffix name="BeforeCommit" label=""/>
-  <suffix name="DuringParse" label=""/>
-  <affected-histogram name="PageLoad.AbortTiming.Background"/>
-  <affected-histogram name="PageLoad.AbortTiming.ClientRedirect"/>
-  <affected-histogram name="PageLoad.AbortTiming.Close"/>
-  <affected-histogram name="PageLoad.AbortTiming.ForwardBackNavigation"/>
-  <affected-histogram name="PageLoad.AbortTiming.NewNavigation"/>
-  <affected-histogram name="PageLoad.AbortTiming.Other"/>
-  <affected-histogram name="PageLoad.AbortTiming.Reload"/>
-  <affected-histogram name="PageLoad.AbortTiming.Stop"/>
-  <affected-histogram name="PageLoad.AbortTiming.UnknownNavigation"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.Background"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.ClientRedirect"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.Close"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.ForwardBackNavigation"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.NewNavigation"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.Other"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.Reload"/>
-  <affected-histogram name="PageLoad.Experimental.AbortTiming.Stop"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="PageLoadMetricsAfterPaint" separator=".">
@@ -6332,7 +3738,6 @@
              data reduction proxy where a lite page response was received."/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
-  <affected-histogram name="PageLoad.DocumentTiming.NavigationToFirstLayout"/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Network"/>
@@ -6342,24 +3747,11 @@
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstImagePaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/>
-  <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstTextPaint"/>
   <affected-histogram name="PageLoad.ParseTiming.NavigationToParseStart"/>
   <affected-histogram name="PageLoad.ParseTiming.ParseBlockedOnScriptLoad"/>
   <affected-histogram name="PageLoad.ParseTiming.ParseDuration"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsClientsDataReductionProxyResources"
-    separator=".">
-  <suffix name="NonProxied"
-      label="Resources not loaded through data reduction proxy."/>
-  <suffix name="PercentProxied"
-      label="Percent of resources loaded through data reduction proxy."/>
-  <suffix name="Proxied"
-      label="Resources loaded through data reduction proxy."/>
-  <affected-histogram
-      name="PageLoad.Clients.DataReductionProxy.Experimental.CompletedResources.Network2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsClientsDocWrite" separator="."
     ordering="prefix">
   <suffix name="Clients.DocWrite.Block"
@@ -6378,16 +3770,6 @@
   <affected-histogram
       name="PageLoad.ParseTiming.ParseBlockedOnScriptLoadFromDocumentWrite"/>
   <affected-histogram name="PageLoad.ParseTiming.ParseDuration"/>
-  <affected-histogram name="PageLoad.Timing2.NavigationToFirstContentfulPaint"/>
-  <affected-histogram name="PageLoad.Timing2.ParseBlockedOnScriptLoad"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoad.ParseComplete"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite"/>
-  <affected-histogram
-      name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite.ParseComplete"/>
-  <affected-histogram name="PageLoad.Timing2.ParseDuration"/>
-  <affected-histogram name="PageLoad.Timing2.ParseStartToFirstContentfulPaint"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="PageLoadMetricsClientsFromGoogleSearch" separator="."
@@ -6396,61 +3778,9 @@
       label="PageLoadMetrics that are a result of a navigation from a Google
              web search"/>
   <affected-histogram
-      name="PageLoad.AbortTiming.Close.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.Close.AfterPaint.BeforeInteraction"/>
-  <affected-histogram name="PageLoad.AbortTiming.Close.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.ForwardBackNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.ForwardBackNavigation.AfterPaint.Before1sDelayedInteraction"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.NewNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.NewNavigation.AfterPaint.BeforeInteraction"/>
-  <affected-histogram name="PageLoad.AbortTiming.Other.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.Reload.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.Reload.AfterPaint.Before1sDelayedInteraction"/>
-  <affected-histogram name="PageLoad.AbortTiming.Stop.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.Stop.AfterPaint.BeforeInteraction"/>
-  <affected-histogram name="PageLoad.AbortTiming.Stop.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.AbortTiming.UnknownNavigation.BeforeCommit"/>
-  <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Close.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Close.AfterPaint.BeforeInteraction"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Close.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.ForwardBackNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.ForwardBackNavigation.AfterPaint.Before1sDelayedInteraction"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.NewNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.NewNavigation.AfterPaint.BeforeInteraction"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Other.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Reload.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Reload.AfterPaint.Before1sDelayedInteraction"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Stop.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Stop.AfterPaint.BeforeInteraction"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Stop.BeforeCommit"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay2"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay3"/>
   <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay4"/>
   <affected-histogram
       name="PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame"/>
@@ -6461,7 +3791,6 @@
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstImagePaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/>
-  <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstTextPaint"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint2"/>
   <affected-histogram
@@ -6470,24 +3799,6 @@
   <affected-histogram name="PageLoad.ParseTiming.ParseDuration"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsClientsLoadingPredictor" separator="."
-    ordering="prefix">
-  <obsolete>
-    These suffixes are used to record metrics if LoadingPredictor enabled. As
-    part of crbug.com/1317494, this suffix is replaced by
-    Clients.LoadingPredictor2. The difference are 1.
-    *.Clients.LoadingPredictor2.* include samples from prerendered pages and 2.
-    the value of the UMAs are modified as activation origined for prerendered
-    pages.
-  </obsolete>
-  <suffix base="true" name="Clients.LoadingPredictor"
-      label="PageLoadMetrics with enabled LoadingPredictor"/>
-  <affected-histogram
-      name="PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"/>
-  <affected-histogram
-      name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsClientsLoadingPredictor2"
     separator="." ordering="prefix">
   <suffix base="true" name="Clients.LoadingPredictor2"
@@ -6506,40 +3817,18 @@
       label="The predictor database contained origins for preconnecting for a
              page"/>
   <affected-histogram
-      name="PageLoad.Clients.LoadingPredictor.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"/>
-  <affected-histogram
-      name="PageLoad.Clients.LoadingPredictor.PaintTiming.NavigationToFirstContentfulPaint"/>
-  <affected-histogram
       name="PageLoad.Clients.LoadingPredictor2.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"/>
   <affected-histogram
       name="PageLoad.Clients.LoadingPredictor2.PaintTiming.NavigationToFirstContentfulPaint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsClientsMedia" separator="."
-    ordering="prefix">
-  <obsolete>
-    Removed in favor of Clients.MediaPageLoad2, which includes samples from
-    prerendered pages.
-  </obsolete>
-  <suffix name="Clients.MediaPageLoad"
-      label="PageLoadMetrics for page loads that involved playing a media
-             element."/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Cache"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Cache2"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Network"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Total"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Total2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsClientsMedia2" separator="."
     ordering="prefix">
   <suffix name="Clients.MediaPageLoad2"
       label="PageLoadMetrics for page loads that involved playing a media
              element. Includes samples from prerendered pages"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Cache"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Cache2"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Network"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Total"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Total2"/>
 </histogram_suffixes>
 
@@ -6559,8 +3848,6 @@
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
   <affected-histogram
-      name="PageLoad.Experimental.PaintTiming.ForegroundToFirstMeaningfulPaint"/>
-  <affected-histogram
       name="PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"/>
   <affected-histogram
       name="PageLoad.PaintTiming.ForegroundToFirstContentfulPaint"/>
@@ -6658,9 +3945,6 @@
       name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
   <affected-histogram
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay2"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay3"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/>
@@ -6693,28 +3977,11 @@
   <suffix name="Clients.TabRestore"
       label="PageLoadMetrics that are a result of a navigation caused by a
              tab restore."/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Cache"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Cache2"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Network"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Total"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Total2"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsEarlyHints" separator="."
-    ordering="prefix">
-  <obsolete>
-    Removed in favor of Clients.EarlyHints2.Preload.
-  </obsolete>
-  <suffix name="Clients.EarlyHints.Preload"
-      label="PageLoadMetrics from a page that received preload Link headers
-             via Early Hints responses. Recorded only for main frames."/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay4"/>
-  <affected-histogram
-      name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
-  <affected-histogram
-      name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsEarlyHints2" separator="."
     ordering="prefix">
   <suffix name="Clients.EarlyHints2.Preload"
@@ -6745,12 +4012,8 @@
       name="PageLoad.Clients.ServiceWorker2.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram
       name="PageLoad.Clients.ServiceWorker2.ParseTiming.NavigationToParseStart"/>
-  <affected-histogram
-      name="PageLoad.Clients.SubresourceFilter.ActivationDecision"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Cache"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Cache2"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Network"/>
-  <affected-histogram name="PageLoad.Experimental.Bytes.Total"/>
   <affected-histogram name="PageLoad.Experimental.Bytes.Total2"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
@@ -6764,16 +4027,6 @@
   <affected-histogram name="PageLoad.PageTiming.ForegroundDuration"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsNoEndTime" separator=".">
-  <suffix name="NoEndTime"
-      label="The page load had no recorded end time, so an end time was
-             synthesized at the time the page end notification was processed."/>
-  <affected-histogram
-      name="PageLoad.Experimental.PageTiming.FirstPaintToPageEnd"/>
-  <affected-histogram
-      name="PageLoad.Experimental.PageTiming.NavigationToPageEnd"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsPaintInfo" separator=".">
   <suffix name="WithoutPaint"
       label="The foreground duration for page loads did not reach first
@@ -6805,9 +4058,6 @@
       name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
   <affected-histogram
       name="PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay2"/>
-  <affected-histogram name="PageLoad.InteractiveTiming.FirstInputDelay3"/>
   <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/>
@@ -6828,115 +4078,14 @@
       label="(experimental) Page load metric that is approximately user
              initiated"/>
   <affected-histogram
-      name="PageLoad.AbortTiming.ForwardBackNavigation.BeforeCommit"/>
-  <affected-histogram name="PageLoad.AbortTiming.NewNavigation.BeforeCommit"/>
-  <affected-histogram name="PageLoad.AbortTiming.Reload.BeforeCommit"/>
-  <affected-histogram
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsUserInitiated2" separator=".">
-  <suffix name="BrowserInitiated"
-      label="(experimental) Page load that was initiated from the browser
-             process"/>
-  <suffix name="UserGesture"
-      label="(experimental) Page load that has a user gesture"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.ForwardBackNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.ForwardBackNavigation.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.NewNavigation.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.NewNavigation.BeforeCommit"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Reload.AfterCommit.BeforePaint"/>
-  <affected-histogram
-      name="PageLoad.Experimental.AbortTiming.Reload.BeforeCommit"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PageLoadType" separator="_">
-  <suffix name="HistoryLoad"
-      label="but only for user pressing back or forward"/>
-  <suffix name="LinkLoad"
-      label="deprecated - see LinkLoadReload, LinkLoadNormal,
-             LinkLoadStaleOk, LinkLoadCacheOnly; content initiated, commonly
-             back to a posted page"/>
-  <suffix name="LinkLoadCacheOnly"
-      label="content initiated, commonly back to a posted page, where browser
-             must ONLY use cache"/>
-  <suffix name="LinkLoadNormal"
-      label="content initiated, ordinary link traversal or post"/>
-  <suffix name="LinkLoadReload" label="content initiated, calling reload()"/>
-  <suffix name="LinkLoadStaleOk"
-      label="content initiated, commonly forward or back where stale cached
-             data is very acceptable"/>
-  <suffix name="NormalLoad"
-      label="but only for user entered URL or omnibox search"/>
-  <suffix name="Reload" label="but only for user pressed reload"/>
-  <suffix name="UndefLoad"
-      label="should never happen... as it is only for an client-code error
-             case which should not exist"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.StartToCommit">
-    <with-suffix name="LinkLoadNormal"/>
-    <with-suffix name="NormalLoad"/>
-  </affected-histogram>
-  <affected-histogram name="PLT.StartToFinish">
-    <with-suffix name="LinkLoadNormal"/>
-    <with-suffix name="NormalLoad"/>
-  </affected-histogram>
-  <affected-histogram name="Renderer4.BeginToFinish"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PageLoadType" separator="_">
-  <suffix name="HistoryLoad"
-      label="but only for user pressing back or forward"/>
-  <suffix name="LinkLoad"
-      label="deprecated - see LinkLoadReload, LinkLoadNormal,
-             LinkLoadStaleOk, LinkLoadCacheOnly; content initiated, commonly
-             back to a posted page"/>
-  <suffix name="LinkLoadCacheOnly"
-      label="content initiated, commonly back to a posted page, where browser
-             must ONLY use cache"/>
-  <suffix name="LinkLoadNormal"
-      label="content initiated, ordinary link traversal or post"/>
-  <suffix name="LinkLoadReload" label="content initiated, calling reload()"/>
-  <suffix name="LinkLoadStaleOk"
-      label="content initiated, commonly forward or back where stale cached
-             data is very acceptable"/>
-  <suffix name="NormalLoad"
-      label="but only for user entered URL or omnibox search"/>
-  <suffix name="Reload" label="but only for user pressed reload"/>
-  <suffix name="UndefLoad"
-      label="should never happen... as it is only for an client-code error
-             case which should not exist"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.StartToCommit">
-    <with-suffix name="LinkLoadNormal"/>
-    <with-suffix name="NormalLoad"/>
-  </affected-histogram>
-  <affected-histogram name="PLT.StartToFinish">
-    <with-suffix name="LinkLoadNormal"/>
-    <with-suffix name="NormalLoad"/>
-  </affected-histogram>
-  <affected-histogram name="Renderer4.BeginToFinish"/>
-  <affected-histogram name="Renderer4.BeginToFinishDoc"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ParallelDownload" separator=".">
   <suffix name="ParallelDownload"
       label="Download that uses parallel requests."/>
   <affected-histogram name="Download.Counts"/>
-  <affected-histogram name="Download.InterruptedAtEndReason"/>
-  <affected-histogram name="Download.InterruptedOverrunBytes"/>
   <affected-histogram name="Download.InterruptedReason"/>
-  <affected-histogram name="Download.InterruptedReceivedSizeK"/>
-  <affected-histogram name="Download.InterruptedTotalSizeK"/>
-  <affected-histogram name="Download.InterruptedUnderrunBytes"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="ParallelizableDownload" separator=".">
@@ -6959,26 +4108,6 @@
   <affected-histogram name="PasswordManager.NewlySavedPasswordIsGenerated"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PasswordCustomPassphrase" separator=".">
-  <suffix name="WithCustomPassphrase" label=""/>
-  <suffix name="WithoutCustomPassphrase" label=""/>
-  <affected-histogram name="PasswordManager.AccountsPerSite"/>
-  <affected-histogram name="PasswordManager.AccountsPerSite.AutoGenerated"/>
-  <affected-histogram name="PasswordManager.AccountsPerSite.UserCreated"/>
-  <affected-histogram name="PasswordManager.BlacklistedSites"/>
-  <affected-histogram name="PasswordManager.TimesGeneratedPasswordUsed"/>
-  <affected-histogram name="PasswordManager.TotalAccounts.AutoGenerated"/>
-  <affected-histogram name="PasswordManager.TotalAccounts.UserCreated"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PasswordGenerated" separator=".">
-  <suffix base="true" name="AutoGenerated" label=""/>
-  <suffix base="true" name="Overall" label=""/>
-  <suffix base="true" name="UserCreated" label=""/>
-  <affected-histogram name="PasswordManager.AccountsPerSite"/>
-  <affected-histogram name="PasswordManager.TotalAccounts"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PasswordProtectionTriggerForAnyPasswordEntry"
     separator=".">
   <suffix name="AnyPasswordEntry"
@@ -7129,51 +4258,6 @@
   <affected-histogram name="PasswordProtection.Verdict"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PasswordProtectionVerdict" separator=".">
-  <suffix name="LowReputation"
-      label="Password protection reponse with low reputation verdict"/>
-  <suffix name="Phishing"
-      label="Password protection response with phishing verdict"/>
-  <suffix name="Safe" label="Password protection response with safe verdict"/>
-  <affected-histogram name="PasswordProtection.ReferrerChainSize"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PasswordReuseSourceRealm" separator=".">
-  <suffix name="FromHttpRealm"
-      label="The account in question was saved on an HTTP site."/>
-  <suffix name="FromHttpsRealm"
-      label="The account in question was saved on a HTTPS site (including
-             those with certificate issues)."/>
-  <affected-histogram name="PasswordManager.AccountsReusingPassword"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PasswordReuseTargetRealm" separator=".">
-  <suffix name="OnAnyRealmWithDifferentHost"
-      label="The number of other accounts whose realms have different hosts
-             than the account in question, and their scheme is either HTTP or
-             HTTPS."/>
-  <suffix name="OnHttpRealmWithDifferentHost"
-      label="The number of other accounts whose realms have HTTP scheme and
-             different hosts than the account in question."/>
-  <suffix name="OnHttpRealmWithSameHost"
-      label="The number of other accounts whose realms have HTTP scheme and
-             the same host as the account in question."/>
-  <suffix name="OnHttpsRealmWithDifferentHost"
-      label="The number of other accounts whose realms have HTTPS scheme and
-             different hosts than the account in question."/>
-  <suffix name="OnHttpsRealmWithSameHost"
-      label="The number of other accounts whose realms have HTTPS scheme and
-             the same host as the account in question."/>
-  <suffix name="OnPSLMatchingRealm"
-      label="The number of other accounts whose realms are public suffix
-             matches to that of the account in question (the scheme is always
-             the same in these cases)."/>
-  <affected-histogram
-      name="PasswordManager.AccountsReusingPassword.FromHttpRealm"/>
-  <affected-histogram
-      name="PasswordManager.AccountsReusingPassword.FromHttpsRealm"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PasswordSecurityOrigin" separator=".">
   <suffix name="InsecureOrigin"
       label="The recording took place on an insecure origin."/>
@@ -7239,55 +4323,26 @@
   <suffix name="VideoCapture" label="Camera permission actions"/>
   <suffix name="VR" label="VR permission actions"/>
   <suffix name="WindowPlacement" label="Window Management permission actions"/>
-  <affected-histogram name="ContentSettings.PermissionActions"/>
-  <affected-histogram name="ContentSettings.PermissionActionsInsecureOrigin"/>
-  <affected-histogram name="ContentSettings.PermissionActionsSecureOrigin"/>
   <affected-histogram name="Permissions.Action"/>
   <affected-histogram name="Permissions.DSE.AutoPermissionRevertTransition"/>
   <affected-histogram name="Permissions.DSE.EffectiveSetting"/>
   <affected-histogram name="Permissions.MissingOSLevelPermission.Action"/>
   <affected-histogram name="Permissions.MissingOSLevelPermission.ShouldShow"/>
-  <affected-histogram name="Permissions.Prompt.Accepted.Persisted"/>
-  <affected-histogram name="Permissions.Prompt.Accepted.PriorDismissCount"/>
   <affected-histogram name="Permissions.Prompt.Accepted.PriorDismissCount2"/>
-  <affected-histogram name="Permissions.Prompt.Accepted.PriorIgnoreCount"/>
   <affected-histogram name="Permissions.Prompt.Accepted.PriorIgnoreCount2"/>
   <affected-histogram
       name="Permissions.Prompt.AcceptedOnce.PriorDismissCount2"/>
   <affected-histogram name="Permissions.Prompt.AcceptedOnce.PriorIgnoreCount2"/>
-  <affected-histogram name="Permissions.Prompt.Denied.Persisted"/>
-  <affected-histogram name="Permissions.Prompt.Denied.PriorDismissCount"/>
   <affected-histogram name="Permissions.Prompt.Denied.PriorDismissCount2"/>
-  <affected-histogram name="Permissions.Prompt.Denied.PriorIgnoreCount"/>
   <affected-histogram name="Permissions.Prompt.Denied.PriorIgnoreCount2"/>
-  <affected-histogram name="Permissions.Prompt.Dismissed.PriorDismissCount"/>
   <affected-histogram name="Permissions.Prompt.Dismissed.PriorDismissCount2"/>
-  <affected-histogram name="Permissions.Prompt.Dismissed.PriorIgnoreCount"/>
   <affected-histogram name="Permissions.Prompt.Dismissed.PriorIgnoreCount2"/>
-  <affected-histogram name="Permissions.Prompt.Ignored.PriorDismissCount"/>
   <affected-histogram name="Permissions.Prompt.Ignored.PriorDismissCount2"/>
-  <affected-histogram name="Permissions.Prompt.Ignored.PriorIgnoreCount"/>
   <affected-histogram name="Permissions.Prompt.Ignored.PriorIgnoreCount2"/>
-  <affected-histogram name="Permissions.Requested.CrossOrigin"/>
   <affected-histogram name="Permissions.Revocation.ElapsedTimeSinceGrant"/>
   <affected-histogram name="Permissions.Usage.ElapsedTimeSinceGrant"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PhysicalWebDebugActions" separator=".">
-  <suffix name="ChromeStart" label="when Chrome first starts up"/>
-  <suffix name="LaunchFromDiagnostics"
-      label="when the user launches the ListUrlActivity from the Physical Web
-             diagnostics page"/>
-  <suffix name="LaunchFromPreferences"
-      label="when the user launches the ListUrlActivity from the Physical Web
-             preferencs screen"/>
-  <affected-histogram name="PhysicalWeb.State.Bluetooth"/>
-  <affected-histogram name="PhysicalWeb.State.DataConnectionActive"/>
-  <affected-histogram name="PhysicalWeb.State.LocationPermission"/>
-  <affected-histogram name="PhysicalWeb.State.LocationServices"/>
-  <affected-histogram name="PhysicalWeb.State.Preference"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Platform_FirmwareType" separator=".">
   <suffix name="EC" label="Embedded Controller firmware"/>
   <suffix name="Main" label="Main processor firmware"/>
@@ -7365,8 +4420,6 @@
       name="Net.QuicConnectivityMonitor.PercentageActiveDegradingSessions"/>
   <affected-histogram
       name="Net.QuicConnectivityMonitor.PercentageAllDegradedSessions"/>
-  <affected-histogram name="Net.QuicStreamFactory.NumDegradingSessions"/>
-  <affected-histogram name="Net.QuicStreamFactory.PercentageDegradingSessions"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="PlatformStorageUfsLifeUsed" separator=".">
@@ -7392,21 +4445,6 @@
   <affected-histogram name="NaCl.Perf.Size.PNaClTranslatedNexe"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PositionVariants" separator="_">
-  <suffix name="0_0" label="Only snippets on position 0"/>
-  <suffix name="1_2" label="Only snippets on position 1-2"/>
-  <suffix name="3_4" label="Only snippets on position 3-4"/>
-  <suffix name="5_9" label="Only snippets on position 5-9"/>
-  <affected-histogram name="NewTabPage.Snippets.CardClickedAge"/>
-  <affected-histogram name="NewTabPage.Snippets.CardClickedScore"/>
-  <affected-histogram name="NewTabPage.Snippets.CardClickedScoreNew"/>
-  <affected-histogram name="NewTabPage.Snippets.CardLongPressedAge"/>
-  <affected-histogram name="NewTabPage.Snippets.CardLongPressedScoreNew"/>
-  <affected-histogram name="NewTabPage.Snippets.CardShownAge"/>
-  <affected-histogram name="NewTabPage.Snippets.CardShownScore"/>
-  <affected-histogram name="NewTabPage.Snippets.CardShownScoreNew"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Power_CpuTimeProcessAndCoreTypes" separator=".">
   <suffix name="BigLittle.Big.Browser"
       label="Browser processes on big cores of a BIG.little CPU"/>
@@ -7519,8 +4557,6 @@
   <suffix name="Preferences" label="Preferences file"/>
   <suffix name="Secure_Preferences" label="Secure Preferences file"/>
   <affected-histogram name="Settings.JsonDataReadSizeKilobytes"/>
-  <affected-histogram name="Settings.JsonDataSizeKilobytes"/>
-  <affected-histogram name="Settings.JsonDataWriteCount"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="Prefetch" separator="_">
@@ -7529,44 +4565,6 @@
   <suffix name="ContentPrefetchPrefetchOn"
       label="prefetch is enabled but prerender is disabled."/>
   <affected-histogram name="Net.HttpTimeToFirstByte"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish"/>
-  <affected-histogram name="PLT.BeginToFinish_ContentPrefetcher"/>
-  <affected-histogram name="PLT.BeginToFinish_ContentPrefetcherReferrer"/>
-  <affected-histogram name="PLT.BeginToFinishDoc"/>
-  <affected-histogram name="PLT.BeginToFinishDoc_ContentPrefetcher"/>
-  <affected-histogram name="PLT.BeginToFinishDoc_ContentPrefetcherReferrer"/>
-  <affected-histogram name="PLT.PerceivedLoadTime"/>
-  <affected-histogram name="PLT.PerceivedLoadTime_PrerenderLoad"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PrerenderPrefetchAge" separator=".">
-  <suffix name="Cold" label="Prefetch too old to skip revalidation."/>
-  <suffix name="Reference"
-      label="No prefetch. Warning: do not compare with the load times of
-             prefetched pages (bias)."/>
-  <suffix name="Warm" label="Prefetch skips revalidation."/>
-  <affected-histogram name="Prerender.PrefetchTTFCP"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PrerenderPrefetchMainResourceType" separator=".">
-  <suffix name="Cacheable" label="Main resource cacheable."/>
-  <suffix name="NoStore" label="Main resource no-store."/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Reference"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PrerenderPrefetchPaintVisibility" separator=".">
-  <suffix name="Hidden" label="Page was hidden during rendering."/>
-  <suffix name="Visible" label="Page visible for all of rendering."/>
-  <affected-histogram name="Prerender.PerceivedTTFCPRecorded"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.Cacheable"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.NoStore"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Reference.Cacheable"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Reference.NoStore"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.Cacheable"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.NoStore"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="PrerenderSource" separator="_" ordering="prefix">
@@ -7587,54 +4585,12 @@
   <suffix name="webnext" label="Link triggered prerender, rel=next."/>
   <suffix name="websame"
       label="Link triggered prerender, rel=prerender, same domain."/>
-  <affected-histogram name="Prerender.AbandonTimeUntilUsed"/>
-  <affected-histogram name="Prerender.CookieSendType"/>
-  <affected-histogram name="Prerender.CookieStatus"/>
-  <affected-histogram name="Prerender.Event"/>
   <affected-histogram name="Prerender.FinalStatus"/>
-  <affected-histogram name="Prerender.LocalPredictorTimeUntilUsed"/>
-  <affected-histogram name="Prerender.NetworkBytesUsed"/>
   <affected-histogram name="Prerender.NetworkBytesWasted"/>
-  <affected-histogram name="Prerender.NoStatePrefetchAge"/>
   <affected-histogram name="Prerender.NoStatePrefetchMainResourceRedirects"/>
   <affected-histogram name="Prerender.NoStatePrefetchResponseTypes"/>
   <affected-histogram name="Prerender.NoStatePrefetchSubResourceRedirects"/>
-  <affected-histogram name="Prerender.PageVisitedStatus"/>
-  <affected-histogram name="Prerender.PerceivedPLT"/>
-  <affected-histogram name="Prerender.PerceivedPLTFirstAfterMiss"/>
-  <affected-histogram name="Prerender.PerceivedPLTFirstAfterMissAnyOnly"/>
-  <affected-histogram name="Prerender.PerceivedPLTFirstAfterMissBoth"/>
-  <affected-histogram
-      name="Prerender.PerceivedPLTFirstAfterMissNonOverlapping"/>
-  <affected-histogram
-      name="Prerender.PerceivedPLTFirstAfterMissNonOverlappingOnly"/>
-  <affected-histogram name="Prerender.PerceivedPLTMatched"/>
-  <affected-histogram name="Prerender.PerceivedPLTWindowed"/>
-  <affected-histogram name="Prerender.PerceivedPLTWindowNotMatched"/>
-  <affected-histogram name="Prerender.PerceivedTTFCPRecorded.Hidden"/>
-  <affected-histogram name="Prerender.PerceivedTTFCPRecorded.Visible"/>
-  <affected-histogram name="Prerender.PrefetchAge"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.Cacheable.Hidden"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.Cacheable.Visible"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.NoStore.Hidden"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Cold.NoStore.Visible"/>
-  <affected-histogram
-      name="Prerender.PrefetchTTFCP.Reference.Cacheable.Hidden"/>
-  <affected-histogram
-      name="Prerender.PrefetchTTFCP.Reference.Cacheable.Visible"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Reference.NoStore.Hidden"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Reference.NoStore.Visible"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.Cacheable.Hidden"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.Cacheable.Visible"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.NoStore.Hidden"/>
-  <affected-histogram name="Prerender.PrefetchTTFCP.Warm.NoStore.Visible"/>
-  <affected-histogram name="Prerender.PrerenderNotSwappedInPLT"/>
   <affected-histogram name="Prerender.PrerendersPerSessionCount"/>
-  <affected-histogram name="Prerender.SimulatedLocalBrowsingBaselinePLT"/>
-  <affected-histogram name="Prerender.SimulatedLocalBrowsingPLT"/>
-  <affected-histogram name="Prerender.TimeBetweenPrerenderRequests"/>
-  <affected-histogram name="Prerender.TimeSinceLastRecentVisit"/>
-  <affected-histogram name="Prerender.TimeUntilUsed2"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="Previews_Types" separator=".">
@@ -7643,12 +4599,9 @@
       label="Page Info opened when https image compression was enabled"/>
   <suffix name="None" label="No preview was served"/>
   <affected-histogram name="Previews.EligibilityReason"/>
-  <affected-histogram name="Previews.InfoBarAction"/>
   <affected-histogram name="Previews.OmniboxAction"/>
-  <affected-histogram name="Previews.OptimizationFilterStatus"/>
   <affected-histogram name="Previews.OptOut.UserOptedOut"/>
   <affected-histogram name="Previews.PageEndReason"/>
-  <affected-histogram name="Previews.Triggered.EffectiveConnectionType"/>
   <affected-histogram name="Previews.Triggered.EffectiveConnectionType2"/>
 </histogram_suffixes>
 
@@ -8242,24 +5195,6 @@
   <affected-histogram name="Network.Shill.Wifi.TimeToScanAndConnect"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ProxyConnectionImpact" separator="_">
-  <suffix name="proxy_connections_8"
-      label="with 8 connections per proxy server"/>
-  <suffix name="proxy_connections_16"
-      label="with 16 connections per proxy server"/>
-  <suffix name="proxy_connections_32"
-      label="with 32 connections per proxy server"/>
-  <suffix name="proxy_connections_64"
-      label="with 64 connections per proxy server"/>
-  <affected-histogram name="Net.HttpProxySocketRequestTime"/>
-  <affected-histogram name="Net.SocksSocketRequestTime"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadReload"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadStaleOk"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="QueryTimeSuffix" separator=".">
   <suffix name="0" label="N = 0"/>
   <suffix name="1" label="N = 1"/>
@@ -8267,9 +5202,7 @@
   <suffix name="3" label="N = 3"/>
   <suffix name="4" label="N = 4"/>
   <suffix name="5" label="N = 5"/>
-  <affected-histogram name="Omnibox.QueryTime"/>
   <affected-histogram name="Omnibox.QueryTime2"/>
-  <affected-histogram name="ShortcutsProvider.QueryIndexTime"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="QuicConnectionType" separator="">
@@ -8279,7 +5212,6 @@
   <affected-histogram name="Net.QuicSession.ConnectRandomPort"/>
   <affected-histogram
       name="Net.QuicSession.ConnectRandomPortRequiringConfirmation"/>
-  <affected-histogram name="Net.QuicSession.HandshakeRoundTrips"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="QuicPortSelection" separator="">
@@ -8328,15 +5260,6 @@
              of 02/2018. Using suffix Gpu and Software instead."/>
   <suffix name="Gpu" label="This metric is for only gpu raster."/>
   <suffix name="Software" label="This metric is for only software raster."/>
-  <affected-histogram name="Compositing.Browser.CachedImagesCount"/>
-  <affected-histogram name="Compositing.Browser.RasterTask.RasterPixelsPerMs"/>
-  <affected-histogram name="Compositing.Browser.RasterTask.RasterPixelsPerMs2"/>
-  <affected-histogram name="Compositing.Browser.RasterTask.RasterUs"/>
-  <affected-histogram name="Compositing.Renderer.CachedImagesCount"/>
-  <affected-histogram name="Compositing.Renderer.RasterTask.RasterPixelsPerMs"/>
-  <affected-histogram
-      name="Compositing.Renderer.RasterTask.RasterPixelsPerMs2"/>
-  <affected-histogram name="Compositing.Renderer.RasterTask.RasterUs"/>
   <affected-histogram name="Renderer4.ImageDecodeTaskDurationUs"/>
   <affected-histogram name="Renderer4.ImageDecodeTaskDurationUs.Jpeg"/>
   <affected-histogram name="Renderer4.ImageDecodeTaskDurationUs.Other"/>
@@ -8407,109 +5330,6 @@
   <affected-histogram name="Media.Remoting.SessionStopTrigger"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="RendererEventLatency" separator=".">
-  <suffix name="Char" label="The Char event occurs on textual keyboard input."/>
-  <suffix name="ContextMenu" label="For ContextMenu event."/>
-  <suffix name="GestureDoubleTap"
-      label="A GestureDoubleTap occurs when the user double taps on a
-             touchscreen."/>
-  <suffix name="GestureFlingCancel"
-      label="A GestureFlingCancel is sent to the renderer to cancel any
-             active flings."/>
-  <suffix name="GestureFlingStart"
-      label="A GestureFlingStart is sent when the user quickly flicks on a
-             touchscreen."/>
-  <suffix name="GestureLongPress"
-      label="A GestureLongPress is sent when the user taps down and holds
-             their finger on a touchscreen."/>
-  <suffix name="GestureLongTap"
-      label="A GestureLongTap is sent when the user taps down on a
-             touchscreen, holds their finger for a while, then releases."/>
-  <suffix name="GesturePinchBegin"
-      label="A GesturePinchBegin is sent when a user starts a pinch zoom
-             motion on a touchscreen."/>
-  <suffix name="GesturePinchEnd"
-      label="A GesturePinchEnd is sent when the user releases their fingers
-             from the touchscreen after performing a pinch zoom motion."/>
-  <suffix name="GesturePinchUpdate"
-      label="GesturePinchUpdate events are sent while the user is performing
-             a pinch zoom motion on a touch screen. GesturePinchUpdate events
-             are sent as the user changes the distance between their fingers."/>
-  <suffix name="GestureScrollBegin"
-      label="A GestureScrollBegin is sent at the beginning of a gesture
-             scroll on a touchscreen."/>
-  <suffix name="GestureScrollEnd"
-      label="A GestureScrollEnd is sent when the user releases their finger
-             after a gesture scroll on a touchscreen."/>
-  <suffix name="GestureScrollUpdate"
-      label="GestureScrollUpdate events are sent as the user drags their
-             finger along the touchscreen during a gesture scroll."/>
-  <suffix name="GestureScrollUpdateWithoutPropagation"
-      label="GestureScrollUpdateWithoutPropagation events are scroll updates
-             that shouldn't bubble, generated by a gesture fling."/>
-  <suffix name="GestureShowPress"
-      label="A GestureShowPress event is sent when the user presses down on
-             the touchscreen but before a GestureTapDown."/>
-  <suffix name="GestureTap"
-      label="A GestureTap is sent when the user presses down and releases on
-             a touchscreen."/>
-  <suffix name="GestureTapCancel"
-      label="A GestureTapCancel is sent to cancel a pending GestureTap event.
-             For example, if the user taps down but drags their finger
-             instead of releasing it."/>
-  <suffix name="GestureTapDown"
-      label="A GestureTapDown is sent when the user presses on the
-             touchscreen in what could potentially be a full GestureTap
-             event."/>
-  <suffix name="GestureTapUnconfirmed"
-      label="A GestureTapUnconfirmed is sent when the user taps the
-             touchscreen but, due to a delay, the GestureTap isn't sent yet."/>
-  <suffix name="GestureTwoFingerTap"
-      label="A GestureTwoFingerTap is sent when the user presses down a
-             releases on a touchscreen with two fingers."/>
-  <suffix name="KeyDown"
-      label="A KeyDown event is sent when a keyboard key is pressed down."/>
-  <suffix name="KeyUp"
-      label="A KeyUp event is sent when a depressed keyboard key is released."/>
-  <suffix name="MouseDown"
-      label="A MouseDown event is sent when the user click down a mouse
-             button."/>
-  <suffix name="MouseEnter"
-      label="A MouseEnter event is sent when the mouse cursor enters the
-             renderer area."/>
-  <suffix name="MouseLeave"
-      label="A MouseLeave event is sent when the mouse cursor leaves the
-             renderer area."/>
-  <suffix name="MouseMove"
-      label="A MouseMove event is sent when the mouse cursor moves within the
-             renderer area."/>
-  <suffix name="MouseUp"
-      label="A MouseUp event is sent when a depressed mouse button is
-             released."/>
-  <suffix name="MouseWheel"
-      label="A MouseWheel event is sent when the user scrolls using the mouse
-             wheel within the renderer area."/>
-  <suffix name="RawKeyDown"
-      label="A RawKeyDown event is a wrapper around a native key event."/>
-  <suffix name="TouchCancel"
-      label="A TouchCancel is used to cancel an existing touch point. For
-             example, if the user drags a finger outside the bounds of the
-             renderer."/>
-  <suffix name="TouchEnd"
-      label="A TouchEnd is send when the user lifts a finger from the
-             touchscreen."/>
-  <suffix name="TouchMove"
-      label="A TouchMove is sent when the user moves a finger along the
-             touchscreen."/>
-  <suffix name="TouchStart"
-      label="A TouchStart is sent when the user first touches a finger to the
-             touchscreen."/>
-  <suffix name="Undefined" label="For unknown or undefined events."/>
-  <affected-histogram name="Event.Latency.Renderer"/>
-  <affected-histogram name="Event.Latency.Renderer2"/>
-  <affected-histogram name="Event.Latency.RendererImpl"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="RendererScheduler_AfterNthMinuteInBackgroundSplit"
     separator=".">
   <suffix name="Background.AfterFifthMinute"
@@ -8523,36 +5343,6 @@
   <affected-histogram name="RendererScheduler.TaskDurationPerTaskType2"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="RendererScheduler_FrameQueueType" separator=".">
-  <suffix name="default_tq" label="Default task queue"/>
-  <suffix name="frame_deferrable_tq" label="Frame deferrable task queue"/>
-  <suffix name="frame_loading_control_tq"
-      label="Frame loading control task queue"/>
-  <suffix name="frame_loading_tq" label="Frame loading task queue"/>
-  <suffix name="frame_pausable_tq" label="Frame pausable task queue"/>
-  <suffix name="frame_throttleable_tq" label="Frame throttleable task queue"/>
-  <suffix name="frame_unpausable_tq" label="Frame unpausable task queue"/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherAgentsWhileTaskReady.Hidden"/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherAgentsWhileTaskReady.Visible"/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherFramesWhileTaskReady.Hidden"/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherFramesWhileTaskReady.Visible"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="RendererScheduler_FrameVisibility" separator=".">
-  <suffix name="Hidden"
-      label="The frame is hidden when the task starts running."/>
-  <suffix name="Visible"
-      label="The frame is visible when the task starts running."/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherAgentsWhileTaskReady"/>
-  <affected-histogram
-      name="RendererScheduler.TimeRunningOtherFramesWhileTaskReady"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="RendererScheduler_MainThreadLoadSplit" separator=".">
   <suffix name="Background"
       label="Main thread load when the renderer is backgrounded. This does
@@ -8588,85 +5378,10 @@
     separator=".">
   <suffix name="Background" label=""/>
   <suffix name="Foreground" label=""/>
-  <affected-histogram name="RendererScheduler.TaskCPUDurationPerThreadType"/>
-  <affected-histogram name="RendererScheduler.TaskDurationPerTaskType"/>
   <affected-histogram name="RendererScheduler.TaskDurationPerTaskType2"/>
-  <affected-histogram name="RendererScheduler.TaskDurationPerThreadType"/>
   <affected-histogram name="RendererScheduler.TaskDurationPerThreadType2"/>
 </histogram_suffixes>
 
-<histogram_suffixes
-    name="RendererScheduler_TaskDurationPerFrameOriginTypeSplit" separator=".">
-  <suffix name="DedicatedWorker" label=""/>
-  <suffix name="DedicatedWorker.Background" label=""/>
-  <affected-histogram name="RendererScheduler.TaskDurationPerFrameOriginType"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="RendererScheduler_TaskDurationPerQueueTypeSplit"
-    separator=".">
-  <suffix name="Background"
-      label="Time spent in tasks of a particular queue type when the renderer
-             is in the background."/>
-  <suffix name="Background.AfterFifthMinute"
-      label="Time spent in tasks of a particular queue type starting from the
-             sixth minute after backgrounding the renderer. The renderer is
-             expected to be mostly idle during this period."/>
-  <suffix name="Background.AfterTenthMinute"
-      label="Time spent in tasks of a particular type starting from the
-             eleventh minute after backgrounding the renderer. The renderer
-             is expected to be mostly idle during this period."/>
-  <suffix name="Background.FifthMinute"
-      label="Time spent in tasks of a particular queue type during the fifth
-             minute after backgrounding the renderer."/>
-  <suffix name="Background.FirstMinute"
-      label="Time spent in tasks of a particular queue type during the first
-             minute after backgrounding the renderer. A large amount of
-             loading tasks are expected during this period."/>
-  <suffix name="Background.FourthMinute"
-      label="Time spent in tasks of a particular queue type during the fourth
-             minute after backgrounding the renderer."/>
-  <suffix name="Background.KeepAlive.AfterFifthMinute"
-      label="Time spent in tasks of a particular queue type starting from the
-             sixth minute after backgrounding the renderer when keep-alive
-             signal is present."/>
-  <suffix name="Background.KeepAlive.AfterTenthMinute"
-      label="Time spent in tasks of a particular queue type starting from the
-             eleventh minute after backgrounding the renderer when keep-alive
-             signal is present."/>
-  <suffix name="Background.SecondMinute"
-      label="Time spent in tasks of a particular queue type during the second
-             minute after backgrounding the renderer."/>
-  <suffix name="Background.ThirdMinute"
-      label="Time spent in tasks of a particular queue type during the third
-             minute after backgrounding the renderer."/>
-  <suffix name="Foreground"
-      label="Time spent in tasks of a particular queue type when the renderer
-             is in the foreground. Please note that individual tabs in this
-             renderer can be backgrounded."/>
-  <suffix name="Foreground.AfterThirdMinute"
-      label="Time spent in tasks of a particular queue type starting from the
-             fourth minute after foregrounding the renderer."/>
-  <suffix name="Foreground.FirstMinute"
-      label="Time spent in tasks of a particular queue type during the first
-             minute after foregrounding the renderer."/>
-  <suffix name="Foreground.SecondMinute"
-      label="Time spent in tasks of a particular queue type during the second
-             minute after foregrounding the renderer."/>
-  <suffix name="Foreground.ThirdMinute"
-      label="Time spent in tasks of a particular queue type during the third
-             minute after foregrounding the renderer."/>
-  <suffix name="Hidden"
-      label="Time spent in tasks of a particular queue type when the renderer
-             is hidden."/>
-  <suffix name="HiddenMusic"
-      label="Time spent in tasks of a particular queue type when the renderer
-             is hidden and is playing audible sound."/>
-  <suffix name="Visible"
-      label="Time spent in tasks of a particular queue type when the renderer
-             is visible."/>
-  <affected-histogram name="RendererScheduler.TaskDurationPerQueueType2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="RendererScheduler_TaskDurationPerTaskTypeSplit"
     separator=".">
   <suffix name="UseCaseInputHandling" label=""/>
@@ -8697,29 +5412,6 @@
   <affected-histogram name="NewTabPage.RequestThrottler.RequestStatus"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ResourceLoaderSizeSlice" separator=".">
-  <suffix name="LT_2kB" label="Sliced for resources smaller than 2kB."/>
-  <suffix name="LT_32kB"
-      label="Sliced for resources smaller than 32kB and larger than 2kB."/>
-  <suffix name="LT_512kB"
-      label="Sliced for resources smaller than 512kB and larger than 32kB."/>
-  <suffix name="Over_512kB" label="Sliced for resources larger than 512kB."/>
-  <affected-histogram name="Net.ResourceLoader.ResponseStartToEnd"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="ResourceLoadScheduler_FrameType" separator=".">
-  <suffix name="MainframeNotThrottled" label="Main frame, not throttled"/>
-  <suffix name="MainframeThrottled" label="Main frame, throttled"/>
-  <suffix name="SubframeNotThrottled" label="Sub frame, not throttled"/>
-  <suffix name="SubframeThrottled" label="Sub frame, throttled"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.DecodedBytes"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.PeakRequests"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.TotalDecodedBytes"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.TotalRequestCount"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.TotalTrafficBytes"/>
-  <affected-histogram name="Blink.ResourceLoadScheduler.TrafficBytes"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ResourceSchedulerPeakDelayableRequestsInFlight"
     separator=".">
   <suffix name="LayoutBlocking"
@@ -8776,10 +5468,6 @@
   <affected-histogram
       name="Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite"/>
   <affected-histogram name="Blink.MemoryCache.RevalidationPolicy.Preload"/>
-  <affected-histogram name="PreloadScanner.Counts"/>
-  <affected-histogram name="PreloadScanner.Counts.Miss"/>
-  <affected-histogram name="PreloadScanner.Counts2"/>
-  <affected-histogram name="PreloadScanner.Counts2.Miss"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="RoamSecurityType" separator=".">
@@ -8866,68 +5554,32 @@
       name="SafeBrowsing.V4ProcessFullUpdate.AdditionsHashesCount2"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessFullUpdate.ApplyUpdate.Result"/>
-  <affected-histogram name="SafeBrowsing.V4ProcessFullUpdate.ApplyUpdate.Time"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessFullUpdate.ApplyUpdateDuration"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessFullUpdate.DecodeAdditions.Result"/>
   <affected-histogram
-      name="SafeBrowsing.V4ProcessFullUpdate.DecodeAdditions.Time"/>
-  <affected-histogram name="SafeBrowsing.V4ProcessFullUpdate.MergeUpdate.Time"/>
-  <affected-histogram
       name="SafeBrowsing.V4ProcessFullUpdate.RemovalsHashesCount"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.AdditionsHashesCount"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdate.Result"/>
   <affected-histogram
-      name="SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdate.Time"/>
-  <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdateDuration"/>
   <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.DecodeAdditions.Result"/>
   <affected-histogram
-      name="SafeBrowsing.V4ProcessPartialUpdate.DecodeAdditions.Time"/>
-  <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.DecodeRemovals.Result"/>
   <affected-histogram
-      name="SafeBrowsing.V4ProcessPartialUpdate.DecodeRemovals.Time"/>
-  <affected-histogram
-      name="SafeBrowsing.V4ProcessPartialUpdate.MergeUpdate.Time"/>
-  <affected-histogram
       name="SafeBrowsing.V4ProcessPartialUpdate.RemovalsHashesCount"/>
   <affected-histogram name="SafeBrowsing.V4ReadFromDisk.ApplyUpdate.Result"/>
-  <affected-histogram name="SafeBrowsing.V4ReadFromDisk.ApplyUpdate.Time"/>
   <affected-histogram
       name="SafeBrowsing.V4ReadFromDisk.DecodeAdditions.Result"/>
-  <affected-histogram name="SafeBrowsing.V4ReadFromDisk.DecodeAdditions.Time"/>
-  <affected-histogram name="SafeBrowsing.V4ReadFromDisk.MergeUpdate.Time"/>
   <affected-histogram
       name="SafeBrowsing.V4ReadFromDisk.VerifyChecksumDuration"/>
   <affected-histogram name="SafeBrowsing.V4Store.IsStoreValid"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="SafeBrowsing_V4UnusedStore_Metrics" separator=".">
-  <suffix name="AnyIpMalware" label=""/>
-  <suffix name="ChromeFilenameClientIncident" label=""/>
-  <suffix name="UrlSuspiciousSiteId" label=""/>
-  <affected-histogram name="SafeBrowsing.V4UnusedStoreFileExists"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="SafeBrowsingLists" separator=".">
-  <suffix name="Browse" label="Browse"/>
-  <suffix name="CsdWhitelist" label="CsdWhitelist"/>
-  <suffix name="Download" label="Download"/>
-  <suffix name="DownloadWhitelist" label="DownloadWhitelist"/>
-  <suffix name="ExtensionBlacklist" label="ExtensionBlacklist"/>
-  <suffix name="InclusionWhitelist" label="InclusionWhitelist"/>
-  <suffix name="IPBlacklist" label="IPBlacklist"/>
-  <suffix name="ResourceBlacklist" label="ResourceBlacklist"/>
-  <suffix name="UnwantedSoftware" label="UnwantedSoftware"/>
-  <affected-histogram name="SB2.DatabaseSizeKilobytes"/>
-  <affected-histogram name="SB2.PrefixSetSizeKilobytes"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="SafeBrowsingScoutOptInLocations" separator=".">
   <suffix name="AndroidSettings" label="The settings UI on Android"/>
   <suffix name="ChromeSettings" label="The settings UI on Desktop"/>
@@ -9028,7 +5680,6 @@
   <affected-histogram
       name="Event.Latency.ScrollInertial.Touch.HandledToRendererSwap2"/>
   <affected-histogram name="Event.Latency.ScrollInertial.Touch.TimeToHandled2"/>
-  <affected-histogram name="Event.Latency.ScrollUpdate.HandledToRendererSwap"/>
   <affected-histogram
       name="Event.Latency.ScrollUpdate.Scrollbar.HandledToRendererSwap2"/>
   <affected-histogram
@@ -9036,7 +5687,6 @@
   <affected-histogram
       name="Event.Latency.ScrollUpdate.Touch.HandledToRendererSwap2"/>
   <affected-histogram name="Event.Latency.ScrollUpdate.Touch.TimeToHandled2"/>
-  <affected-histogram name="Event.Latency.ScrollUpdate.TouchToHandled"/>
   <affected-histogram
       name="Event.Latency.ScrollUpdate.Wheel.HandledToRendererSwap2"/>
   <affected-histogram name="Event.Latency.ScrollUpdate.Wheel.TimeToHandled2"/>
@@ -9152,7 +5802,6 @@
   <affected-histogram name="Security.PageInfo.TimeOpen.NoAction"/>
   <affected-histogram name="Security.SiteEngagement"/>
   <affected-histogram name="Security.SiteEngagementDelta"/>
-  <affected-histogram name="Security.TimeOnPage"/>
   <affected-histogram name="Security.TimeOnPage2"/>
 </histogram_suffixes>
 
@@ -9194,7 +5843,6 @@
   <suffix name="PUSH" label="PUSH"/>
   <suffix name="SYNC" label="SYNC"/>
   <suffix name="UNKNOWN" label="UNKNOWN"/>
-  <affected-histogram name="ServiceWorker.EventDispatchingDelay"/>
   <affected-histogram name="ServiceWorker.StartWorker.Time_Any"/>
   <affected-histogram name="ServiceWorker.StartWorker.Time_DuringStartup"/>
   <affected-histogram
@@ -9244,37 +5892,9 @@
   <suffix name="ExistingUnreadyProcess"
       label="An existing unready process was used for the worker."/>
   <suffix name="NewProcess" label="A new process was created for the worker."/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency"/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.TimeToEvaluateScript"/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.TimeToLoad.HttpCache"/>
-  <affected-histogram
-      name="EmbeddedWorkerInstance.Start.TimeToLoad.InstalledScript"/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.TimeToLoad.Network"/>
-  <affected-histogram
-      name="EmbeddedWorkerInstance.Start.TimeToSendStartWorker"/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.TimeToStartThread"/>
-  <affected-histogram name="EmbeddedWorkerInstance.Start.TimeToURLJob"/>
   <affected-histogram name="ServiceWorker.StartWorker.Time"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ServiceWorker_WorkerPreparationMode" separator="_">
-  <suffix name="RunningWorker"
-      label="The activated worker was already running."/>
-  <suffix name="StartingWorker"
-      label="The activated worker was already starting up."/>
-  <suffix name="StartWorkerDuringStartup"
-      label="Started a worker during browser startup."/>
-  <suffix name="StartWorkerExistingReadyProcess"
-      label="Started a worker in an existing ready process."/>
-  <suffix name="StartWorkerExistingUnreadyProcess"
-      label="Started a worker in an existing unready process."/>
-  <suffix name="StartWorkerNewProcess"
-      label="Started a worker in a new process."/>
-  <suffix name="StoppingWorker" label="The activated worker was stopping."/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ServiceWorkerScheduler" separator="."
     ordering="prefix">
   <suffix name="BackgroundSyncManager"
@@ -9313,39 +5933,6 @@
       name="ServiceWorkerCache.CacheStorage.Scheduler.QueueLength"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ServiceWorkerStartOccurred" separator="_">
-  <suffix name="WorkerStartOccurred"
-      label="The worker was not already running. Worker startup occurred."/>
-  <affected-histogram
-      name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time"/>
-  <affected-histogram name="ServiceWorker.NavPreload.ConcurrentTime_MainFrame"/>
-  <affected-histogram name="ServiceWorker.NavPreload.FinishedFirst_MainFrame"/>
-  <affected-histogram name="ServiceWorker.NavPreload.ResponseTime_MainFrame"/>
-  <affected-histogram name="ServiceWorker.NavPreload.WorkerWaitTime_MainFrame"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="SessionRestoreTabCountMemoryPressure" separator="_">
-  <suffix name="MemoryPressure"
-      label="Total tabs involved in session restore that encountered memory
-             pressure."/>
-  <suffix name="MemoryPressure_Deferred"
-      label="Tabs deferred by memory pressure."/>
-  <suffix name="MemoryPressure_Loaded"
-      label="Tabs fully loaded before memory pressure."/>
-  <suffix name="MemoryPressure_LoadStarted"
-      label="Tabs started to load before memory pressure."/>
-  <suffix name="NoMemoryPressure"
-      label="Total tabs involved in a session restore that did not encounter
-             memory pressure."/>
-  <suffix name="NoMemoryPressure_Loaded"
-      label="Tabs fully loaded in a session restore that did not encounter
-             memory pressure."/>
-  <suffix name="NoMemoryPressure_LoadStarted"
-      label="Tabs started to load in a session restore that did not encounter
-             memory pressure."/>
-  <affected-histogram name="SessionRestore.TabCount"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="SessionRestoreTabCounts" separator="_">
   <suffix name="1" label="1 tab present"/>
   <suffix name="2" label="2 tabs present"/>
@@ -9367,12 +5954,6 @@
   <suffix name="18" label="18 tabs present"/>
   <suffix name="19" label="19 tabs present"/>
   <suffix name="20" label="20 tabs present"/>
-  <affected-histogram name="SessionRestore.AllTabsLoaded"/>
-  <affected-histogram name="SessionRestore.FirstTabPainted"/>
-  <affected-histogram name="SessionRestore.ForegroundTabFirstLoaded"/>
-  <affected-histogram name="SessionRestore.ForegroundTabFirstPaint"/>
-  <affected-histogram name="SessionRestore.ForegroundTabFirstPaint2"/>
-  <affected-histogram name="SessionRestore.ForegroundTabFirstPaint3"/>
   <affected-histogram name="SessionRestore.ForegroundTabFirstPaint4"/>
 </histogram_suffixes>
 
@@ -9523,10 +6104,6 @@
 <histogram_suffixes name="SideloadWipeout" separator="_">
   <suffix name="Disabled" label="Control group."/>
   <suffix name="Enabled" label="Sideload Wipeout Active."/>
-  <affected-histogram name="DisabledExtension.ExtensionWipedStatus"/>
-  <affected-histogram name="DisabledExtension.SideloadWipeoutCount"/>
-  <affected-histogram name="DisabledExtension.SideloadWipeoutNeeded"/>
-  <affected-histogram name="DisabledExtension.UserSelection"/>
   <affected-histogram name="Extensions.ExternalExtensionEvent"/>
   <affected-histogram name="Extensions.InstallSource"/>
   <affected-histogram name="Extensions.UpdateSource"/>
@@ -9662,8 +6239,6 @@
   <affected-histogram
       name="Graphics.Smoothness.PercentMissedDeadlineFrames.ScrollingThread"/>
   <affected-histogram name="Graphics.Smoothness.Stale"/>
-  <affected-histogram name="SingleThreadedCompositorLatency"/>
-  <affected-histogram name="SingleThreadedCompositorLatency.MissedFrame"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="SmoothnessThreadTypes" separator=".">
@@ -9682,39 +6257,6 @@
   <affected-histogram name="Graphics.Smoothness.Jank"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="SocketOperation" separator=".">
-  <suffix name="Connect" label=""/>
-  <suffix name="Read" label=""/>
-  <suffix name="Write" label=""/>
-  <affected-histogram name="Net.SSLProtocolErrorCipher"/>
-  <affected-histogram name="Net.SSLProtocolErrorReason"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="SpdyImpact" separator="_">
-  <suffix name="npn_with_http"
-      label="with NPN negotiated but using HTTP instead of SPDY"/>
-  <suffix name="npn_with_spdy" label="with NPN negotiated and using SPDY"/>
-  <affected-histogram name="Net.Transaction_Connected"/>
-  <affected-histogram name="Net.Transaction_Connected_New"/>
-  <affected-histogram name="Net.Transaction_Connected_New_b"/>
-  <affected-histogram name="Net.Transaction_Connected_Under_10"/>
-  <affected-histogram name="PLT.Abandoned"/>
-  <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
-  <affected-histogram name="PLT.StartToCommit_LinkLoadNormal"/>
-  <affected-histogram name="PLT.StartToCommit_NormalLoad"/>
-  <affected-histogram name="PLT.StartToFinish_LinkLoadNormal"/>
-  <affected-histogram name="PLT.StartToFinish_NormalLoad"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="SpdySettingsCwnd" separator="">
-  <suffix name="10K" label="where at least 10KB was transferred."/>
-  <suffix name="25K" label="where at least 25KB was transferred."/>
-  <suffix name="50K" label="where at least 50KB was transferred."/>
-  <suffix name="100K" label="where at least 100KB was transferred."/>
-  <affected-histogram name="Net.SpdySettingsCwnd"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Spellcheck_Windows_LocaleSupportType" separator=".">
   <suffix name="Both"
       label="This variation counts the number of locales that are supported
@@ -9745,38 +6287,6 @@
   <affected-histogram name="Spellcheck.Windows.SuggestionGatheringDuration"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="SqliteDatabases" separator=".">
-  <owner>costan@google.com</owner>
-  <suffix name="Activity" label="Activity"/>
-  <suffix name="Affiliation" label="Affiliation"/>
-  <suffix name="AppCache" label="AppCache"/>
-  <suffix name="BackgroundRequestQueue" label="BackgroundRequestQueue"/>
-  <suffix name="Cookie" label="Cookie"/>
-  <suffix name="DatabaseTracker" label="DatabaseTracker"/>
-  <suffix name="DomainBoundCerts" label="DomainBoundCerts"/>
-  <suffix name="DOMStorageDatabase" label="DOMStorageDatabase"/>
-  <suffix name="History" label="History"/>
-  <suffix name="MediaHistory" label="Media History"/>
-  <suffix name="OfflinePageMetadata" label="OfflinePageMetadata"/>
-  <suffix name="Passwords" label="Passwords"/>
-  <suffix name="Predictor" label="Predictor"/>
-  <suffix name="PrefetchStore" label="PrefetchStore"/>
-  <suffix name="PreviewsOptOut" label="PreviewsOptOut"/>
-  <suffix name="Quota" label="Quota"/>
-  <suffix name="Shortcuts" label="Shortcuts"/>
-  <suffix name="SyncDirectory" label="SyncDirectory"/>
-  <suffix name="Thumbnail" label="Thumbnail"/>
-  <suffix name="TopSites" label="TopSites"/>
-  <suffix name="TrustTokens" label="TrustTokens"/>
-  <suffix name="Web" label="Web"/>
-  <affected-histogram name="Sqlite.AutoCommitTime"/>
-  <affected-histogram name="Sqlite.CommitTime"/>
-  <affected-histogram name="Sqlite.QueryTime"/>
-  <affected-histogram name="Sqlite.SizeKB"/>
-  <affected-histogram name="Sqlite.Stats"/>
-  <affected-histogram name="Sqlite.UpdateTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="StaleWhileRevalidate" separator=".">
   <suffix name="Cache" label=""/>
   <suffix name="Network" label=""/>
@@ -9796,55 +6306,18 @@
       name="LibraryLoader.PercentageOfResidentCodeBeforePrefetch"/>
   <affected-histogram
       name="ProfilePicker.StartupTime.FirstPaint.FromApplicationStart"/>
-  <affected-histogram name="Startup.BrowserMainToRendererMain"/>
   <affected-histogram name="Startup.BrowserMessageLoopFirstIdle"/>
-  <affected-histogram
-      name="Startup.BrowserMessageLoopStart.To.MainNavigationStart"/>
   <affected-histogram name="Startup.BrowserMessageLoopStart.To.NonEmptyPaint2"/>
   <affected-histogram name="Startup.BrowserMessageLoopStartTime"/>
-  <affected-histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry"/>
-  <affected-histogram
-      name="Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun"/>
-  <affected-histogram
-      name="Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun2"/>
-  <affected-histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry2"/>
-  <affected-histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry3"/>
-  <affected-histogram name="Startup.BrowserOpenTabs"/>
   <affected-histogram name="Startup.BrowserWindow.FirstPaint"/>
   <affected-histogram name="Startup.BrowserWindowDisplay"/>
-  <affected-histogram name="Startup.FirstWebContents.MainFrameLoad"/>
-  <affected-histogram name="Startup.FirstWebContents.MainFrameLoad2"/>
   <affected-histogram name="Startup.FirstWebContents.MainNavigationFinished"/>
   <affected-histogram name="Startup.FirstWebContents.MainNavigationStart"/>
-  <affected-histogram name="Startup.FirstWebContents.NonEmptyPaint"/>
-  <affected-histogram name="Startup.FirstWebContents.NonEmptyPaint2"/>
   <affected-histogram name="Startup.FirstWebContents.NonEmptyPaint3"/>
   <affected-histogram
       name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint"/>
   <affected-histogram name="Startup.LoadTime.ApplicationStartToChromeMain"/>
-  <affected-histogram name="Startup.LoadTime.ExeMainToDllMain"/>
-  <affected-histogram name="Startup.LoadTime.ExeMainToDllMain2"/>
   <affected-histogram name="Startup.LoadTime.ProcessCreateToApplicationStart"/>
-  <affected-histogram name="Startup.LoadTime.ProcessCreateToDllMain"/>
-  <affected-histogram name="Startup.LoadTime.ProcessCreateToDllMain2"/>
-  <affected-histogram name="Startup.LoadTime.ProcessCreateToExeMain"/>
-  <affected-histogram name="Startup.LoadTime.ProcessCreateToExeMain2"/>
-  <affected-histogram name="Startup.SystemUptime"/>
-  <affected-histogram name="Startup.TimeSinceLastStartup"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="Storage_Bytes" separator=".">
-  <suffix name="DiskCache.AppCache" label="AppCache usage."/>
-  <suffix name="DiskCache.CacheStorage" label="CacheStorage usage."/>
-  <suffix name="DiskCache.ServiceWorker"
-      label="ServiceWorker scriptcache usage."/>
-  <suffix name="LevelDBEnv" label="Undifferentiated leveldb usage."/>
-  <suffix name="LevelDBEnv.IDB" label="IndexedDB usage."/>
-  <suffix name="LevelDBEnv.ServiceWorker"
-      label="ServiceWorker database usage."/>
-  <suffix name="MojoLevelDBEnv" label="Mojo leveldb component usage."/>
-  <affected-histogram name="Storage.BytesRead"/>
-  <affected-histogram name="Storage.BytesWritten"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="StunPingInternal" separator=".">
@@ -9886,8 +6359,6 @@
       name="WebCore.IndexedDB.TombstoneSweeper.DeletedTombstonesSize"/>
   <affected-histogram
       name="WebCore.IndexedDB.TombstoneSweeper.NumDeletedTombstones"/>
-  <affected-histogram name="WebCore.IndexedDB.TombstoneSweeper.NumTombstones"/>
-  <affected-histogram name="WebCore.IndexedDB.TombstoneSweeper.TombstonesSize"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="SystemNotificationAgeType" separator=".">
@@ -9939,13 +6410,6 @@
   <affected-histogram name="Ash.UnlockAnimation.Smoothness"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="TeamDrivesSupport" separator=".">
-  <suffix name="TeamDrives" label=""/>
-  <affected-histogram name="Drive.DeltaFeedLoadTime"/>
-  <affected-histogram name="Drive.DirectoryFeedLoadTime"/>
-  <affected-histogram name="Drive.FullFeedLoadTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ThreadPoolName" separator=".">
   <suffix base="true" name="Browser"
       label="ThreadPool for the browser process."/>
@@ -9954,10 +6418,7 @@
   <suffix base="true" name="GPU" label="ThreadPool for the gpu process."/>
   <suffix base="true" name="Renderer"
       label="ThreadPools for renderer processes."/>
-  <affected-histogram name="ThreadPool.NumActiveWorkers"/>
   <affected-histogram name="ThreadPool.NumTasksBeforeDetach"/>
-  <affected-histogram name="ThreadPool.NumTasksBetweenWaits"/>
-  <affected-histogram name="ThreadPool.NumWorkers"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="ThreadPoolWorkerGroup" separator=".">
@@ -9965,18 +6426,9 @@
       label="Applies to the Background priority worker group."/>
   <suffix name="Foreground"
       label="Applies to the Foreground priority worker group."/>
-  <affected-histogram name="ThreadPool.NumActiveWorkers.Browser"/>
-  <affected-histogram name="ThreadPool.NumActiveWorkers.ContentChild"/>
-  <affected-histogram name="ThreadPool.NumActiveWorkers.Renderer"/>
   <affected-histogram name="ThreadPool.NumTasksBeforeDetach.Browser"/>
   <affected-histogram name="ThreadPool.NumTasksBeforeDetach.ContentChild"/>
   <affected-histogram name="ThreadPool.NumTasksBeforeDetach.Renderer"/>
-  <affected-histogram name="ThreadPool.NumTasksBetweenWaits.Browser"/>
-  <affected-histogram name="ThreadPool.NumTasksBetweenWaits.ContentChild"/>
-  <affected-histogram name="ThreadPool.NumTasksBetweenWaits.Renderer"/>
-  <affected-histogram name="ThreadPool.NumWorkers.Browser"/>
-  <affected-histogram name="ThreadPool.NumWorkers.ContentChild"/>
-  <affected-histogram name="ThreadPool.NumWorkers.Renderer"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="TileUiSurface" separator="." ordering="prefix,2">
@@ -9997,17 +6449,6 @@
   <affected-histogram name="Net.HttpJob.TotalTimeNotCached"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="Tps65090Fets" separator=".">
-  <suffix name="Fet1" label="FET1 on tps65090 (register 0xf)"/>
-  <suffix name="Fet2" label="FET2 on tps65090 (register 0x10)"/>
-  <suffix name="Fet3" label="FET3 on tps65090 (register 0x11)"/>
-  <suffix name="Fet4" label="FET4 on tps65090 (register 0x12)"/>
-  <suffix name="Fet5" label="FET5 on tps65090 (register 0x13)"/>
-  <suffix name="Fet6" label="FET6 on tps65090 (register 0x14)"/>
-  <suffix name="Fet7" label="FET7 on tps65090 (register 0x15)"/>
-  <affected-histogram name="Platform.Tps65090Retries"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="TrackedPreferencesExternalValidators" separator=".">
   <suffix name="FromRegistry"
       label="Validation using MACs in the Windows Registry."/>
@@ -10103,8 +6544,6 @@
   <suffix name="DocumentIdle" label="Scripts with run_at: document_idle."/>
   <suffix name="DocumentStart" label="Scripts with run_at: document_start."/>
   <affected-histogram name="Extensions.InjectedScriptExecutionTime"/>
-  <affected-histogram name="Extensions.LongInjectionTaskTime"/>
-  <affected-histogram name="Extensions.TimeYieldedBetweenContentScriptRuns"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="V8SpecialApps" separator=".">
@@ -10117,10 +6556,8 @@
       label="Custom histogram for Alexa's Top10 non-Google sites"/>
   <suffix name="youtube" label="Custom histogram for Youtube"/>
   <affected-histogram name="V8.MemoryExternalFragmentationTotal"/>
-  <affected-histogram name="V8.MemoryHeapCommitted"/>
   <affected-histogram name="V8.MemoryHeapSampleTotalCommitted"/>
   <affected-histogram name="V8.MemoryHeapSampleTotalUsed"/>
-  <affected-histogram name="V8.MemoryHeapUsed"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="V8WasmSeparateAsmAndWasm" separator=".">
@@ -10129,9 +6566,6 @@
       label="This histogram contains results for wasm modules."/>
   <affected-histogram name="V8.WasmCompileFunctionMicroSeconds"/>
   <affected-histogram name="V8.WasmCompileModuleMicroSeconds"/>
-  <affected-histogram name="V8.WasmDecodeFunctionMicroSeconds"/>
-  <affected-histogram name="V8.WasmDecodeModuleMicroSeconds"/>
-  <affected-histogram name="V8.WasmDecodeModulePeakMemoryBytes"/>
   <affected-histogram name="V8.WasmFunctionsPerModule"/>
   <affected-histogram name="V8.WasmHugeFunctionSizeBytes"/>
   <affected-histogram name="V8.WasmInstantiateModuleMicroSeconds"/>
@@ -10171,16 +6605,9 @@
       label="The session is restricted to the period that browser is
              displaying WebVR contents."/>
   <affected-histogram name="VRSessionTime"/>
-  <affected-histogram name="VRSessionTimeFromDLA"/>
   <affected-histogram name="VRSessionVideoTime"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="WebApkType" separator=".">
-  <suffix name="BrowserApk" label="Installed by Chrome"/>
-  <suffix name="UnboundApk" label="Not installed by Chrome"/>
-  <affected-histogram name="WebApk.ShellApkVersion"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="WebAppContainerEngagementType" separator=".">
   <suffix name="InTab" label="Happened in app running as a tab"/>
   <suffix name="InWindow" label="Happened in app running as a window"/>
@@ -10256,11 +6683,6 @@
   <suffix name="opensans" label="Open Sans font"/>
   <suffix name="others" label="Fonts other than Roboto and Open Sans"/>
   <suffix name="roboto" label="Roboto font"/>
-  <affected-histogram name="WebFont.DiskCache.EntryAge.Evict"/>
-  <affected-histogram name="WebFont.DiskCache.EntryAge.Hit"/>
-  <affected-histogram name="WebFont.DiskCache.ReuseCount.Evict"/>
-  <affected-histogram name="WebFont.DiskCache.ReuseCount.Hit"/>
-  <affected-histogram name="WebFont.DiskCacheHit"/>
   <affected-histogram name="WebFont.HttpCacheStatus"/>
 </histogram_suffixes>
 
@@ -10276,16 +6698,6 @@
   <affected-histogram name="Media.UnderflowDuration2"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="WebRTCEchoCancellerStatisticType" separator=".">
-  <suffix name="Average" label="The average over the time interval"/>
-  <suffix name="Max" label="The maximum over the time interval"/>
-  <suffix name="Min" label="The minimum over the time interval"/>
-  <affected-histogram name="WebRTC.Audio.EchoCanceller.ComfortNoiseBand0"/>
-  <affected-histogram name="WebRTC.Audio.EchoCanceller.ComfortNoiseBand1"/>
-  <affected-histogram name="WebRTC.Audio.EchoCanceller.SuppressorGainBand0"/>
-  <affected-histogram name="WebRTC.Audio.EchoCanceller.SuppressorGainBand1"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="WebSocketErrorCodesVariants" separator="_">
   <suffix name="Localhost" label=""/>
   <suffix name="NotLocalhost" label=""/>
@@ -10297,7 +6709,6 @@
   <suffix name="FooterLink" label="Link in bottom right of footer"/>
   <suffix name="PlusIcon" label="Plus icon in apps page"/>
   <affected-histogram name="Extensions.AppLaunch"/>
-  <affected-histogram name="NewTabPage.DefaultPageType"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="WebUITabStripTabCount" separator=".">
diff --git a/tools/metrics/histograms/metadata/obsolete_histograms.xml b/tools/metrics/histograms/metadata/obsolete_histograms.xml
deleted file mode 100644
index 217c66a..0000000
--- a/tools/metrics/histograms/metadata/obsolete_histograms.xml
+++ /dev/null
@@ -1,90529 +0,0 @@
-<!--
-Copyright 2020 The Chromium Authors
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-
-<!--
-This file is used to generate a list of obsolete histograms along with a
-detailed description for each histogram.
-
-This was auto-generated from the split_xml.py script which splits out previously
-obsolete histograms. Users don't need to move newly marked obsolete histograms
-into this file.
-
-In other words, when marking an existing histogram as <obsolete>, it's fine
-to leave the histogram in its existing file in one of the metadata
- subdirectories.
-
-For best practices on writing histogram descriptions, see
-https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md
-
-Please send CLs to someone randomly chosen from the OWNERS file in this
-directory. If no OWNERS file exists, please consider signing up at
-go/reviewing-metrics (Googlers only). As a last resort you can send the CL to
-chromium-metrics-reviews@google.com.
--->
-
-<histogram-configuration>
-
-<histograms>
-
-<histogram name="Accessibility.Android.AnimationsEnabled" enum="BooleanEnabled"
-    expires_after="2019-11-02">
-  <obsolete>
-    Removed 11/2018 because a need was discovered for a non-boolean value.
-    Superseded by Accessibility.Android.AnimationsEnabled2.
-  </obsolete>
-  <owner>dmazzoni@chromium.org</owner>
-  <owner>smcgruer@chromium.org</owner>
-  <summary>
-    Tracks whether animations are enabled on Android (e.g. if the animator
-    duration scale is non-zero.) The purpose is to inform the design of the
-    prefers-reduced-motion media feature; see http://crbug.com/722548. This is
-    logged once, 45 seconds after startup.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosAutoclickDelay" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>dmazzoni@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>katie@chromium.org</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    If the user has enabled Autoclick, this is the delay set by the user for
-    autoclicks to occur, in milliseconds, at startup and when changed.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosChromeVoxAfterSwitchAccess"
-    enum="BooleanEnabled" expires_after="M85">
-  <obsolete>
-    Removed M85 when no longer needed, as there is no longer a restriction on
-    having both features enabled.
-  </obsolete>
-  <owner>anastasi@google.com</owner>
-  <owner>dtseng@chromium.org</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    When ChromeVox is enabled, true if Switch Access was previously enabled.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosSelectToSpeak.SpeechPitch"
-    enum="CrosSelectToSpeakSpeechPitch" expires_after="2018-08-01">
-  <obsolete>
-    Removed 7/2018 in Issue 866550 in favor of using global Text-to-Speech
-    settings for speech pitch.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <summary>
-    The speech pitch setting when Select-to-Speak was activated. It is stored as
-    a sparse histogram with values (100 * speech_pitch). For example, a speech
-    pitch of 1.0 (default) will be seen as 100.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosSelectToSpeak.SpeechRate"
-    enum="CrosSelectToSpeakSpeechRate" expires_after="2018-08-01">
-  <obsolete>
-    Removed 7/2018 in Issue 866550 in favor of using global Text-to-Speech
-    settings for speech rate.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <summary>
-    The speech rate setting when Select-to-Speak was activated. It is stored as
-    a sparse histogram with values (100 * speech_rate). For example, a speech
-    rate of 1.0 (default) will be seen as 100.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosSelectToSpeak.WordHighlighting"
-    enum="BooleanEnabled" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <summary>
-    Whether Select-to-Speak had per-word highlighting enabled when activated.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.CrosSwitchAccessAfterChromeVox"
-    enum="BooleanEnabled" expires_after="M85">
-  <obsolete>
-    Removed M85 when no longer needed, as there is no longer a restriction on
-    having both features enabled.
-  </obsolete>
-  <owner>anastasi@google.com</owner>
-  <owner>dtseng@chromium.org</owner>
-  <summary>
-    When Switch Access is enabled, true if ChromeVox was previously enabled.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.ImageLabels.ContextMenuOption"
-    enum="AccessibilityImageLabelMode" expires_after="2020-04-26">
-  <obsolete>
-    Removed 06/2020 because we don't need to keep tracking this.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    When a user selects the Chrome accessibility image labels option in the
-    context menu, whether they are trying to enable or disable the feature, or
-    enable it for a single use. Recorded when the user selects the option from
-    the context menu. The feature may not have been enabled if they do not
-    confirm on the modal dialog that appears after.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.ImageLabels.FromSettings.ToggleSetting"
-    enum="BooleanEnabled" expires_after="2020-04-19">
-  <obsolete>
-    Removed 06/2020 because we don't need to keep tracking this.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    When a user selects the Chrome accessibility image labels option in
-    chrome://settings, whether they are trying to enable or disable the feature.
-    Recorded when the user activates the toggle from the settings page. The
-    feature may not have been enabled if they do not confirm on the modal dialog
-    that appears after.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.InvertedColors" enum="BooleanEnabled"
-    expires_after="2020-03-25">
-  <obsolete>
-    Removed 03/2020 in favor of Accessibility.WinHighContrastTheme.
-  </obsolete>
-  <owner>dmazzoni@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Whether Windows system settings show that high-contrast mode is enabled and
-    the user has selected a light-on-dark color scheme (logged once 45 secs
-    after startup). This causes Chrome to prompt the user with a bubble to
-    optionally install a High Contrast extension and theme.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.LiveCaptions" enum="BooleanEnabled"
-    expires_after="2020-09-30">
-  <obsolete>
-    Removed 08/2020. Replaced by Accessibility.LiveCaption.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>abigailbklein@google.com</owner>
-  <owner>evliu@google.com</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Whether the Live Caption feature is enabled. This is logged once, 45 seconds
-    after startup.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.LiveCaptions.Session"
-    enum="LiveCaptionSessionEvent" expires_after="2020-09-30">
-  <obsolete>
-    Removed 08/2020. Replaced by Accessibility.LiveCaption.Session.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>abigailbklein@google.com</owner>
-  <owner>evliu@google.com</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Logged when there's a change in the lifetime of a Live Caption audio stream:
-    When a session started and captions began arriving from the service, when a
-    session ended because the audio stream finished, or when the session ended
-    because a user clicked the close button on the caption bubble.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.LiveCaptions.ToggleEnabled"
-    enum="BooleanEnabled" expires_after="2020-09-30">
-  <obsolete>
-    Removed 08/2020. Replaced by Accessibility.LiveCaption.ToggleEnabled.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>abigailbklein@google.com</owner>
-  <owner>evliu@google.com</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Records when a user enables or disables the Live Caption feature from
-    chrome://settings.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.Mac.DifferentiateWithoutColor"
-    enum="BooleanEnabled" expires_after="2020-11-02">
-  <obsolete>
-    Removed 2020-09: Data no longer needed or gathered.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Whether the &quot;differentiate without color&quot; Mac system setting is
-    enabled. This is logged once, 45 seconds after startup.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.Mac.FullKeyboardAccessEnabled"
-    enum="BooleanEnabled" expires_after="2020-11-02">
-  <obsolete>
-    Removed 2020-09: Data no longer needed or gathered.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Whether the &quot;full keyboard access&quot; Mac system setting is enabled.
-    This is logged once, 45 seconds after startup.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.Mac.IncreaseContrast" enum="BooleanEnabled"
-    expires_after="2020-11-02">
-  <obsolete>
-    Removed 2020-09: Data no longer needed or gathered.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <owner>chrome-a11y-core@google.com</owner>
-  <summary>
-    Whether the &quot;increase contrast&quot; Mac system setting is enabled.
-    This is logged once, 45 seconds after startup.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Accessibility.ScreenReader.Image.MinSize"
-    units="px" expires_after="2020-05-10">
-  <obsolete>
-    Removed 06/2020 as this is stable and doesn't need to be tracked closely.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AccessibilityScreenReaderImage" -->
-
-  <owner>katie@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    For every image on a page with screen reader accessibility mode enabled,
-    this histogram will be used to understand minimum dimension of the image,
-    i.e. either the width or height in px.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Accessibility.ScreenReader.Image.SizeRatio"
-    units="%" expires_after="2020-05-10">
-  <obsolete>
-    Removed 06/2020 as this is stable and doesn't need to be tracked closely.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AccessibilityScreenReaderImage" -->
-
-  <owner>katie@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    For every image on a page with screen reader accessibility mode enabled,
-    this histogram will be used to understand the size ratio of the image. This
-    is the smaller dimension divided by the larger dimension.
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.State" enum="BooleanEnabled"
-    expires_after="2016-12-20">
-  <obsolete>
-    Removed 12/2016 in Issue 672205 with the addition of Accessibility.ModeFlag.
-  </obsolete>
-  <owner>dmazzoni@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>
-    Whether Chrome has enabled accessibility support because it detects
-    supported assistive technology running, or due to being manually enabled via
-    a command-line flag (logged once 45 secs after startup).
-  </summary>
-</histogram>
-
-<histogram name="Accessibility.WinSAToGo" enum="BooleanEnabled"
-    expires_after="2020-02-23">
-  <obsolete>
-    System Access To Go is a discontinued product.
-  </obsolete>
-  <owner>dmazzoni@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>
-    Whether the third-party System Access To Go screen reader is running (logged
-    once 45 secs after startup).
-  </summary>
-</histogram>
-
-<histogram name="AccountManager.LegacySetPrimaryAccountAndUpdateAccountInfo"
-    enum="BooleanUsage" expires_after="2020-08-30">
-  <obsolete>
-    Removed in M84 as part of https://crrev.com/c/2131912 The legacy code path
-    and API being checked by this UMA stat no longer exist.
-  </obsolete>
-  <owner>sinhak@chromium.org</owner>
-  <summary>
-    Tracks the usage of the legacy Primary Account setting flow vs the new flow
-    through Account Manager. This is recorded only once per session, at login
-    time.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.Collect.UncleanShutdownCount" units="count"
-    expires_after="2017-06-05">
-  <obsolete>
-    Removed 05/2017 in favor of ActivityTracker.Collect.Status.
-  </obsolete>
-  <owner>manzagop@chromium.org</owner>
-  <summary>
-    Number of unclean shutdowns, as derived from the stability instrumentation.
-    Logged each time stability file collection is performed.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.Collect.UncleanSystemCount" units="count"
-    expires_after="2017-06-05">
-  <obsolete>
-    Removed 05/2017 in favor of ActivityTracker.Collect.Status.
-  </obsolete>
-  <owner>manzagop@chromium.org</owner>
-  <summary>
-    Number of unclean shutdowns that can potentially be attributed to system
-    instability. This should be smaller or equal to UncleanShutdownCount. Logged
-    each time stability file collection is performed.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.CollectCrash.OpenForDeleteSuccess"
-    enum="BooleanSuccess" expires_after="2017-06-01">
-  <obsolete>
-    Removed 05/2017 in favor of ActivityTracker.CollectCrash.Event.
-  </obsolete>
-  <owner>manzagop@chromium.org</owner>
-  <summary>
-    Success of the attempt to open the debug file for deletion. Logged each time
-    a debug file is opened for deletion during collection from the crash
-    handler.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.Record.InitStatus"
-    enum="ActivityTrackerRecordInitStatus" expires_after="2017-06-01">
-  <obsolete>
-    Removed 05/2017 in favor of ActivityTracker.Record.Event.
-  </obsolete>
-  <owner>manzagop@chromium.org</owner>
-  <summary>
-    Status of internal activity tracking initialization. Logged once, during the
-    activity tracking initialization.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.Record.SetupTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/06.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Time spent setting up the stability debugging instrumentation. Logged once,
-    during setup of the stability debugging instrumentation.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.ThreadTrackers.Count" units="count"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/06.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The number of threads being tracked for activities such as waiting for a
-    lock/event, a thread to join, or a task to run. Analysis of this data can
-    reveal why a thread will not exit. This value is updated every time a new
-    thread gets an activity tracked for the first time so will show one count
-    for every permanent thread but multiple counts for a thread than exits and
-    is replaced.
-  </summary>
-</histogram>
-
-<histogram name="ActivityTracker.ThreadTrackers.MemLimitTrackerCount"
-    units="count" expires_after="M77">
-  <obsolete>
-    Never occurred. Removed 2019/06.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The limit on the number of thread trackers that could be allocated from the
-    persistent memory segment. Trackers beyond this number were allocated from
-    the heap and thus were not available for analysis. This value is updated on
-    every &quot;memory full&quot; failure.
-  </summary>
-</histogram>
-
-<histogram name="Ads.Features.AdResourceIsIsolated" enum="AdIsolatedInfo"
-    expires_after="M80">
-  <obsolete>
-    Removed April 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For a given ad request, logs information related to whether it is isolated
-    from the top-level context. Logged per ad subresource request.
-  </summary>
-</histogram>
-
-<histogram name="Ads.Features.ResourceIsSecure" enum="AdSecureInfo"
-    expires_after="M77">
-  <obsolete>
-    Removed April 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For a given request, logs information related to whether it is marked as an
-    ad, and whether it is secure (e.g. https). Logged per subresource request.
-  </summary>
-</histogram>
-
-<histogram name="Ads.Media.BytesReceived" units="KB" expires_after="2020-01-26">
-  <obsolete>
-    Removed 10/2019 in issue 1000058; no longer needed.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Total number of bytes buffered over the lifetime of a WebMediaPlayer inside
-    of an adframe. Suffixed by type of playback.
-  </summary>
-</histogram>
-
-<histogram name="Ads.ResourceUsage.Size.Cache" units="KB"
-    expires_after="2019-10-02">
-  <obsolete>
-    Removed 07/2019 in favor of Ads.ResourceUsage.Size.Cache2.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For a given resource fetched from the disk cache, logs the encoded body
-    length of the resource, even if the resource request was canceled or
-    incomplete. Recorded when the resource request is complete, or when the page
-    is destroyed/navigated for incomplete resources.
-  </summary>
-</histogram>
-
-<histogram name="Ads.ResourceUsage.Size.Mainframe.AdResource" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 10/2018. Replaced with
-    Ads.ResourceUsage.Size.Network.Mainframe.AdResource and
-    Ads.ResourceUsage.Size.Cache.Mainframe.AdResource.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    For a given ad resource in the main frame, logs the network bytes received
-    for the resource, even if the resource request was canceled or incomplete.
-  </summary>
-</histogram>
-
-<histogram name="Ads.ResourceUsage.Size.Mainframe.VanillaResource" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 10/2018. Replaced with
-    Ads.ResourceUsage.Size.Network.Mainframe.VanillaResource and
-    Ads.ResourceUsage.Size.Cache.Mainframe.VanillaResource.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    For a given non-ad resource in the main frame, logs the network bytes
-    received for the resource, even if the resource request was canceled or
-    incomplete.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Ads.ResourceUsage.Size.Mime" units="KB"
-    expires_after="2019-09-10">
-  <obsolete>
-    Removed 10/2018. Replaced with Ads.ResourceUsage.Size.Cache.Mime and
-    Ads.ResourceUsage.Size.Network.Mime.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Size of resources tagged as ads, identified by the response header mime
-    type. This includes resources that did not complete loading. Recorded when
-    the resource request is completed. For incomplete requests, recorded when
-    the page is destroyed/navigated.
-  </summary>
-</histogram>
-
-<histogram name="Ads.ResourceUsage.Size.Subframe.AdResource" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 10/2018. Replaced with
-    Ads.ResourceUsage.Size.Network.Subframe.AdResource and
-    Ads.ResourceUsage.Size.Cache.Subframe.AdResource.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    For a given ad resource in a subframe, logs the network bytes received for
-    the resource, even if the resource request was canceled or incomplete.
-  </summary>
-</histogram>
-
-<histogram name="Ads.ResourceUsage.Size.Subframe.VanillaResource" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 10/2018. Replaced with
-    Ads.ResourceUsage.Size.Network.Subframe.VanillaResource and
-    Ads.ResourceUsage.Size.Cache.Subframe.VanillaResource.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    For a given non-ad resource in a subframe, logs the network bytes received
-    for the resource, even if the resource request was canceled or incomplete.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.AreaRank" units="rank"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The rank of the clicked anchor element in terms of area. This histogram is
-    recorded when the anchor element is clicked.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.ClickIntervals" units="ms"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The interval between consecutive clicks of anchor elements. This histogram
-    is recorded when an anchor element is clicked except the first click in the
-    current document.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.DurationLoadToFirstClick"
-    units="ms" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The duration between page load and the first click of an anchor element. If
-    the first click happens before page load, then the sample is recorded in
-    bucket 0. This histogram is recorded when an anchor element is clicked for
-    the first time in the current document.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.HrefEngagementScore"
-    units="score" expires_after="2018-07-03">
-  <obsolete>
-    Removed 07/2018. Replaced with
-    AnchorElementMetrics.Clicked.HrefEngagementScore2.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The target link (href) engagement score of an anchor element. The score is
-    retrieved from the site engagement service. Currently all scores reported
-    are set to 0. This will soon change. This histogram is recorded when the
-    anchor element is clicked.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.HrefEngagementScorePositive"
-    units="score" expires_after="M80">
-  <obsolete>
-    Obsoleted in M79.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The site engagement score of the target link (href) of an anchor element.
-    The score is retrieved from the site engagement service. This histogram is
-    recorded when the anchor element is clicked, and the score is larger than 0.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.NavigationScore" units="score"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The calculated navigation score of the target link (href) of an anchor
-    element. The score is retrieved from the site engagement service. This
-    histogram is recorded when the anchor element is clicked and the score has
-    already been calculated when the document is loaded.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.NavigationScoreRank" units="rank"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The rank of the navigation score of the target link (href) of an anchor
-    element. This histogram is recorded when the anchor element is clicked and
-    the score has already been calculated when the document is loaded.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioContainsImage_ContainsImage"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements that contains
-    images and the total number of anchor elements. This histogram is recorded
-    when the anchor element is clicked and it contains images.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioContainsImage_NoImage"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements that contains
-    images and the total number of anchor elements. This histogram is recorded
-    when the anchor element is clicked and it does not contain images.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_InIframe" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements that is inside an
-    iframe and the total number of anchor elements. This histogram is recorded
-    when the anchor element is clicked and it is inside an iframe.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_NotInIframe"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements that is inside an
-    iframe and the total number of anchor elements. This histogram is recorded
-    when the anchor element is clicked and it is not inside an iframe.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioRootHeight" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio between the height of the root document and the height of the
-    viewport times 100. This histogram is recorded when the anchor element is
-    clicked.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioSameHost_DiffHost" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements whose href have
-    the same host as the document and the total number of anchor elements. This
-    histogram is recorded when the anchor element is clicked and href of the
-    anchor element has a different host than the document.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Clicked.RatioSameHost_SameHost" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements whose href have
-    the same host as the document and the total number of anchor elements. This
-    histogram is recorded when the anchor element is clicked and href of the
-    anchor element has the same host as the document.
-  </summary>
-</histogram>
-
-<histogram
-    name="AnchorElementMetrics.Clicked.RatioUrlIncremented_NotIncremented"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements whose href is
-    incremented by one from the url of the document and the total number of
-    anchor elements. This histogram is recorded when the anchor element is
-    clicked and its href is not incremented by one from the url of the document.
-  </summary>
-</histogram>
-
-<histogram
-    name="AnchorElementMetrics.Clicked.RatioUrlIncremented_UrlIncremented"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the number of anchor elements whose href is
-    incremented by one from the url of the document and the total number of
-    anchor elements. This histogram is recorded when the anchor element is
-    clicked and its href is incremented by one from the url of the document.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.ContainsImage" enum="Boolean"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    True if the anchor element contains an image element, false if it is not.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.DocumentEngagementScore"
-    units="score" expires_after="M80">
-  <obsolete>
-    Obsoleted in M79.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The site engagement score of the document URL. The score is retrieved from
-    the site engagement service.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.HrefEngagementScore2"
-    units="score" expires_after="M80">
-  <obsolete>
-    Obsoleted in M79.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The site engagement score of the target link (href) of an anchor element.
-    The score is retrieved from the site engagement service.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.HrefEngagementScoreExternal"
-    units="score" expires_after="M80">
-  <obsolete>
-    Obsoleted in M79.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The site engagement score of the target link (href) of an anchor element.
-    The score is retrieved from the site engagement service. This histogram is
-    recorded when href is an external link.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.IsAdFrameElement" enum="Boolean"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    True if the anchor element was inside an iframe tagged as an ad iframe.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.IsInIFrame" enum="Boolean"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    True if the anchor element is within an iframe, false if it is not.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.IsUrlIncrementedByOne"
-    enum="Boolean" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    True if the target URL of the anchor element and the URL of the root
-    document only differ by one number, and the number in the target URL equals
-    the number in the the URL of the root document plus one.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.RatioArea" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the clickable region area of an anchor element,
-    and the viewport area.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="AnchorElementMetrics.RatioDistanceCenterToVisibleTop" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the distance from the center of the clickable
-    region of an anchor element to the top edge of the visible region, and the
-    viewport height.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.RatioDistanceRootBottom"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the distance from the bottom of the clickable
-    region of an anchor element to the bottom edge of the root frame, and the
-    viewport height.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.RatioDistanceRootTop"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the distance from the top of the clickable
-    region of an anchor element to the top edge of the root frame, and the
-    viewport height.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.RatioDistanceTopToVisibleTop"
-    units="%" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the distance from the top of the clickable
-    region of an anchor element to the top edge of the visible region, and the
-    viewport height.
-  </summary>
-</histogram>
-
-<histogram base="true" name="AnchorElementMetrics.RatioVisibleArea" units="%"
-    expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The ratio times 100 between the visible clickable region area of an anchor
-    element, and the viewport area.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Visible.HighestNavigationScore"
-    units="score" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The highest navigation score of the anchor elements sent to the browser
-    process on a page load. This histogram is recorded when the webpage is
-    loaded. Normalized to a value between 0.0 and 100.0.
-  </summary>
-</histogram>
-
-<histogram name="AnchorElementMetrics.Visible.NumberOfAnchorElements"
-    units="count" expires_after="2020-05-21">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>chelu@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The number of anchor element metrics sent to the browser process on a page
-    load. This histogram is recorded when the webpage is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Android.Activity.ChromeTabbedActivity.StopReason"
-    enum="AndroidActivityStopReason" expires_after="M81">
-  <obsolete>
-    Removed 2020-01
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    What caused ChromeTabbedActivity#onStop() to be called, which indicates that
-    Chrome is sent to the background.
-  </summary>
-</histogram>
-
-<histogram name="Android.Activity.ChromeTabbedActivity.SystemBackAction"
-    enum="AndroidActivitySystemBackAction" expires_after="2020-01-26">
-  <obsolete>
-    Removed 2020-01
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    What happened when the user hit the system back button in
-    ChromeTabbedActivity.
-  </summary>
-</histogram>
-
-<histogram name="Android.ArmFpu" enum="AndroidArmFpu"
-    expires_after="2019-02-01">
-  <obsolete>
-    Removed 2019-01: New releases of Chrome+Android+ARM rely on NEON support.
-  </obsolete>
-  <owner>fdegans@chromium.org</owner>
-  <summary>
-    Reports the FPU capabilities of the Android ARM device. This is recorded
-    once per browser session during startup.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChildProcessLauncher.OnServiceConnectedTime"
-    units="ms" expires_after="2017-08-29">
-  <obsolete>
-    Removed 08/2017. Made decision in issue 736066 with already acquired data.
-    So this is no longer needed.
-  </obsolete>
-  <owner>boliu@chromium.org</owner>
-  <summary>
-    Measure time from bindService call to onServiceConnected. This is part of
-    launching child services on Android that's under Android's control. Recorded
-    in the first onServiceConnected of a connection.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChildProcessLauncher.OnServiceConnectedTimedOut"
-    enum="BooleanTimedOut" expires_after="2017-08-29">
-  <obsolete>
-    Removed 08/2017. Made decision in issue 736066 with already acquired data.
-    So this is no longer needed.
-  </obsolete>
-  <owner>boliu@chromium.org</owner>
-  <summary>
-    Boolean histogram that records whether bindServiced timed out. Timeout is
-    recorded in a delayed task, and success is recorded in onServiceConnected
-    callback.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.DurationOpen" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Unused as of 7/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>The duration the Chrome Home bottom sheet was open.</summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.OpenReason" enum="ChromeHomeOpenReason"
-    expires_after="2020-03-01">
-  <obsolete>
-    Unused as of 7/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>The reason the bottom sheet was opened.</summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.OpenSheetVelocity.Fail"
-    units="microseconds/dp" expires_after="2018-03-16">
-  <obsolete>
-    Removed 03/2018. Chrome Home is being deprecated.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records the reciprocal of the velocity of a swipe that did not result in the
-    bottom sheet opening. This value is recorded in microseconds per dp traveled
-    and is only recorded if the &quot;chrome-home-swipe-logic&quot; experiment
-    is set to &quot;velocity&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.OpenSheetVelocity.Navigation"
-    units="microseconds/dp" expires_after="2018-03-16">
-  <obsolete>
-    Removed 03/2018. Chrome Home is being deprecated.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records the reciprocal of the velocity of a swipe that resulted in the
-    bottom sheet opening and the user navigating to a URL or a different sheet
-    content. This value is recorded in microseconds per dp traveled.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.OpenSheetVelocity.NoNavigation"
-    units="microseconds/dp" expires_after="2018-03-16">
-  <obsolete>
-    Removed 03/2018. Chrome Home is being deprecated.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records the reciprocal of the velocity of a swipe that resulted in the
-    bottom sheet opening but the user taking no action (i.e. the next action is
-    the sheet closing). This value is recorded in microseconds per dp traveled.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.OpenSheetVelocity.Success"
-    units="microseconds/dp" expires_after="2018-03-16">
-  <obsolete>
-    Removed 03/2018. Chrome Home is being deprecated.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records the reciprocal velocity of a swipe that resulted in the bottom sheet
-    opening. This value is recorded in microseconds per dp traveled and is only
-    recorded if the &quot;chrome-home-swipe-logic&quot; experiment is set to
-    &quot;velocity&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Promo.Result.Menu"
-    enum="ChromeHomePromoResult" expires_after="2018-01-22">
-  <obsolete>
-    Removed 01/2018 with the removal of the first version of Chrome Home.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The result of showing the Chrome Home promo when launched from the overflow
-    menu. This action can only be performed if Chrome Home is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Promo.Result.NTP"
-    enum="ChromeHomePromoResult" expires_after="2018-01-22">
-  <obsolete>
-    Removed 01/2018 with the removal of the first version of Chrome Home.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The result of showing the Chrome Home promo when launched from the NTP. This
-    action can only be performed if Chrome Home is disabled.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Promo.Result.Startup"
-    enum="ChromeHomePromoResult" expires_after="2018-01-22">
-  <obsolete>
-    Removed 01/2018 with the removal of the first version of Chrome Home.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The result of showing the Chrome Home promo when launched from startup. This
-    action can only be performed if Chrome Home is disabled.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Promo.ShowReason"
-    enum="ChromeHomePromoShowReason" expires_after="2018-01-22">
-  <obsolete>
-    Removed 01/2018 with the removal of the first version of Chrome Home.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>The reason the Chrome Home promo was shown.</summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Survey.DownloadResponseCode"
-    enum="SurveyDownloadResponseCodes" expires_after="2018-04-12">
-  <obsolete>
-    Removed 04/2018. Replaced with Android.Survey.DownloadResponseCode.
-  </obsolete>
-  <owner>danielpark@chromium.org</owner>
-  <summary>The response code of the completed survey download request.</summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Survey.InfoBarClosingState"
-    enum="InfoBarClosingStates" expires_after="2018-04-12">
-  <obsolete>
-    Removed 04/2018. Replaced with Android.Survey.InfoBarClosingState.
-  </obsolete>
-  <owner>danielpark@chromium.org</owner>
-  <summary>
-    If the infobar was visible when it was closed and if it was closed directly
-    or not.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Survey.ShowSurvey" enum="BooleanSuccess"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed 04/2018. Replaced with Android.Survey.ShowSurvey.
-  </obsolete>
-  <owner>danielpark@chromium.org</owner>
-  <summary>
-    Whether or not the survey was successfully shown after its download.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.Survey.SurveyFilteringResults"
-    enum="SurveyFilteringResult" expires_after="2018-04-12">
-  <obsolete>
-    Removed 04/2018. Replaced with Android.Survey.SurveyFilteringResults.
-  </obsolete>
-  <owner>danielpark@chromium.org</owner>
-  <summary>
-    The result of the survey filtering process. Each enum represents a different
-    filter that caught the user. This is recorded on cold starts when we check
-    if a user qualifies for a survey.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.TimeBetweenCloseAndNextOpen" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Unused as of 7/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The time between the last time the Chrome Home bottom sheet was closed and
-    the next time it was opened.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.TimeToFirstOpen" units="ms"
-    expires_after="2020-03-01">
-  <obsolete>
-    Unused as of 7/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The time between app creation and the first open of the Chrome Home bottom
-    sheet for this run of Chrome.
-  </summary>
-</histogram>
-
-<histogram name="Android.ChromeHome.UserPreference.Enabled"
-    enum="BooleanEnabled" expires_after="M80">
-  <obsolete>
-    Unused as of 7/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records whether or not the user preference for Chrome Home is set to
-    enabled. This is recorded whenever the browser is restarted and the state of
-    Chrome Home is first checked. This metric is only recorded if the user's
-    preference is set.
-  </summary>
-</histogram>
-
-<histogram name="Android.CustomFeedback.Category"
-    enum="AndroidFeedbackCategory" expires_after="2018-12-15">
-  <obsolete>
-    Removed 12/2018. CustomFeedback never shipped to 100% and is no longer
-    planned for launch.
-  </obsolete>
-  <owner>jwanda@chromium.org</owner>
-  <summary>
-    Recorded when the user selects a category button when in the Custom Feedback
-    UI.
-  </summary>
-</histogram>
-
-<histogram name="Android.CustomFeedback.CategoryDetails"
-    enum="AndroidFeedbackCategoryDetails" expires_after="2018-12-15">
-  <obsolete>
-    Removed 12/2018. CustomFeedback never shipped to 100% and is no longer
-    planned for launch.
-  </obsolete>
-  <owner>jwanda@chromium.org</owner>
-  <summary>
-    Recorded when a user selects an option related to their problem within the
-    Custom Feedback UI.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.Chips.Enabled" units="chips"
-    expires_after="2020-01-30">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>shaktisahu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Records the number of chips being shown on download home. Recorded during
-    initialization and also during any list change.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.List.Section.Menu.Images.Action"
-    enum="Android.DownloadManager.List.Section.Menu.Actions"
-    expires_after="M80">
-  <obsolete>
-    Removed October 2019. The feature was dropped during implementation review.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>shaktisahu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>Recorded when a menu action is taken on the images section.</summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.NotificationLaunch"
-    enum="DownloadNotificationLaunchType" expires_after="M80">
-  <obsolete>
-    Removed July 2019. The relaunch rarely happens.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Records instances when a notification is being launched for the first time
-    or relaunched due to the need to dissociate the notification from the
-    foreground (only on API less than 24).
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.NotificationsCount.ForegroundDisabled"
-    units="notifications" expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Records the number of notifications that are already existing (presumably
-    displayed) when a new notification is being launched to help understand the
-    frequency of multiple downloads with downloads as a foreground service
-    disabled.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.NotificationsCount.ForegroundEnabled"
-    units="notifications" expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Records the number of notifications that are already existing (presumably
-    displayed) when a new notification is being launched to help understand the
-    frequency of multiple downloads with downloads as a foreground service
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.OtherExtensions.InitialCount"
-    enum="AndroidDownloadExtensionType" expires_after="2020-09-06">
-  <obsolete>
-    Deprecated Jan 2020.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The extension type for non-incognito download items that match the
-    &quot;other&quot; filter type. Recorded when the download UI is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.OtherExtensions.OpenFailed"
-    enum="AndroidDownloadExtensionType" expires_after="M81">
-  <obsolete>
-    Deprecated Jan 2020.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The extension type for downloads that match the &quot;other&quot; filter
-    type. Recorded when a download fails to open.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.OtherExtensions.OpenSucceeded"
-    enum="AndroidDownloadExtensionType" expires_after="M81">
-  <obsolete>
-    Deprecated Jan 2020.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The extension type for downloads that match the &quot;other&quot; filter
-    type. Recorded when a download is opened.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.OtherExtensions.Share"
-    enum="AndroidDownloadExtensionType" expires_after="2020-09-06">
-  <obsolete>
-    Deprecated Jan 2020.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The extension type for downloads that match the &quot;other&quot; filter
-    type. Recorded when downloads are shared through the download manager.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.ShowStorageInfo" enum="BooleanVisible"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2016 with code removal of download home V1 to follow.
-  </obsolete>
-  <owner>shaktisahu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Recorded when the user clicks the info button on download home to toggle the
-    storage info. The state recorded is after the visibility is toggled.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.ViewRetentionTime.Audio"
-    units="minutes" expires_after="2020-01-30">
-  <obsolete>
-    Removed on Jan 2020.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The duration between when an audio file is downloaded and when the file is
-    opened, only recorded when the user opens the file in download home UI.
-  </summary>
-</histogram>
-
-<histogram name="Android.DownloadManager.ViewRetentionTime.Video"
-    units="minutes" expires_after="2020-01-30">
-  <obsolete>
-    Removed on Jan 2020.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    The duration between when a video file is downloaded and when the file is
-    opened, only recorded when the user opens the file in download home UI.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Android.FeatureModules.CachedInstallDuration"
-    units="ms" expires_after="2021-01-31">
-  <obsolete>
-    Removed 2019-09 in favour of
-    Android.FeatureModules.CachedAwakeInstallDuration.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AndroidFeatureModuleName" -->
-
-  <owner>agrieve@chromium.org</owner>
-  <owner>fredmello@chromium.org</owner>
-  <owner>tiborg@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Duration of successful installs for each dynamic feature module. Only
-    contains install durations for modules first requested *before* Chrome
-    started last and may therefore be installed from cache.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Android.FeatureModules.UncachedInstallDuration"
-    units="ms" expires_after="2021-01-31">
-  <obsolete>
-    Removed 2019-09 in favour of
-    Android.FeatureModules.UncachedAwakeInstallDuration.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AndroidFeatureModuleName" -->
-
-  <owner>agrieve@chromium.org</owner>
-  <owner>fredmello@chromium.org</owner>
-  <owner>tiborg@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Duration of successful installs for each dynamic feature module. Only
-    contains install durations of modules first requested *after* Chrome started
-    last and are therefore unlikely to be installed from cache.
-  </summary>
-</histogram>
-
-<histogram name="Android.HistoryPage.OpenSelected" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of selected items the user opened in new tabs from the native
-    Android history page.
-  </summary>
-</histogram>
-
-<histogram name="Android.HistoryPage.RemoveSelected" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of selected items the user removed from the native Android
-    history page.
-  </summary>
-</histogram>
-
-<histogram name="Android.InstantApps.ApiCallDuration2" units="ms"
-    expires_after="2018-06-05">
-  <obsolete>
-    Not being recorded as of 2017.
-  </obsolete>
-  <owner>mariakhomenko@chromium.org</owner>
-  <summary>
-    Measures the amount of time spent in the getInstantAppIntent() API call.
-  </summary>
-</histogram>
-
-<histogram name="Android.IntentHeaders" enum="IntentHeadersResult"
-    expires_after="M85">
-  <obsolete>
-    Removed in M86. No longer tracked.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Records the usage of the Browser.EXTRA_HEADERS field for Intents that Chrome
-    receives, breaking down by type of header and by whether the launching app
-    was first or third party.
-  </summary>
-</histogram>
-
-<histogram name="Android.IntentNonSafelistedHeaderNames"
-    enum="AndroidIntentNonSafelistedHeaderNameHashes" expires_after="M85">
-  <obsolete>
-    Removed in M86. No longer tracked.
-  </obsolete>
-  <owner>jochen@chromium.org</owner>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Records hashes of header names used in the Browser.EXTRA_HEADERS fields for
-    Intents that Chrome receives that aren't on the CORS header safelist. This
-    can be used to match against known types of headers to measure their
-    frequencies.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiInstanceMigration.FailedToRenameMetadataFile"
-    enum="Boolean" expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Renaming the old tab metadata file failed during multi-instance migration.
-    Only true is recorded.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiInstanceMigration.NewMetadataFileExists"
-    enum="Boolean" expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    The new tab metadata file already existed when multi-instance migration was
-    attempted. Only true is recorded.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiWindowMode.IsTabletScreenWidthBelow600"
-    enum="Boolean" expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Records whether the screen width is below 600dp when the activity is in
-    Android N multi-window mode. True if the screen width is less than 600dp and
-    false if is greater than or equal to 600dp.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiWindowMode.ScreenHeight" units="dp"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Records the screen height in dp when the activity is in Android N
-    multi-window mode. Clamped at 200dp to 1200dp.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiWindowMode.ScreenWidth" units="dp"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Records the screen width in dp when the activity is in Android N
-    multi-window mode. Clamped at 200dp to 1200dp.
-  </summary>
-</histogram>
-
-<histogram name="Android.MultiWindowMode.TabletScreenWidth" units="dp"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Records the screen width in dp when the activity is in Android N
-    multi-window mode and the width is below 600dp.
-  </summary>
-</histogram>
-
-<histogram name="Android.NativeLibraryPreloader.Result.Browser"
-    enum="NativeLibraryPreloaderResult" expires_after="M80">
-  <obsolete>
-    Removed in July 2019. See https://crbug.com/975556.
-  </obsolete>
-  <owner>michaelbai@chromium.org</owner>
-  <summary>
-    The return value of NativeLibraryPreloader.loadLibrary() in browser process,
-    is recorded once per browser process start.
-  </summary>
-</histogram>
-
-<histogram name="Android.NativeLibraryPreloader.Result.Renderer"
-    enum="NativeLibraryPreloaderResult" expires_after="M80">
-  <obsolete>
-    Removed in July 2019. See https://crbug.com/975556.
-  </obsolete>
-  <owner>michaelbai@chromium.org</owner>
-  <summary>
-    The return value of NativeLibraryPreloader.loadLibrary() in renderer
-    process, is recorded once per renderer process start.
-  </summary>
-</histogram>
-
-<histogram name="Android.Permissions.ReadStorage"
-    enum="BooleanHasReadStoragePermission" expires_after="M77">
-  <obsolete>
-    Removed from the code in July 2019. See https://crbug.com/975701.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>ewald@chromium.org</owner>
-  <summary>
-    At startup, records whether the Chrome application has been granted the read
-    storage permission on Android.
-  </summary>
-</histogram>
-
-<histogram name="Android.RecentTabsManager.OtherDevices" units="count"
-    expires_after="M82">
-  <obsolete>
-    Removed in July, 2020
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Records the number of other devices listed in recent tabs page when recent
-    tabs page is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Android.RecentTabsManager.RecentlyClosedTabs" units="count"
-    expires_after="M82">
-  <obsolete>
-    Removed in July, 2020
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Records the number of recently-closed tabs shown in recent tabs page when
-    recent tabs page is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Android.RecentTabsManager.TotalTabs" units="count"
-    expires_after="M82">
-  <obsolete>
-    Removed in July, 2020
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Records the total number of tabs listed in recent tabs page (sum of all tab
-    from other devices plus recently-closed tabs) when recent tabs page is
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="Android.SeccompStatus.Prctl" enum="AndroidSeccompStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed from the code in July 2019. See https://crbug.com/975749.
-  </obsolete>
-  <owner>rsesek@chromium.org</owner>
-  <summary>
-    Reports the level of kernel support for the seccomp-bpf sandbox using
-    prctl(PR_SET_SECCOMP).
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.CheckGooglePlayServicesTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019. See https://crbug.com/577190 for context.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from checking for
-    whether play services is available.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.CheckGoogleSignedTime" units="ms"
-    expires_after="M78">
-  <obsolete>
-    Removed July 2019 (http://crbug.com/984291).
-  </obsolete>
-  <owner>estevenson@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from checking for
-    whether a package is Google signed.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.DocumentModeSharedPrefs" units="ms"
-    expires_after="2016-05-25">
-  <obsolete>
-    Removed 05/2016 in Issue 582539 with the removal of document mode.
-  </obsolete>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from fetching the
-    DocumentMode shared preferences file.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.DocumentTabStateLoad" units="ms"
-    expires_after="2016-05-25">
-  <obsolete>
-    Removed 05/2016 in Issue 582539 with the removal of document mode.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from document mode
-    loading its prioritized tab's state.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.DownloadsDir" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019. See https://crbug.com/508615 for context.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from fetching and
-    possibly creating the downloads directory.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.NotificationUIBuildTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from custom
-    notification builder through date formatting.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.SnippetUIBuildTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from snippet UI
-    through date formatting.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.WebappAuthenticatorMac" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from looking up a
-    webapp's MAC on startup.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.WebappDir" units="ms" expires_after="M77">
-  <obsolete>
-    Removed from code June 2019.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from fetching for
-    creating the webapp directory.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.WebappSaveState" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code June 2019.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from reading and
-    saving webapp state.
-  </summary>
-</histogram>
-
-<histogram name="Android.StrictMode.WebappSharedPrefs" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code July 2019.
-  </obsolete>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Measures the amount of time due to a StrictMode violation from fetching the
-    Webapp shared preferences file.
-  </summary>
-</histogram>
-
-<histogram name="Android.TabNavigationInterceptResult"
-    enum="NavigationInterceptResult" expires_after="M81">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    The distribution of results when running ExternalNavigationHandler, this
-    shows how often we send intents to be handled by other applications.
-  </summary>
-</histogram>
-
-<histogram name="Android.TabPersistentStore.MergeStateMetadataFileSize"
-    units="bytes" expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of bytes read for the other tab state's metadata file when
-    merging tab states in Android N+.
-  </summary>
-</histogram>
-
-<histogram name="Android.TabPersistentStore.MergeStateTabCount" units="tabs"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of normal and incognito tabs merged (for Android N+
-    multi-instance). This will be logged for both cold-start and non-cold-start
-    merging assuming that the native library is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Android.TabPersistentStore.MergeStateTimePerTab" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Measures the amount of time it takes to restore state for each merged tab
-    (for Android N+ multi-instance). This will only be logged for non-cold-start
-    merging, because restoring merged tabs is not distingushed from restoring
-    regular tabs on cold start.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Android.WebView.DevUi.SessionDuration" units="ms"
-    expires_after="2021-01-20">
-  <obsolete>
-    Removed May 2020 because this only captures sessions up to 10 seconds long.
-    Use Android.WebView.DevUi.SessionDuration2 instead, which captures sessions
-    up to an hour.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="AndroidWebViewFragments" -->
-
-  <owner>ntfschr@chromium.org</owner>
-  <owner>hazems@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Records the time spent using a specific tool, from creation to destruction.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.ExtraHeaders" enum="WebViewExtraHeaders"
-    expires_after="2020-10-01">
-  <obsolete>
-    Replaced by Android.WebView.ExtraHeadersRedirect 2020-07
-  </obsolete>
-  <owner>torne@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Record when extra headers are added to requests by AwURLLoaderThrottle and
-    whether they were kept or removed during redirects.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.Gfx.FunctorStencilEnabled"
-    enum="BooleanEnabled" expires_after="M78">
-  <obsolete>
-    Removed in M79. Obtained required data from M78.
-  </obsolete>
-  <owner>boliu@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Record in a functor draw whether stencil test is enabled by Android HWUI.
-    This is recorded every frame. Note some OS versions never use stencil so
-    worth checking result split by OS version.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.LoadUrl.DataUriHasOctothorpe" enum="Boolean"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019/10/11. This histogram was never well understood and the
-    underlying feature has been shipped for some time anyway.
-  </obsolete>
-  <owner>smcgruer@chromium.org</owner>
-  <summary>
-    Records if a data url passed to loadUrl had a '#' character. This is to be
-    used in the effort to deprecate the incorrect treatment of '#' characters in
-    data URIs; see http://crbug.com/823666#c30.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.Metrics.BackfillInstallDate"
-    enum="InstallDateBackfill" expires_after="M83">
-  <obsolete>
-    Removed in April 2020. The backfill logic is deemed no longer necessary to
-    keep around.
-  </obsolete>
-  <owner>ntfschr@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Records whether WebView needed to backfill the install date pref with
-    Android frameworks APIs. Recorded once during startup (metrics service
-    initializtion).
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.Mimetype.AppProvided"
-    enum="WebViewAppProvidedMimeType" expires_after="2020-05-14">
-  <obsolete>
-    Removed in April 2020. Network Service has launched, and we don't intend to
-    follow up on this metric.
-  </obsolete>
-  <owner>ntfschr@chromium.org</owner>
-  <owner>timvolodine@chromium.org</owner>
-  <summary>
-    Records information about the specified MIME types for app-provided content
-    loaded in Android WebView. At the moment, this focuses on
-    shouldInterceptRequest, ContentProvider-supplied content, and app
-    assets/resources (where we expect the app to use proper file extensions to
-    indicate MIME type), and is recorded as part of the process of loading each
-    resource. This may apply to any type of resource (frame HTML, subresource,
-    etc.).
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.onReceivedSslError.ErrorCode"
-    enum="AndroidWebViewSslErrorType" expires_after="2020-05-08">
-  <obsolete>
-    Removed 09/2020. These are no longer being tracked.
-  </obsolete>
-  <owner>laisminchillo@chromium.org</owner>
-  <owner>timvolodine@chromium.org</owner>
-  <summary>
-    The WebViewClient SSL error code as received by onReceivedSslError.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.onSafeBrowsingHit.ThreatType"
-    enum="AndroidWebViewClientSafeBrowsingThreatType"
-    expires_after="2020-04-24">
-  <obsolete>
-    Removed 04/2020. These metrics are tracked generally for SafeBrowsing, and
-    WebView no longer needs specializations.
-  </obsolete>
-  <owner>laisminchillo@chromium.org</owner>
-  <owner>timvolodine@chromium.org</owner>
-  <summary>
-    Records the WebViewClient safe browsing threat type as returned by
-    onSafeBrowsingHit callback.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.SplitApkWorkaroundResult"
-    enum="SplitApkWorkaroundResult" expires_after="M81">
-  <obsolete>
-    Removed in M73. Bundles have shipped.
-  </obsolete>
-  <owner>tiborg@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Result of applying a workaround to fix a crash on Android O if the WebView
-    provider is a split APK (see crbug.com/889954 for more details).
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.VariationsEnableState"
-    enum="AndroidWebViewVariationsEnableState" expires_after="M69">
-  <obsolete>
-    Removed from code July 2018. Variations in WebView has launched.
-  </obsolete>
-  <owner>changwan@chromium.org</owner>
-  <summary>
-    Indicates whether variations is enabled. We want to know how enabling
-    variations affects metrics, but we can't enable variations as a variations
-    study, since variations can't enable/disable itself. Instead, WebView
-    hard-codes a random variable for enabling variations, and reports the result
-    in this histogram.
-  </summary>
-</histogram>
-
-<histogram name="AndroidTabCloseUndo.Toast"
-    enum="AndroidTabCloseUndoToastEvent" expires_after="M82">
-  <obsolete>
-    Removed as of 06/2020. Mostly tracked with Snackbar.Shown.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    When a user closes a tab an undo toast will popup on certain devices giving
-    the user the chance to undo closing that tab. This stat tracks how the user
-    interacts with that UI and what actions they take. A cold start means that
-    the undo bar wasn't showing when it was triggered to show again. A warm
-    start means that it was. Warm starts can happen when the user closes
-    multiple tabs close together. When the undo bar is dismissed, all closes
-    that were queued up to be undone are committed. This can happen either by a
-    timeout or by an action by the user to move to another part of the UI.
-  </summary>
-</histogram>
-
-<histogram name="Animation.AnimationWorklet.GlobalScope.MutateDuration"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed as of 01/2019. Replaced with
-    Animation.AnimationWorklet.MutateDuration.
-  </obsolete>
-  <owner>majidvp@chromium.org</owner>
-  <owner>animations-dev@chromium.org</owner>
-  <summary>
-    The time it takes for AnimationWorkletGlobalScope to produce a mutation
-    update. This includes all V8 script execution cost.
-  </summary>
-</histogram>
-
-<histogram name="appcache.CheckResponseResult"
-    enum="AppCacheCheckResponseResult" expires_after="M77">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>AppCache check response result code.</summary>
-</histogram>
-
-<histogram name="appcache.CompletionQueueTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Time elapsed between a completion task being queued and run.
-  </summary>
-</histogram>
-
-<histogram name="appcache.CompletionRunTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The amount of time taken to run a completion task on the IO thread.
-  </summary>
-</histogram>
-
-<histogram name="appcache.CorruptionDetected" units="units" expires_after="M80">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Tracks the number of times corruption is detected in the sql database.
-  </summary>
-</histogram>
-
-<histogram name="appcache.InitResult" enum="AppCacheInitResult"
-    expires_after="M80">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>AppCache initialization result code.</summary>
-</histogram>
-
-<histogram name="appcache.JobStartDelay.AppCache" units="ms"
-    expires_after="2018-07-23">
-  <obsolete>
-    Removed 2018-03-20. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    How long URLRequests to be retrieved from the appcache are delayed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.JobStartDelay.Error" units="ms"
-    expires_after="2018-07-23">
-  <obsolete>
-    Removed 2018-03-20. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    How long URLRequests that result in a synthesized error are delayed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.JobStartDelay.Network" units="ms"
-    expires_after="2018-07-23">
-  <obsolete>
-    Removed 2018-03-20. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    How long URLRequests to be retrieved over the network are delayed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.MainPageLoad" enum="BooleanSecure"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Counts the number of appcached page loads for secure vs insecure origins.
-  </summary>
-</histogram>
-
-<histogram name="appcache.MainResourceResponseRetrieval" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Tracks the success rate of retrieving a main resource from the appcache.
-  </summary>
-</histogram>
-
-<histogram name="appcache.Manifest.FallbackPattern" enum="BooleanPresent"
-    expires_after="M82">
-  <obsolete>
-    Removed 01/2020. Feature has been removed.
-  </obsolete>
-  <owner>pwnall@chromium.org</owner>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The proportion of manifests that use patterns in valid FALLBACK: entries.
-    Only tracks manifests that were successfully parsed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.Manifest.NetworkPattern" enum="BooleanPresent"
-    expires_after="M82">
-  <obsolete>
-    Removed 01/2020. Feature has been removed.
-  </obsolete>
-  <owner>pwnall@chromium.org</owner>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The proportion of manifests that use patterns in valid NETWORK: entries.
-    Only tracks manifests that were successfully parsed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.Manifest.Pattern" enum="BooleanPresent"
-    expires_after="M82">
-  <obsolete>
-    Removed 01/2020. Feature has been removed.
-  </obsolete>
-  <owner>pwnall@chromium.org</owner>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The proportion of manifests that use patterns in any valid entries. Only
-    tracks manifests that were successfully parsed.
-  </summary>
-</histogram>
-
-<histogram name="appcache.Manifest.ValidManifestURL" enum="BooleanValid"
-    expires_after="M82">
-  <obsolete>
-    Removed as of 5/2019. No longer needed.
-  </obsolete>
-  <owner>cmp@chromium.org</owner>
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    The proportion of ParseManifest calls that are triggered using a valid vs an
-    invalid manifest URL.
-  </summary>
-</histogram>
-
-<histogram name="appcache.MissingManifestDetectedAtCallsite"
-    enum="AppCacheErrorSite" expires_after="M80">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>Identifies where a missing manifest was detected occured.</summary>
-</histogram>
-
-<histogram name="appcache.MissingManifestEntry" enum="BooleanSuccess"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Logged on each occurrence of there being no record for the manifest file in
-    the entries table.
-  </summary>
-</histogram>
-
-<histogram name="appcache.SubResourceResponseRetrieval" enum="BooleanSuccess"
-    expires_after="M80">
-  <obsolete>
-    Removed on 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Tracks the success rate of retrieving a sub resource from the appcache.
-  </summary>
-</histogram>
-
-<histogram name="appcache.TaskQueueTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Time elapsed between a background task being queued and run.
-  </summary>
-</histogram>
-
-<histogram name="appcache.TaskRunTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>The amount of time taken to run a background task.</summary>
-</histogram>
-
-<histogram name="appcache.UpdateJob.ExistingVaryDuring304" units="units"
-    expires_after="2021-05-25">
-  <obsolete>
-    Removed on 2020-08-20. No longer tracked.
-  </obsolete>
-  <owner>cmp@chromium.org</owner>
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    Tracks the number of times while handling a 304 response a cached response
-    has a Vary header while the incoming 304 response doesn't.
-  </summary>
-</histogram>
-
-<histogram name="appcache.UpdateJobResult" enum="AppCacheUpdateJobResult"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>AppCache update job result code.</summary>
-</histogram>
-
-<histogram name="appcache.UpdateProgressAtPointOfFaliure" units="%"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>Percent completion at point of failure of an update job.</summary>
-</histogram>
-
-<histogram name="appcache.UpdateWasOffOriginAtPointOfFailure" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Whether the resource causing the failure was from a different origin.
-  </summary>
-</histogram>
-
-<histogram name="appcache.UpdateWasStalledAtPointOfFailure" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-06-17. No longer tracked.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Whether any progresss had been made in the 5 minutes preceeding failure.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppLauncherPromo" enum="AppLauncherPromo"
-    expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017 in issue 600915 with the removal of app list on platforms
-    other than Chrome OS.
-  </obsolete>
-  <owner>mad@chromium.org</owner>
-  <summary>Interactions with the App Launcher promo dialog.</summary>
-</histogram>
-
-<histogram name="Apps.AppList.ZeroStateResultsList.LaunchedItemPosition"
-    units="position" expires_after="M80">
-  <obsolete>
-    Removed October 2019, replaced by
-    Apps.AppList.ZeroStateResultsList.LaunchedItemPositionV2, which uses
-    different bucketing.
-  </obsolete>
-  <owner>wrong@chromium.org</owner>
-  <owner>tby@chromium.org</owner>
-  <owner>jiameng@chromium.org</owner>
-  <summary>
-    The position index of an item launched from zero state search results.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppList.ZeroStateResultsList.NumImpressionTypes"
-    units="count" expires_after="M81">
-  <obsolete>
-    Removed October 2019, replaced by
-    Apps.AppList.ZeroStateResultsList.NumImpressionTypesV2, which uses different
-    bucketing.
-  </obsolete>
-  <owner>wrong@chromium.org</owner>
-  <owner>tby@chromium.org</owner>
-  <owner>jiameng@chromium.org</owner>
-  <summary>
-    The number of item types included in each zero state impression set.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppList.ZeroStateSearchResutRemovalDecision"
-    enum="AppListResultRemovalConfirmation" expires_after="2019-12-31">
-  <obsolete>
-    Removed June 2019, replaced by
-    Apps.AppList.ZeroStateSearchResultRemovalDecision.
-  </obsolete>
-  <owner>jennyz@chromium.org</owner>
-  <owner>newcomer@chromium.org</owner>
-  <summary>
-    The decision of the user whether to remove a zero state search result. This
-    is gathered per click of a remove or cancel button of a search result
-    removal confirmation dialog.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListAppLaunched" enum="SuggestedAppListAppLaunched"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 04/2019 in favor Apps.AppListAppLaunchedV2.
-  </obsolete>
-  <owner>newcomer@chromium.org</owner>
-  <summary>
-    The number of apps launched from the launcher. This is logged each time an
-    app is launched. The bucket denotes whether the app is suggested.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListAppLaunchedFullscreen"
-    enum="SuggestedAppListAppLaunched" expires_after="M80">
-  <obsolete>
-    Removed as of 04/2019 in favor Apps.AppListAppLaunchedV2.
-  </obsolete>
-  <owner>newcomer@chromium.org</owner>
-  <summary>
-    The number of apps launched from the fullscreen launcher. This is logged
-    each time an app is launched. The bucket denotes whether the app is
-    suggested.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListDoodleAction" enum="AppListDoodleAction"
-    expires_after="2018-01-20">
-  <obsolete>
-    App list doesn't support doodles anymore.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <summary>
-    The number of user interactions with the app list doodle. This is logged
-    once per action.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListDriveQuickAccessProvider.ResultPresence"
-    enum="AppListDriveQuickAccessResultPresence" expires_after="2020-08-02">
-  <obsolete>
-    Removed January 2020, this was a debugging metric that was too expensive to
-    keep in the code.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>wrong@chromium.org</owner>
-  <owner>jiameng@chromium.org</owner>
-  <summary>
-    Emitted when the launcher updates the displayed zero-state search results.
-    Records whether a) a Drive QuickAccess result was displayed, b) a DQA result
-    was present in the candidate results list but wasn't one of the top 5 so was
-    not displayed, or c) no DQA results were in the results list.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListHowEnabled" enum="AppListEnableSource"
-    expires_after="2018-03-20">
-  <obsolete>
-    Removed 03/2018 with Mash AppList refactoring.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    The trigger that caused the app list to be enabled. Recorded when the user
-    first shows the app list. If not shown after one hour, will be recorded
-    then. If Chrome was not running at the one-hour mark, will be recorded
-    during the next Chrome startup.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListLaunchRecorderError"
-    enum="AppListLaunchRecorderError" expires_after="2020-05-18">
-  <obsolete>
-    Removed January 2020, the app list launch recorded has been removed.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>charleszhao@chromium.org</owner>
-  <summary>
-    Reports error states of the app list launch recorder system.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListSearchResultDistanceFromOrigin" units="keystrokes"
-    expires_after="2020-05-24">
-  <obsolete>
-    Removed 2020-05. Not needed any longer.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <summary>
-    The minimum number of arrow keys a user would need to press to navigate to
-    the opened search result. This is gathered per click of a search result.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListSearchResultOpenType" enum="AppListSearchResult"
-    expires_after="2019-03-22">
-  <obsolete>
-    Removed March 2019. Replaced with Apps.AppListSearchResultOpenTypeV2.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    The type of app list search result that was opened by the user. This is
-    gathered per SearchResult opened. Only recorded for search results shown in
-    the search result page of the launcher, except for M-62 where suggestion
-    chips were recorded as search results (https://crbug.com/919550). M-62
-    should be filtered out when viewing this histogram to ignore the metrics
-    caused by the above mentioned bug.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListTileLaunchIndexAndQueryLength"
-    units="(index, query length)" expires_after="M84">
-  <obsolete>
-    Removed 04/2020. The related app ranking experiments have finished.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>jiameng@chromium.org</owner>
-  <summary>
-    The index of a clicked result in the search result app tiles and the length
-    of the search query. The index is relative to the SearchTileItemListView,
-    not the overall position in the suggestion window.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListTimeToDiscover" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 2018-03.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    Time between enabling the app list, and a user explicitly choosing to show
-    it. If the app list is not shown after one hour, an entry in the last bucket
-    is recorded. If the user installs a second packaged app within one hour, or
-    if the app list was not enabled by installing a packaged app from the Web
-    Store, no time value is recorded - only Apps.AppListHowEnabled.
-  </summary>
-</histogram>
-
-<histogram name="Apps.AppListWarmupDuration" units="ms"
-    expires_after="2016-08-01">
-  <obsolete>
-    Removed 07/2016 in Issue 600915 with the removal of the app list on Windows.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    The amount of time spent in warmup (in WarmupForProfile call). This will
-    tell us how long warmup blocks the UI.
-  </summary>
-</histogram>
-
-<histogram name="Apps.FileHandler.Registration.Mac.Result"
-    enum="FileHandlerRegistrationMacResult" expires_after="M90">
-  <obsolete>
-    Removed 08/2020. File handler registration is done through shortcuts
-    creation, replaced by WebApp.Shortcuts.Creation.Result.
-  </obsolete>
-  <owner>phillis@chromium.org</owner>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    Records the result of file handler registration for PWA on MacOS
-  </summary>
-</histogram>
-
-<histogram name="Apps.LockScreen.NoteTakingApp.UnlockUIAction"
-    enum="LockScreenNoteTakingUnlockUIAction" expires_after="M80">
-  <obsolete>
-    Obsolete - tracks actions in UI that did not launch.
-  </obsolete>
-  <owner>tbarzic@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The action the user took on the lock screen UI shown when lock screen app
-    window is in background, shown under the lock screen.
-  </summary>
-</histogram>
-
-<histogram name="Apps.Window.Type" enum="AppsWindowType" expires_after="M82">
-  <obsolete>
-    There was only one valid value starting in M69 and code to record the values
-    was removed in M85.
-  </obsolete>
-  <owner>stevenjb@chromium.org</owner>
-  <summary>
-    The type of app window opened (through the chrome.app.window API).
-  </summary>
-</histogram>
-
-<histogram name="Arc.CustomTabs.SessionLifetime.All" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019. Replaced by Arc.CustomTabs.SessionLifetime2.All to extend
-    the max value.
-  </obsolete>
-  <owner>hashimoto@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>Lifetime of each session. Recorded when a session ends.</summary>
-</histogram>
-
-<histogram name="Arc.CustomTabs.SessionLifetime.Closed" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019. Replaced by Arc.CustomTabs.SessionLifetime2.Closed to
-    extend the max value.
-  </obsolete>
-  <owner>hashimoto@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>
-    Lifetime of each session. Recorded when a session is closed.
-  </summary>
-</histogram>
-
-<histogram name="Arc.CustomTabs.SessionLifetime.ForwardedToNormalTab"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 06/2019. Replaced by
-    Arc.CustomTabs.SessionLifetime2.ForwardedToNormalTab to extend the max
-    value.
-  </obsolete>
-  <owner>hashimoto@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>
-    Lifetime of each session. Recorded when a session ends because the tab was
-    forwarded to a normal tab.
-  </summary>
-</histogram>
-
-<histogram name="Arc.IntentHandlerAction" enum="ArcIntentHandlerAction"
-    expires_after="2018-04-16">
-  <obsolete>
-    Removed April 2018 and replaced by ChromeOS.Apps.IntentPickerAction.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>ARC intent handler action taken by user.</summary>
-</histogram>
-
-<histogram name="Arc.IntentHandlerDestinationPlatform"
-    enum="ArcIntentHandlerDestinationPlatform" expires_after="2018-04-16">
-  <obsolete>
-    Removed April 2018 and replaced by
-    ChromeOS.Apps.IntentPickerDestinationPlatform.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>
-    ARC intent handler destination platform. The destination may be specified
-    due to the user explicit selection or a previously stored preference.
-  </summary>
-</histogram>
-
-<histogram name="Arc.OOMKills.Score" units="badness score"
-    expires_after="2020-09-03">
-  <obsolete>
-    Removed 09/2020 for Issue 1124182.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>
-    The oom_badness score of a OOM killed process as reported by kernel.
-  </summary>
-</histogram>
-
-<histogram name="Arc.OOMKills.TimeDelta" units="ms" expires_after="M82">
-  <obsolete>
-    Removed 09/2020 for Issue 1124182.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <owner>shihuis@google.com</owner>
-  <summary>The elapsed time since last OOM kill event.</summary>
-</histogram>
-
-<histogram name="ArcRuntime.LowMemoryKiller.FreedSize" units="KB"
-    expires_after="2016-03-27">
-  <obsolete>
-    Renamed to Arc.LowMemoryKiller.FreedSize on 2016/03/24.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <summary>The memory size freed by each low memory kill event.</summary>
-</histogram>
-
-<histogram name="ArcRuntime.LowMemoryKiller.TimeDelta" units="ms"
-    expires_after="2016-03-27">
-  <obsolete>
-    Renamed to Arc.LowMemoryKiller.TimeDelta on 2016/03/24.
-  </obsolete>
-  <owner>elijahtaylor@google.com</owner>
-  <summary>The elapsed time to last low memory kill event.</summary>
-</histogram>
-
-<histogram name="Ash.Accelerators.Deprecated.LockScreen"
-    enum="DeprecatedAcceleratorUsage" expires_after="2020-06-28">
-  <obsolete>
-    Removed Jan 2020 for R82.
-  </obsolete>
-  <owner>zentaro@chromium.org</owner>
-  <owner>cros-peripherals@chromium.org</owner>
-  <summary>
-    The lock screen action has two accelerators: - Ctrl+Shift+L which is
-    deprecated. - Search+L which is new. This histogram shows the number of
-    times each accelerator (deprecated and new) is used.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Accelerators.Deprecated.NextIME"
-    enum="DeprecatedAcceleratorUsage" expires_after="2017-01-30">
-  <obsolete>
-    Removed 01/2017 for Issue 672905.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The switch to the next IME action has two accelerators: - Shift+Alt which is
-    deprecated. - Ctrl+Shift+Space which is new. This histogram shows the number
-    of times each accelerator (deprecated and new) is used.
-  </summary>
-</histogram>
-
-<histogram name="Ash.ActiveTouchPoints" units="units"
-    expires_after="2017-03-03">
-  <obsolete>
-    Removed 02/2017 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Number of active touch-points when a new touch-point is added.
-  </summary>
-</histogram>
-
-<histogram name="Ash.AppList.TimeBetweenTaskSwitches" units="seconds"
-    expires_after="2016-10-04">
-  <obsolete>
-    Removed 10/2016 for Issue 616581.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The amount of time between selecting an item from the Ash app list. Not
-    recorded on the first time an item is selected from the app list after
-    startup.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Ash.ContextualNudge" units="units"
-    expires_after="M83">
-  <obsolete>
-    Removed from code as of 04/2020.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AshContextualNudgesNames" -->
-
-  <owner>yulunwu@chromium.org</owner>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Tracks usage of the contextual nudge for the user gesture education.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Desks.DesksCount" units="units" expires_after="M85">
-  <obsolete>
-    Removed 03/2020, and replaced by Ash.Desks.DesksCount2. This was broken as
-    it did report desks count during the creation of the first-ever created desk
-    after boot.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    Emitted when there's a change in the virtual desks count whether due to desk
-    creation or removal. Specifies the number of available desks.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Desks.NewDesk" enum="DesksCreationRemovalSource"
-    expires_after="M85">
-  <obsolete>
-    Removed 03/2020, and replaced by Ash.Desks.NewDesk2. This was broken as it
-    did report the creation of the first-ever created default desk after boot as
-    being created by the new-desk button.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    Emitted when a virtual desk is created to specify the source of this action,
-    i.e. whether from the new-desk button, keyboard shortcut.
-  </summary>
-</histogram>
-
-<histogram name="Ash.DisplayColorManager.IccFileFound" enum="Boolean"
-    expires_after="2017-10-25">
-  <obsolete>
-    Removed 10/2017, replaced by Ash.DisplayColorManager.IccFileDownloaded
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <owner>dcastagna@chromium.org</owner>
-  <summary>
-    This boolean keeps track if a request for an ICC for a specific product id
-    has been successful or not.
-  </summary>
-</histogram>
-
-<histogram name="Ash.GestureCreated" enum="UIEventType"
-    expires_after="2014-08-28">
-  <obsolete>
-    Removed 08/2014 in Issue 352654, and replaced by Event.GestureCreated.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    The gesture-events recognized and dispatched by the browser gesture
-    recognizer.
-  </summary>
-</histogram>
-
-<histogram name="Ash.GestureTarget" enum="AshGestureActionType"
-    expires_after="2020-07-06">
-  <obsolete>
-    Removed on 01/2020, no longer useful.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    The gesture-events recognized and dispatched for UI components owned by Ash.
-    For browser gestures, see Event.Touch.GestureType.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Login.Lock.NumPasswordAttempts.UntilFailure" units="count"
-    expires_after="2020-05-27">
-  <obsolete>
-    Removed 27/05/2020, the histogram has been revised as we do not count pod
-    switching anymore and the metric was not recorded on shutdown. New
-    histogram: Ash.Login.Lock.NbPasswordAttempts.UntilFailure
-  </obsolete>
-  <owner>kerrnel@google.com</owner>
-  <summary>
-    The number of incorrect password entered in ChromeOS login/lock screen until
-    the user gives up (switch pods or user sign out the current session or
-    shutdown the device).
-  </summary>
-</histogram>
-
-<histogram name="Ash.Login.Lock.NumPasswordAttempts.UntilSuccess" units="count"
-    expires_after="2020-05-27">
-  <obsolete>
-    Removed 27/05/2020, the histogram has been revised as we did not count
-    successful authentification on login screen and successful authentification
-    on lock screen wasn't recorded due to a bug. New histogram:
-    Ash.Login.Lock.NbPasswordAttempts.UntilSuccess
-  </obsolete>
-  <owner>kerrnel@google.com</owner>
-  <summary>
-    The number of incorrect password entered in ChromeOS login/lock screen until
-    a successful attempt.
-  </summary>
-</histogram>
-
-<histogram name="Ash.ProcessCreationToFirstPresent" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 05/2019; no longer need to track this.
-  </obsolete>
-  <owner>sky@chromium.org</owner>
-  <summary>
-    The delta between when chrome main starts to when the Chrome OS system UI
-    (ash) is visible to the user (specifically the first time pixels are lit up
-    on the primary display showing the Chrome OS system UI).
-  </summary>
-</histogram>
-
-<histogram name="Ash.StationaryTouchDuration" units="seconds"
-    expires_after="2017-03-03">
-  <obsolete>
-    Removed 02/2017 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>The duration of mostly stationary long-duration touches.</summary>
-</histogram>
-
-<histogram name="Ash.Tab.TimeBetweenSwitchToExistingTabUserActions"
-    units="seconds" expires_after="2016-10-04">
-  <obsolete>
-    Removed 10/2016 for Issue 616581.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The number of seconds between tab switches triggered by a user gesture (e.g.
-    Ctrl+T, Ctrl+1, tapping or clicking the tab strip, etc).
-  </summary>
-</histogram>
-
-<histogram name="Ash.TouchDuration" units="ms" expires_after="2013-12-12">
-  <obsolete>
-    Removed 12/2013 in r239809, and replaced by Ash.TouchDuration2.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <summary>The duration of a touch-sequence.</summary>
-</histogram>
-
-<histogram name="Ash.TouchDuration2" units="ms" expires_after="2014-08-28">
-  <obsolete>
-    Removed 08/2014 in Issue 352654, and replaced by Event.TouchDuration.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>The duration of a touch-sequence.</summary>
-</histogram>
-
-<histogram name="Ash.TouchMaxDistance" units="pixels"
-    expires_after="2014-08-28">
-  <obsolete>
-    Removed 08/2014 in Issue 352654, and replaced by Event.TouchMaxDistance.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    The maximum euclidean distance in dips which a touch point has travelled
-    away from its starting point. Only measured for single finger gestures.
-  </summary>
-</histogram>
-
-<histogram name="Ash.TouchMoveInterval" units="ms" expires_after="2017-03-03">
-  <obsolete>
-    Removed 02/2017 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>The interval between touch-move events.</summary>
-</histogram>
-
-<histogram name="Ash.TouchPositionX" units="pixels" expires_after="2018-07-13">
-  <obsolete>
-    Removed 07/2018 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <summary>The position of the touch-events along the X axis.</summary>
-</histogram>
-
-<histogram name="Ash.TouchPositionY" units="pixels" expires_after="2018-07-13">
-  <obsolete>
-    Removed 07/2018 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <summary>The position of the touch-events along the Y axis.</summary>
-</histogram>
-
-<histogram name="Ash.TouchRadius" units="pixels" expires_after="2018-07-13">
-  <obsolete>
-    Removed 07/2018 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <summary>The radius of a touch event.</summary>
-</histogram>
-
-<histogram name="Ash.TouchStartBurst" units="units" expires_after="2017-03-03">
-  <obsolete>
-    Removed 02/2017 due to lack of usage.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    The number of rapid touch-starts that happened within a short interval.
-    Logged once for each such burst group.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.Apps" enum="WallpaperApps"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed as of 2/2018. Currently there is only one type of Wallpaper App.
-  </obsolete>
-  <owner>xdai@chromium.org</owner>
-  <summary>
-    The Wallpaper App that the user is using right now on Chrome OS. It's the
-    app that is used when the user right clicks on desktop and selects &quot;Set
-    wallpaper&quot; or when the user selects &quot;Set wallpaper&quot; from
-    chrome://settings page. This is recorded at user login.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.ColorExtraction.Durations" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 8/2018.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The time taken to extract colors from wallpapers. Recorded each time the
-    wallpaper image changes. It may contain multiple colors extracted.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.ColorExtraction.UserDelay" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 8/2018.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The time taken to extract colors from 'expensive' wallpapers. Recorded each
-    time the wallpaper image changes and the color extraction is expected to be
-    expensive, e.g. image size &gt; 100 pixels. This includes time spent
-    switching threads. It may contain multiple colors extracted.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.ColorExtractionResult" enum="BooleanSuccess"
-    expires_after="2017-06-22">
-  <obsolete>
-    Removed as of 6/2017.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    Tracks the success rate for wallpaper color extraction. Recorded each time
-    the wallpaper image changes.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.DefaultIndex" units="units"
-    expires_after="2014-08-08">
-  <obsolete>
-    Removed as of 11/2012. Use of indices has been removed.
-  </obsolete>
-  <owner>kuscher@google.com</owner>
-  <summary>
-    The wallpaper index if one of the default wallpapers has been selected.
-    Recorded at user login. Currently only for the old wallpaper picker UI.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.TimeSpentExtractingColors" units="ms"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed as of 04/2017 in favor of Ash.Wallpaper.ColorExtraction.Durations
-    and Ash.Wallpaper.ColorExtraction.UserDelay.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The time taken to extract colors from wallpapers. Recorded each time the
-    wallpaper image changes. NOTE, this measure also included the time spent
-    jumping between threads, thus it was deprecated in favor of
-    Ash.Wallpaper.ColorExtraction.Durations.
-  </summary>
-</histogram>
-
-<histogram name="Ash.Wallpaper.TimeSpentResizing" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 8/2018.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The time taken to resize wallpapers. Recorded once each time the wallpaper
-    changes (e.g. initial wallpaper loading at boot, switching user avatar at
-    login screen, switching between logged in users, user selects new wallpaper,
-    etc).
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowCycleController.CycleTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 07/2019.
-  </obsolete>
-  <owner>wutao@chromium.org</owner>
-  <owner>tbuckley@google.com</owner>
-  <summary>
-    The amount of time the Alt key is held after pressing Alt+Tab to begin
-    cycling through windows.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowCycleController.SelectionDepth" units="items"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 07/2019.
-  </obsolete>
-  <owner>wutao@chromium.org</owner>
-  <owner>tbuckley@google.com</owner>
-  <summary>
-    When a window is selected after pressing Alt+Tab, records that window's
-    position in the global MRU ordering. 1 represents the most-recently used
-    window, 2 represents the next most-recently used window, and so on. Recorded
-    when Alt+Tab cycling stops, i.e., when Alt key is released.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowCycleView.AnimationSmoothness.HighLight" units="%"
-    expires_after="2020-03-22">
-  <obsolete>
-    Removed 01/2020 in Issue 989794 since we are now using focus rings instead
-    of a highlight. The focus rings have no animations.
-  </obsolete>
-  <owner>yjliu@chromium.org</owner>
-  <owner>chromeos-wmp@google.com</owner>
-  <summary>
-    Relative smoothness of showing window animation when the highlight moves to
-    the next window in the window cycle view when alt + tab is pressed. 100%
-    represents ideally smooth 60 frames per second. 50% represents when only 30
-    frames per second is achieved during the animations. 0% should not happen.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowSelector.AnimationSmoothness.Close" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 03/2019 in favor of Ash.Overview.AnimationSmoothness.Close.Clamshell
-    and Ash.Overview.AnimationSmoothness.Close.Tablet
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Relative smoothness of animations when closing a window in overview mode.
-    100% represents ideally smooth 60 frames per second.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowSelector.AnimationSmoothness.Enter" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 03/2019 in favor of Ash.Overview.AnimationSmoothness.Enter.Clamshell
-    and Ash.Overview.AnimationSmoothness.Enter.Tablet
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Relative smoothness of animations when entering overview mode. 100%
-    represents ideally smooth 60 frames per second.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowSelector.AnimationSmoothness.Exit" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 03/2019 in favor of
-    Ash.Overview.AnimationSmoothness.Exit.ClamshellMode and
-    Ash.Overview.AnimationSmoothness.Exit.TabletMode
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Relative smoothness of animations when exiting overview mode. 100%
-    represents ideally smooth 60 frames per second.
-  </summary>
-</histogram>
-
-<histogram name="Ash.WindowSelector.CycleTime" units="ms"
-    expires_after="2014-06-12">
-  <obsolete>
-    Removed as of 06/2014. No longer relevant since alt-tab switching was
-    separated from WindowSelector.
-  </obsolete>
-  <owner>flackr@chromium.org</owner>
-  <owner>kuscher@google.com</owner>
-  <summary>
-    The amount of time the Alt key is held after pressing Alt+Tab to begin
-    cycling through windows.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ContainerView.Resize.AnimationSmoothness" units="%"
-    expires_after="2020-03-22">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>wutao@chromium.org</owner>
-  <summary>
-    Relative animation smoothness of resizing assistant container window. 100%
-    represents ideally smooth 60 frames per second. 50% represents when only 30
-    frames per second is achieved during the animations. 0% should not happen.
-    This metric is recorded when the container window resizing is finished.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.CardClick"
-    enum="BooleanClicked" expires_after="2020-11-15">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a click on a proactive suggestions card by the user. This histogram
-    is recorded for every click event while derivative metrics are recorded for
-    splicing by category, index, and veId only when those respective attributes
-    are known.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.CardClick.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-11-15">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for a proactive suggestions card that was clicked
-    by the user.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.CardClick.ByIndex"
-    units="index" expires_after="2020-11-15">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records the index for a proactive suggestions card within its list that was
-    clicked by the user.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.CardClick.ByVeId"
-    enum="ProactiveSuggestionsVeId" expires_after="2020-11-15">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records the VE ID for a proactive suggestions card that was clicked by the
-    user.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.FirstShowAttempt"
-    enum="ProactiveSuggestionsShowAttempt" expires_after="2020-11-01">
-  <obsolete>
-    Removed 11/2018 because a need was discovered for a non-boolean value.
-    Superseded by Accessibility.Android.AnimationsEnabled2.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records an attempt to show a proactive suggestion to the user for the first
-    time.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Assistant.ProactiveSuggestions.FirstShowAttempt.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AssistantProactiveSuggestionsShowAttemptByCategory" -->
-
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for an attempt to show a proactive suggestion to
-    the user for the first time.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.FirstShowResult"
-    enum="ProactiveSuggestionsShowResult" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a result of having shown a proactive suggestion to the user for the
-    first time.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Assistant.ProactiveSuggestions.FirstShowResult.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AssistantProactiveSuggestionsShowResultByCategory" -->
-
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user for the first time.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.RequestResult"
-    enum="ProactiveSuggestionsRequestResult" expires_after="2020-11-01">
-  <obsolete>
-    Removed 11/2018 because a need was discovered for a non-boolean value.
-    Superseded by Accessibility.Android.AnimationsEnabled2.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a result for a proactive suggestions server request.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.RequestResult.Error"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for a proactive suggestions server request that
-    resulted in error.
-  </summary>
-</histogram>
-
-<histogram
-    name="Assistant.ProactiveSuggestions.RequestResult.SuccessWithContent"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for a proactive suggestions server request that
-    resulted in a successful response containing content.
-  </summary>
-</histogram>
-
-<histogram
-    name="Assistant.ProactiveSuggestions.RequestResult.SuccessWithoutContent"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for a proactive suggestions server request that
-    resulted in a successful response that did not contain content.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ReshowAttempt"
-    enum="ProactiveSuggestionsShowAttempt" expires_after="2020-11-15">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records an attempt to reshow a proactive suggestion to the user that has
-    already been seen.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Assistant.ProactiveSuggestions.ReshowAttempt.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AssistantProactiveSuggestionsShowAttemptByCategory" -->
-
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for an attempt to reshow a proactive suggestion
-    to the user that has already been seen.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ReshowResult"
-    enum="ProactiveSuggestionsShowResult" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a result of having reshown a proactive suggestion to the user that
-    has already been seen.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Assistant.ProactiveSuggestions.ReshowResult.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-       name="AssistantProactiveSuggestionsShowResultByCategory" -->
-
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having reshown a proactive suggestion to the
-    user that has already been seen.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowAttempt"
-    enum="ProactiveSuggestionsShowAttempt" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by Assistant.ProactiveSuggestions.FirstShowAttempt and
-    Assistant.ProactiveSuggestions.ReshowAttempt.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records an attempt to show a proactive suggestion to the user.
-  </summary>
-</histogram>
-
-<histogram
-    name="Assistant.ProactiveSuggestions.ShowAttempt.AbortedByDuplicateSuppression"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowAttempt.AbortedByDuplicateSuppression.ByCategory
-    and
-    Assistant.ProactiveSuggestions.ReshowAttempt.AbortedByDuplicateSupression.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for an attempt to show a proactive suggestion to
-    the user that was aborted due to duplicate suppression.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowAttempt.Success"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowAttempt.Success.ByCategory and
-    Assistant.ProactiveSuggestions.ReshowAttempt.Success.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for an attempt to show a proactive suggestion to
-    the user that was successful.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowResult"
-    enum="ProactiveSuggestionsShowResult" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by Assistant.ProactiveSuggestions.FirstShowResult and
-    Assistant.ProactiveSuggestions.ReshowResult.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a result of having shown a proactive suggestion to the user.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowResult.Click"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowResult.Click.ByCategory and
-    Assistant.ProactiveSuggestions.ReshowResult.Click.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user that resulted in a click.
-  </summary>
-</histogram>
-
-<histogram
-    name="Assistant.ProactiveSuggestions.ShowResult.CloseByContextChange"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowResult.CloseByContextChange.ByCategory.
-    and
-    Assistant.ProactiveSuggestions.ReshowResult.CloseByContextChange.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user that resulted in being closed due to a change in context.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowResult.CloseByTimeout"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowResult.CloseByTimeout.ByCategory and
-    Assistant.ProactiveSuggestions.ReshowResult.CloseByTimeout.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user that resulted in being closed due to timeout.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowResult.CloseByUser"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowResult.CloseByUser.ByCategory and
-    Assistant.ProactiveSuggestions.ReshowResult.CloseByUser.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user that resulted in being closed by the user.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ShowResult.Teleport"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-08-30">
-  <obsolete>
-    Replaced in M80 by
-    Assistant.ProactiveSuggestions.FirstShowResult.Teleport.ByCategory and
-    Assistant.ProactiveSuggestions.ReshowResult.Teleport.ByCategory.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for having shown a proactive suggestion to the
-    user that resulted in teleportation directly to a single result.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ViewImpression"
-    enum="BooleanShown" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records an impression of a proactive suggestions view seen by the user. This
-    histogram is recorded for every impression event while derivative metrics
-    are recorded for splicing by category and veId only when those respective
-    attributes are known. Note that this histogram is primarily used with
-    Assistant.ProactiveSuggestions.CardClick to give an idea of CTR.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ViewImpression.ByCategory"
-    enum="ProactiveSuggestionsCategory" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records a content category for a proactive suggestions view that was seen by
-    the user. Note that this histogram is primarily used with
-    Assistant.ProactiveSuggestions.CardClick.ByCategory to give an idea of CTR.
-  </summary>
-</histogram>
-
-<histogram name="Assistant.ProactiveSuggestions.ViewImpression.ByVeId"
-    enum="ProactiveSuggestionsVeId" expires_after="2020-11-01">
-  <obsolete>
-    Associated with an experimental feature which was removed in M85.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>dmblack@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    Records the VE ID for a proactive suggestions view that was seen by the
-    user. Note that this histogram is primarily used with
-    Assistant.ProactiveSuggestions.CardClick.ByVeId to give an idea of CTR.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.AttemptCountFail" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of DnsAttempts before DnsTransaction completes with failure.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.AttemptCountSuccess" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of DnsAttempts before DnsTransaction completes successfully.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ConfigParseResult" enum="BooleanSuccess"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Whether DnsConfig was parsed successfully.</summary>
-</histogram>
-
-<histogram name="AsyncDNS.DNSChangerDetected" enum="BooleanSuccess"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Whether the first valid DnsConfig included a rogue nameserver.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.DnsClientDisabledReason" enum="NetErrorCodes"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned by DnsTask if a subsequent ProcTask
-    succeeded, at the end of a streak of failures after which the DnsClient was
-    disabled.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.DnsClientEnabled" enum="BooleanSuccess"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    TRUE counts the events when a valid DnsConfig is received and used to enable
-    DnsClient, while FALSE counts the events when DnsClient is disabled after a
-    series of successful fallbacks from DnsTask to ProcTask.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.FallbackFail" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time spent by ProcTask in failing fallback resolutions.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.FallbackSuccess" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time spent by ProcTask in successful fallback resolutions.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.HaveDnsConfig" enum="BooleanSuccess"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Whether there was a valid DNS configuration at the start of a job which
-    eventually completed successfully.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.HostsSize" units="bytes" expires_after="M82">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The size of the HOSTS file observed before each attempt to parse it.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime_HIGHEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient). Includes only Jobs which had
-    priority HIGHEST when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime_IDLE" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient). Includes only Jobs which had
-    priority IDLE when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime_LOW" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient). Includes only Jobs which had
-    priority LOW when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime_LOWEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient). Includes only Jobs which had
-    priority LOWEST when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTime_MEDIUM" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (using DnsClient). Includes only Jobs which had
-    priority MEDIUM when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange_HIGHEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient). Includes only Jobs which had priority HIGHEST
-    when started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange_IDLE" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient). Includes only Jobs which had priority IDLE when
-    started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange_LOW" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient). Includes only Jobs which had priority LOW when
-    started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange_LOWEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient). Includes only Jobs which had priority LOWEST when
-    started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.JobQueueTimeAfterChange_MEDIUM" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (using DnsClient). Includes only Jobs which had priority MEDIUM when
-    started.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.NameServersType" enum="AsyncDNSNameServersType"
-    expires_after="2016-04-07">
-  <obsolete>
-    Removed as of 4/2016.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Type of nameservers in the DNS config, recorded each time the config is read
-    by the DNSConfigService.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ParseToAddressList" enum="AsyncDNSParseResult"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Counts of results of parsing addresses out of DNS responses in successful
-    DnsTransactions.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.PrefDefaultSource" enum="AsyncDNSPrefDefaultSource"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The source of the async DNS preference's default. Logged at startup, when
-    the IO thread is created.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.PrefSource" enum="AsyncDNSPrefSource"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The source of the async DNS preference's value. Logged at startup, when the
-    IO thread is created.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.Rcode" enum="AsyncDNSRcode"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    The DNS response rcode
-    (https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6).
-    Logged when a DnsTransaction finishes an attempt at a DNS record lookup. It
-    may make multiple attempts - the rcode of each attempt will be logged. No
-    logging will occur for attempts that do not obtain a response from a DNS
-    server.
-
-    Only DNS record lookups performed by the internal DNS resolver
-    (&quot;AsyncDNS&quot;) will have their rcode logged. Lookups performed by
-    the system resolver will not have their rcode logged.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveError" enum="NetErrorCodes"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskError.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned by DnsTask if a subsequent ProcTask
-    succeeded.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveFail" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsTask in resolutions that failed. Excludes time
-    spent in the subsequent fallback.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveStatus" enum="AsyncDNSResolveStatus"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Counts of the overall results of using asynchronous DNS in HostResolverImpl.
-    This only includes jobs started with valid DNS configuration and excludes
-    synchronous resolutions (as IP literals, from cache, and from HOSTS).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveSuccess" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsTask in resolutions that succeeded.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveSuccess_FAMILY_IPV4" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as AsyncDNS.ResolveSuccess, but limited to pure IPv4 lookups.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveSuccess_FAMILY_IPV6" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as AsyncDNS.ResolveSuccess, but limited to pure IPv6 lookups.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ResolveSuccess_FAMILY_UNSPEC" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.DnsTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as AsyncDNS.ResolveSuccess, but limited to IPv4/IPv6 lookups.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerFailureIndex" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Index in DnsConfig of the failing server, recorded at the time of failure.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerFailuresAfterNetworkChange" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of server failures after network change before first success in the
-    DnsSession. Recorded at the time of first success.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerFailuresAfterSuccess" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of server failures after success until the end of the session. Server
-    has reported success at some point during the session. Recorded at the end
-    of the DnsSession.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerFailuresBeforeSuccess" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of server failures before success. This is NOT the first success in
-    the DnsSession. Recorded at the time of success.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerFailuresWithoutSuccess" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Count of server failures without success until the end of the session.
-    Server has never reported success during the DnsSession. Recorded at the end
-    of the DnsSession.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.ServerIsGood" enum="BooleanSuccess"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The current server is &quot;good&quot; and does not have to be skipped.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.SortFailure" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in failing calls to AddressSorter in dual-stack
-    resolutions using DnsTask.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.SortSuccess" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in successful calls to AddressSorter in dual-stack
-    resolutions using DnsTask.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.SuffixSearchDone" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The number of names from the search name list consumed during a successful
-    transaction (QTYPE A only).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.SuffixSearchRemain" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The number of names left on the search name list at the end of a successful
-    transaction (QTYPE A only).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.SuffixSearchStart" units="units"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The number of names on the search name list at the start of a transaction
-    (QTYPE A only).
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TCPAttemptFail" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsTCPAttempt in failed attempts. Excludes
-    timeouts.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TCPAttemptSuccess" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsTCPAttempt in successful attempts.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutErrorHistogram" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Difference between RTT and timeout calculated using Histogram algorithm.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutErrorHistogramUnder" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Difference between timeout calculated using Histogram algorithm and RTT.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutErrorJacobson" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Difference between RTT and timeout calculated using Jacobson algorithm.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutErrorJacobsonUnder" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Difference between timeout calculated using Jacobson algorithm and RTT.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutSpentHistogram" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time that would be spent waiting for lost request using
-    Histogram algorithm.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TimeoutSpentJacobson" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time that would be spent waiting for lost request using Jacobson
-    algorithm.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TotalTime" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.TotalTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Excludes speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TotalTime_speculative" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.TotalTime_speculative.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Speculative requests only.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TransactionFailure" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in failing DnsTransactions. This includes server
-    failures, timeouts and NXDOMAIN results.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TransactionSuccess" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in successful DnsTransactions. This includes all
-    NOERROR answers, even if they indicate the name has no addresses or they
-    cannot be parsed.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TransactionSuccess_A" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Same as AsyncDNS.TransactionSuccess but limited to A query type.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TransactionSuccess_AAAA" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Same as AsyncDNS.TransactionSuccess but limited to AAAA query type.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.TTL" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    TTL of the resolved addresses, as in the response received from the server.
-    For results served from local cache, the TTL is from the original response.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.UDPAttemptFail" units="ms" expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsUDPAttempt in failed attempts. Excludes
-    timeouts.
-  </summary>
-</histogram>
-
-<histogram name="AsyncDNS.UDPAttemptSuccess" units="ms"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed as of 12/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsUDPAttempt in successful attempts. Includes
-    responses arriving after timeout, if multiple attempts are allowed.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.Bubble" enum="AutocheckoutBubble"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the frequency of user interactions with the Autocheckout bubble,
-    which prompts users to invoke Autocheckout on supported websites.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.BuyFlow" enum="AutocheckoutBuyFlow"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the frequency of final states reached in Autocheckout buy flow.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.DismissalState"
-    enum="AutofillDialogDismissalState" expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The state of the Autocheckout dialog when it was dismissed.</summary>
-</histogram>
-
-<histogram name="Autocheckout.FlowDuration" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user submitted the Autocheckout
-    dialog and when the Autocheckout flow, or filling process, concluded.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.FlowDuration.Failed" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user submitted the Autocheckout
-    dialog and when the Autocheckout flow concluded, in cases where the flow
-    failed.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.FlowDuration.Succeeded" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user submitted the Autocheckout
-    dialog and when the Autocheckout flow concluded, in cases where the flow
-    succeeded.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.InitialUserState"
-    enum="AutofillDialogInitialUserState" expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The initial state of a user that's interacting with a freshly shown
-    Autocheckout dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.PopupInDialog" enum="AutofillDialogPopupEvent"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    User interactions with the Autofill popup shown while filling an
-    Autocheckout dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.Security" enum="AutofillDialogSecurity"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the frequency of security warnings and errors in the Autocheckout
-    dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.UiDuration" units="ms" expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the duration for which an Autocheckout dialog was shown.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.UiDuration.Cancel" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the duration for which an Autocheckout dialog was shown, in cases
-    where the user ended up canceling out of the dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.UiDuration.Submit" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the duration for which an Autocheckout dialog was shown, in cases
-    where the user ended up accepting the dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.UiEvents" enum="AutofillDialogUiEvents"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures how users are interacting with the Autocheckout dialog UI.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.UiLatencyToShow" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the duration of time it takes for the Autocheckout UI to be
-    actionable by the user after it is shown.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.WalletErrors" enum="WalletErrors"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the frequency of errors in communicating with the Google Online
-    Wallet server.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.WalletRequiredActions"
-    enum="WalletRequiredActions" expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the frequency of required user actions returned by the Google
-    Online Wallet server.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.WhitelistDownloadDuration" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures time taken to download the Autocheckout whitelist file.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.WhitelistDownloadDuration.Failed" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures time taken to download the Autocheckout whitelist file in case the
-    download was failed.
-  </summary>
-</histogram>
-
-<histogram name="Autocheckout.WhitelistDownloadDuration.Succeeded" units="ms"
-    expires_after="2013-08-30">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures time taken to download the Autocheckout whitelist file in case the
-    download was succeeded.
-  </summary>
-</histogram>
-
-<histogram name="AutodetectEncoding.Attempted" enum="BooleanAttempted"
-    expires_after="2016-02-04">
-  <obsolete>
-    Removed as of 2/2016.
-  </obsolete>
-  <owner>jinsukkim@chromium.org</owner>
-  <summary>
-    Whether the text encoding auto detection logic was attempted for a web page.
-    The logic is triggered when the parser fails to find the encoding method
-    from other signals such as http header, meta tag, BOM, etc.
-
-    If the logic successfully detects a new encoding method which is different
-    from the default one, the result is reported through
-    AutodetectEncoding.Detected with the encoding method (see below). Otherwise
-    - i.e. detection logic somehow fails to work for the page or the detected
-    one is same as the default - no result is reported.
-  </summary>
-</histogram>
-
-<histogram name="AutodetectEncoding.Detected" enum="EncodingMethod"
-    expires_after="2016-02-04">
-  <obsolete>
-    Removed as of 2/2016.
-  </obsolete>
-  <owner>jinsukkim@chromium.org</owner>
-  <summary>
-    The number of web pages whose encoding method is found by the auto detection
-    logic. Grouped by the encoding methods defined in EncodingMethod.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.AddressBook.AccessSkipped" enum="BooleanSkipped"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    Whether an attempt to access the Mac AddressBook was skipped because doing
-    so would incorrectly cause the appearance of the permissions dialog. This
-    happens when Chrome auto-update changes the binary on disk before the first
-    AddressBook access attempt.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.AddressBookAvailable" enum="BooleanAvailable"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    Whether the Mac AddressBook was available on an attempt to read data from
-    it.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.AddressBookAvailableOnFirstAttempt"
-    enum="BooleanAvailable" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    Whether the Mac AddressBook was available on the *first* attempt to read
-    data from it. This is only recorded once per Chrome profile.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.AutomaticProfileCreation" enum="BooleanCreated"
-    expires_after="2015-10-15">
-  <obsolete>
-    Removed as of 6/2015, replaced by Autofill.ProfileActionOnFormSubmitted.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Whether a new Autofill profile was created automatically. In the
-    &quot;false&quot; case, an existing profile was used (and possibly updated).
-  </summary>
-</histogram>
-
-<histogram name="Autofill.CanLogUKM" enum="BooleanEnabled" expires_after="M78">
-  <obsolete>
-    Removed after M78.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>siyua@chromium.org</owner>
-  <owner>payments-autofill-team@google.com</owner>
-  <summary>
-    Tracks whether UKM logging is enabled for the page in the Autofill.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.CardUploadDecision" enum="AutofillCardUploadDecision"
-    expires_after="2016-02-08">
-  <obsolete>
-    Removed as of 2/2016, replaced by Autofill.CardUploadDecisionMetric.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Whether upload was offered upon detecting a form submission with credit card
-    data and a reason if it wasn't.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.CardUploadDecisionExpanded"
-    enum="AutofillCardUploadDecisionExpanded" expires_after="2017-05-02">
-  <obsolete>
-    Removed as of 5/2017, replaced by Autofill.CardUploadDecisionMetric.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Whether upload was offered upon detecting a form submission with credit card
-    data and a detailed reason if it wasn't.
-  </summary>
-</histogram>
-
-<histogram name="AutoFill.CCInfoBarAccepted" units="units"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 3/2011, replaced by Autofill.CreditCardInfoBar.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The Autofill credit card info bar was accepted.</summary>
-</histogram>
-
-<histogram name="AutoFill.CCInfoBarDenied" units="units"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 3/2011, replaced by Autofill.CreditCardInfoBar.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The Autofill credit card info bar was denied.</summary>
-</histogram>
-
-<histogram name="Autofill.CreditCardUploadDisallowedForNetwork"
-    enum="CreditCardUploadDisallowedNetwork" expires_after="M75">
-  <obsolete>
-    Was replaced by the AutofillDoNotUploadSaveUnsupportedCards feature in M75.
-    Removed 2019/07.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <summary>
-    When a credit card is not allowed to be offered upload save due to its
-    network, logs what the card network was.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.DaysSincePreviousUseAtSubmission.Profile"
-    units="days" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Logs the number of days between most recent use without modification and the
-    penultimate use of the profile when submitting a credit card form.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.FormDynamicity" enum="AutofillFormDynamicity"
-    expires_after="M86">
-  <obsolete>
-    Removed 06/2020 after sufficient data was collected, to cleanup the code
-    base.
-  </obsolete>
-  <owner>schwering@google.com</owner>
-  <owner>chrome-autofill@google.com</owner>
-  <summary>
-    Records how forms change dynamically: whether the form signature changed, a
-    field's signature changed, or a field was newly created. The reference
-    period starts when Autofill parses the form for the first time, and ends
-    when a navigation is committed or the frame is destructed.
-
-    Every form is observed for dynamic changes from the time it was first parsed
-    by Autofill until either a navigation has been committed or the frame is
-    destructed or the form's observation had to be flushed prematurely (the form
-    observations are managed in an LRU cache of maximum size 32, with least
-    recently parsed forms being discarded first). At the end of the lifetime, a
-    three-bit number is sent: the lowest bit is 1 iff a field was changed during
-    the form's lifetime (its signature changed); the second bit is 1 iff a field
-    was added (its renderer ID is new to the form); the highest bit is 1 iff the
-    form was changed (its signature changed).
-  </summary>
-</histogram>
-
-<histogram name="Autofill.FormEvents.CreditCard.BankNameDisplayed"
-    enum="BankNameDisplayedFormEvent" expires_after="M80">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>siyua@chromium.org</owner>
-  <summary>
-    Autofill form events for credit card forms. These are recorded when the user
-    interacts with a form requesting a credit card, a dropdown of suggestions is
-    shown and at least one of the suggestions has a bank name. Form events are
-    logged at most once per page load.
-
-    These metrics are used to measure the impact of the bank name experiment.
-    They are used to calculate the CTR of the autofill UI with bank names
-    available. Not all credit cards will have bank names even if we launch the
-    experiment. With these metrics we can run the experiment on 2 groups. For
-    one group, we will show bank names if available. For the other, we won't
-    shown.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.HasModifiedProfile.CreditCardFormSubmission"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Whether user modified an address profile shortly before submitting a credit
-    card form.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.IcuCollatorCreationSuccess" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed after M77.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    Tracks whether Autofill was able to create the ICU collator successfully.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.KeyboardAccessoryButtonsIOS_ScreenReaderOff"
-    enum="AutofillKeyboardAccessoryButtonsIOS" expires_after="M77">
-  <obsolete>
-    Obsolete after M77.
-  </obsolete>
-  <owner>mahmadi@chromium.org</owner>
-  <summary>
-    [iOS] Measures the frequency of button presses on the iOS Autofill keyboard
-    accessory view when VoiceOver is off.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.KeyboardAccessoryButtonsIOS_ScreenReaderOn"
-    enum="AutofillKeyboardAccessoryButtonsIOS" expires_after="M85">
-  <obsolete>
-    Obsolete after M85.
-  </obsolete>
-  <owner>mahmadi@chromium.org</owner>
-  <summary>
-    [iOS] Measures the frequency of button presses on the iOS Autofill keyboard
-    accessory view when VoiceOver is on.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook" enum="AutofillMacAddressBook"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    When Chrome tries to access the user's Address Book, OSX presents a blocking
-    dialog which disrupts the user experience. A new Chrome feature has been
-    introduced wherein Chrome only shows this blocking dialog if the user
-    explicitly asked Chrome to access the user's Address Book. If a form's field
-    looks like it might support Autofill suggestions from the user's Address
-    Book and there are no other suggestions, Chrome shows an Autofill entry that
-    prompts the user to give Chrome access to the user's Address Book. This
-    histogram tracks the frequency that this Autofill entry is presented, and
-    the frequency that this Autofill entry is selected.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.AcceptedSuggestionIsFromAddressBook"
-    enum="BooleanFromAddressBook" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    This metric is emitted each time the user accepts an Autofill suggestion. It
-    records whether the result is from the Address Book.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.AccessTime" units="ms"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The amount of time spent accessing the OSX Address Book the first time after
-    Chrome was launched. If this time is larger than ~100ms, this it is likely
-    that the user was shown a blocking, modal dialog.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.ContainedMeCard"
-    enum="BooleanContainedMeCard" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    After a Chrome is given access to the Mac Address Book, whether the Address
-    Book contained a Me card.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.MeCard.HadAddress"
-    enum="BooleanHadAddress" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    When Chrome is given access to the Me Card of the Address Book, whether the
-    card has an address that contained a street number and either a city or zip
-    code.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.MeCard.HadEmail"
-    enum="BooleanHadEmail" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    When Chrome is given access to the Me Card of the Address Book, whether the
-    card has an email.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.MeCard.HadName" enum="BooleanHadName"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    When Chrome is given access to the Me Card of the Address Book, whether the
-    card has a name.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.MeCard.HadPhoneNumber"
-    enum="BooleanHadPhoneNumber" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    When Chrome is given access to the Me Card of the Address Book, whether the
-    card has a phone number.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MacAddressBook.NumShowsBeforeSelected" units="units"
-    expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The number of times that the access Address Book prompt has been shown when
-    the user selects the prompt.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.MaskedCardComparisonNetworksMatch"
-    enum="BooleanEqual" expires_after="2020-01-15">
-  <obsolete>
-    Removed as of 12/2019.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>payments-autofill-team@google.com</owner>
-  <summary>
-    This metric is recorded when two credit cards are compared using
-    CreditCard::HasSameNumberAs and one of the cards in the comparison is
-    masked. The metric measures whether there is a match between a masked card's
-    network and the network of the card with which the masked card is being
-    compared.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.PasswordFormQueryVolume"
-    enum="PasswordFormQueryVolume" expires_after="2015-11-10">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>gcasto@chromium.org</owner>
-  <summary>
-    Tracks the increased load on the Autofill server if the restriction on
-    querying for password forms with fewer than 3 fields were omitted.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.PayloadCompressionRatio" units="%"
-    expires_after="2016-01-28">
-  <obsolete>
-    Removed as of 1/2016, autofill payload compression was removed.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    Compression ratio of the query and upload payload that are sent to the
-    Autofill server. The payload is compressed using gzip.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.PaymentsCustomerDataBillingIdIsValid" enum="Boolean"
-    expires_after="2019-08-07">
-  <obsolete>
-    Removed as of 9/2018, replaced by
-    Autofill.PaymentsCustomerDataBillingIdStatus.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    When PaymentsCustomerData is used to send a request to Google Payments, we
-    log the validity state of the billing customer ID.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.PaymentsCustomerDataBillingIdStatus"
-    enum="BillingIdStatus" expires_after="2019-09-07">
-  <obsolete>
-    Removed as of August 2019.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    When PaymentsCustomerData is used to send a request to Google Payments, we
-    log the validity state of the billing customer ID.
-  </summary>
-</histogram>
-
-<histogram name="AutoFill.ProfileCount" units="units"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 3/2011, replaced by Autofill.StoredProfileCount.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of Autofill address profiles a user has.</summary>
-</histogram>
-
-<histogram name="AutoFill.Quality" enum="AutofillQuality"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 3/2011, replaced by Autofill.Quality.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The quality of the AutoFill implementation.</summary>
-</histogram>
-
-<histogram name="Autofill.Quality" enum="AutofillQuality"
-    expires_after="2014-03-04">
-  <obsolete>
-    Removed as of 2/2014 (M35), replaced by Autofill.UserHappiness.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>The quality of the Autofill implementation.</summary>
-</histogram>
-
-<histogram name="Autofill.Quality.HeuristicType" enum="AutofillTypeQuality"
-    expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.Aggregate.Heuristic.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>The quality of Autofill's heuristic field type detection.</summary>
-</histogram>
-
-<histogram name="Autofill.Quality.HeuristicType.ByFieldType"
-    enum="AutofillTypeQualityByFieldType" expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.ByFieldType.Heuristic.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The quality of Autofill's heuristic field type detection, broken down by the
-    specific field type. Fields with multiple possible types (based on the
-    stored Autofill data) are logged as having ambiguous type.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Quality.PredictedType" enum="AutofillTypeQuality"
-    expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.Aggregate.Overall.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>The overall quality of the Autofill field type predictions.</summary>
-</histogram>
-
-<histogram name="Autofill.Quality.PredictedType.ByFieldType"
-    enum="AutofillTypeQualityByFieldType" expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.ByFieldType.Overall.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The overall quality of the Autofill field type predictions, broken down by
-    the specific field type. Fields with multiple possible types (based on the
-    stored Autofill data) are logged as having ambiguous type.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Quality.ServerType" enum="AutofillTypeQuality"
-    expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.Aggregate.Server.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>The quality of the Autofill server's field type detection.</summary>
-</histogram>
-
-<histogram name="Autofill.Quality.ServerType.ByFieldType"
-    enum="AutofillTypeQualityByFieldType" expires_after="2017-06-02">
-  <obsolete>
-    Removed as of 6/2017, replaced by
-    Autofill.FieldPredictionQuality.ByFieldType.Server.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The quality of the Autofill server's field type detection, broken down by
-    the specific field type. Fields with multiple possible types (based on the
-    stored Autofill data) are logged as having ambiguous type.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Query.HttpResponseCode" enum="HttpResponseCode"
-    expires_after="2018-08-21">
-  <obsolete>
-    Removed as of 8/2018, replaced by Autofill.Query.HttpResponseOrErrorCode.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>The HTTP response code returned on a query.</summary>
-</histogram>
-
-<histogram name="Autofill.ResetFullServerCards.NumberOfCardsReset"
-    units="Cards" expires_after="M77">
-  <obsolete>
-    Were added as part of Issue 851295; no longer necessary. Removed 2019/07.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>The number of full server cards that were reset.</summary>
-</histogram>
-
-<histogram name="Autofill.ResetFullServerCards.NumberOfCardsReset.DryRun"
-    units="Cards" expires_after="2018-10-19">
-  <obsolete>
-    Removed as of 10/2018 (M72).
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>The number of full server cards that would have been reset.</summary>
-</histogram>
-
-<histogram
-    name="Autofill.ResetFullServerCards.SyncServiceNotActiveOnInitialized"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Were added as part of Issue 851295; no longer necessary. Removed 2019/07.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Records whether a sync service in a not active state is passed to Autofill
-    OnSyncServiceInitialized.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.ResetFullServerCards.SyncServiceNullOnInitialized"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Were added as part of Issue 851295; no longer necessary. Removed 2019/07.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Records whether a null sync service is passed to Autofill
-    OnSyncServiceInitialized.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.ResetFullServerCards.SyncServiceStatusOnStateChanged"
-    enum="SyncUploadState" expires_after="2019-04-23">
-  <obsolete>
-    Removed as of 04/2019 (M76). No longer necessary since we don't mask data
-    for USS Autofill Wallet anymore.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Records the sync service state when OnStateChanged is called.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.SaveCardReachedPersonalDataManager" enum="Boolean"
-    expires_after="2019-06-30">
-  <obsolete>
-    Removed as of 05/2019. Was a temporary metric to gauge the impact of
-    http://crbug.com/892299.
-  </obsolete>
-  <owner>jsaul@google.com</owner>
-  <owner>sebsg@chromium.org</owner>
-  <owner>mahmadi@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="AutofillCreditCardType" -->
-
-  <summary>
-    Records if the PersonalDataManager was notified to attempt saving of a card.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.SaveCardWithFirstAndLastNameComplete" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    Deprecated after M85.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="AutofillCreditCardType" -->
-
-  <summary>
-    Records if a card was saved from a form that had split name fields.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.SaveCardWithFirstAndLastNameOffered" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    Deprecated after M85.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="AutofillCreditCardType" -->
-
-  <summary>
-    Records if a card was offered to be saved from a form that had split name
-    fields.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.ServerExperimentId" enum="AutofillExperimentId"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 6/2011, replaced by Autofill.ServerExperimentId.Query.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The experiment ID received in response to an Autofill server query.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.ServerExperimentId.Query" enum="AutofillExperimentId"
-    expires_after="2014-03-04">
-  <obsolete>
-    Removed as of 2/2014 (M35).
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The experiment ID received in response to an Autofill server query.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.ServerExperimentId.Upload"
-    enum="AutofillExperimentId" expires_after="2014-03-04">
-  <obsolete>
-    Removed as of 2/2014 (M35).
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The experiment ID received at the time of an Autofill upload.
-  </summary>
-</histogram>
-
-<histogram name="AutoFill.ServerQueryResponse" enum="AutofillQueryResult"
-    expires_after="2013-03-30">
-  <obsolete>
-    Removed as of 3/2011, replaced by Autofill.ServerQueryResponse.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The usefulness of AutoFill server information.</summary>
-</histogram>
-
-<histogram name="Autofill.StoredLocalCreditCardCount" units="cards"
-    expires_after="M77">
-  <obsolete>
-    Removed in favor of Autofill.StoredCreditCardCount.Local.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    The number of local credit cards a user has stored, measured at Chrome
-    profile launch time.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.StoredServerCreditCardCount" units="cards"
-    expires_after="M77">
-  <obsolete>
-    Removed in favor of Autofill.StoredCreditCardCount.Server.
-  </obsolete>
-  <owner>mathp@chromium.org</owner>
-  <summary>
-    The number of server credit cards a user has stored, measured at Chrome
-    profile launch time.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Unknown.BackoffDelay" units="ms"
-    expires_after="2019-01-04">
-  <obsolete>
-    Removed as of 01/2019, as it never occurs.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>
-    The delay of a network request for which the download manager seems to have
-    lost the request type due to exponential backoff. This should never be
-    logged.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Unknown.FailingPayloadSize" units="bytes"
-    expires_after="2019-01-04">
-  <obsolete>
-    Removed as of 01/2019, as it never occurs.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>
-    The number of bytes that were sent in a request for which the download
-    manager seems to have lost the request type. This should never be logged.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Unknown.HttpResponseCode" enum="HttpResponseCode"
-    expires_after="2018-08-21">
-  <obsolete>
-    Removed as of 8/2018, replaced by Autofill.Unknown.HttpResponseOrErrorCode.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>
-    The HTTP response code returned on a request for which the download manager
-    seems to have lost the request type. This should never be logged.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Unknown.HttpResponseOrErrorCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2019-01-04">
-  <obsolete>
-    Removed as of 01/2019, as it never occurs.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>
-    The http response code or net error code returned on a request for which the
-    download manager seems to have lost the request type. This should never be
-    logged.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Unknown.RequestDuration" units="ms"
-    expires_after="2019-01-04">
-  <obsolete>
-    Removed as of 01/2019, as it never occurs.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>
-    The duration of a network request for which the download manager seems to
-    have lost the request type. This should never be logged.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.Upload.HttpResponseCode" enum="HttpResponseCode"
-    expires_after="2018-08-21">
-  <obsolete>
-    Removed as of 8/2018, replaced by Autofill.Upload.HttpResponseOrErrorCode.
-  </obsolete>
-  <owner>rogerm@chromium.org</owner>
-  <summary>The HTTP response code returned on an upload.</summary>
-</histogram>
-
-<histogram base="true" name="Autofill.WalletAddresses" units="addresses"
-    expires_after="2019-06-01">
-  <obsolete>
-    Removed as of 12/2018, replaced by Autofill.WalletAddresses2.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
-
-  <owner>sebsg@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    The number of Wallet addresses that were added to Chrome or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server. Recorded only if both the user had previously non-empty
-    data set locally and the new data set is also non-empty (to rule out initial
-    sync and wiping out data). This metric has a flaw that the Directory
-    implementation (unlike the USS implementation) records the metric also on
-    every startup and the resulting histograms are hard to compare.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Autofill.WalletAddresses2" units="addresses"
-    expires_after="2019-06-01">
-  <obsolete>
-    Removed as of 05/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
-
-  <owner>sebsg@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    The number of Wallet addresses that were added to Chrome or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server. Recorded only if both the user had previously non-empty
-    data set locally and the new data set is also non-empty (to rule out initial
-    sync and wiping out data).
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletAddressesAdded" units="addresses"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletAddresses.Added.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of Wallet addresses that were added to Chrome via Sync. Recorded
-    when receiving an AUTOFILL_WALLET_DATA update from the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletAddressesAddedOrRemoved" units="addresses"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletAddresses.AddedOrRemoved.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The total number of Wallet addresses that were added to or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletAddressesRemoved" units="addresses"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletAddresses.Removed.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of Wallet addresses that were removed from Chrome via Sync.
-    Recorded when receiving an AUTOFILL_WALLET_DATA update from the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Autofill.WalletCards" units="credit cards"
-    expires_after="2019-06-01">
-  <obsolete>
-    Removed as of 12/2018, replaced by Autofill.WalletCards2.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
-
-  <owner>sebsg@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    The number of Wallet credit cards that were added to Chrome or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server. Recorded only if both the user had previously non-empty
-    data set locally and the new data set is also non-empty (to rule out initial
-    sync and wiping out data). This metric has a flaw that the Directory
-    implementation (unlike the USS implementation) records the metric also on
-    every startup and the resulting histograms are hard to compare.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Autofill.WalletCards2" units="credit cards"
-    expires_after="2019-06-01">
-  <obsolete>
-    Removed as of 05/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
-
-  <owner>sebsg@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    The number of Wallet credit cards that were added to Chrome or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server. Recorded only if both the user had previously non-empty
-    data set locally and the new data set is also non-empty (to rule out initial
-    sync and wiping out data).
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletCardsAdded" units="credit cards"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletCards.Added.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of Wallet credit cards that were added to Chrome via Sync.
-    Recorded when receiving an AUTOFILL_WALLET_DATA update from the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletCardsAddedOrRemoved" units="credit cards"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletCards.AddedOrRemoved.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The total number of Wallet credit cards that were added to or removed from
-    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
-    the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletCardsRemoved" units="credit cards"
-    expires_after="2018-11-29">
-  <obsolete>
-    Removed as of 11/2018, replaced by Autofill.WalletCards.Removed.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of Wallet credit cards that were removed from Chrome via Sync.
-    Recorded when receiving an AUTOFILL_WALLET_DATA update from the Sync server.
-
-    Can probably be removed around Q1 2019, after project Dice has rolled out.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletUseDate.Address" units="ms" expires_after="M76">
-  <obsolete>
-    Removed as of 04/2019 because most measurements were in the last bucket,
-    replaced by Autofill.WalletUseDateInMinutes.Address.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The time since last use date of a wallet address, as known by sync. Recorded
-    for each wallet address on startup.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletUseDate.Card" units="ms" expires_after="M76">
-  <obsolete>
-    Removed as of 04/2019 because most measurements were in the last bucket,
-    replaced by Autofill.WalletUseDateInMinutes.Card.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The time since last use date of a wallet card, as known by sync. Recorded
-    for each wallet card on startup.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletUseDateInMinutes.Address" units="minutes"
-    expires_after="M76">
-  <obsolete>
-    Removed as of 2019-08.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The time since last use date of a wallet address, as known by sync. Recorded
-    for each wallet address on startup.
-  </summary>
-</histogram>
-
-<histogram name="Autofill.WalletUseDateInMinutes.Card" units="minutes"
-    expires_after="M76">
-  <obsolete>
-    Removed as of 2019-08.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The time since last use date of a wallet card, as known by sync. Recorded
-    for each wallet card on startup.
-  </summary>
-</histogram>
-
-<histogram name="AutogeneratedTheme.ColorGenerationTime" units="ms"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 12/2019. No longer tracked.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    Time that it takes to calculate all the theme properties for autogenerated
-    themes in ms.
-  </summary>
-</histogram>
-
-<histogram name="AutoScreenBrightness.UserAdjustment"
-    enum="AutoScreenBrightnessUserAdjustment" expires_after="2018-11-22">
-  <obsolete>
-    Removed as of 11/2018. It has been replaced by DailyUserAdjustment.
-  </obsolete>
-  <owner>jiameng@chromium.org</owner>
-  <summary>Type of user manual screen brightness adjustment.</summary>
-</histogram>
-
-<histogram base="true" name="Availability.Prober.TimeUntilFailure" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Replaced by Availability.Prober.TimeUntilFailure2.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the amount of time spent working on a single probe attempt to get to
-    a failed state. Recorded every time a probe fails.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Availability.Prober.TimeUntilSuccess" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Replaced by Availability.Prober.TimeUntilSuccess2.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the amount of time spent working on a single probe attempt to get to
-    a successful state. Recorded every time a probe succeeds.
-  </summary>
-</histogram>
-
-<histogram name="BackForwardCache.SameSite.ActionAfterPagehide"
-    enum="BackForwardCacheActionAfterPagehide" expires_after="M88">
-  <obsolete>
-    Deprecated 09/2020 in favor of ActionAfterPagehide2 which excludes actions
-    taken when the unload event is in progress.
-  </obsolete>
-  <owner>rakina@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <owner>bfcache-dev@chromium.org</owner>
-  <summary>
-    Records occurences of certain actions triggered by script running on a page
-    after the pagehide event gets dispatched in the page, which might be
-    possible if we dispatch the pagehide event without unloading/freezing the
-    page (only happens when we're doing a same-site navigation and we did a
-    proactive BrowsingInstance swap but we're reusing the old page's process).
-    Note: we will only track actions that might affect the user after we've
-    navigated away from the old page, such as modifications to storage,
-    navigations, or sending/receiving postMessage.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundFetch.RegistrationCreatedError"
-    enum="BackgroundFetchError" expires_after="2018-11-05">
-  <obsolete>
-    Removed 10/2018 since DB tasks record this more accurately.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Records the error after the Background Fetch Data Manager creates a
-    registration.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundFetch.RegistrationDeletedError"
-    enum="BackgroundFetchError" expires_after="2018-11-05">
-  <obsolete>
-    Removed 10/2018 since DB tasks record this more accurately.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Records the error after the Background Fetch Data Manager deletes a
-    registration.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundFetch.SchedulerFinishedError"
-    enum="BackgroundFetchError" expires_after="2018-11-05">
-  <obsolete>
-    Removed 10/2018 since DB tasks record this more accurately.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Records the error after the Background Fetch Data Manager marks a
-    registration for deletion. This is called when the Scheduler Controller is
-    finished.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundSync.Event.OneShotResult" enum="BooleanSuccess"
-    expires_after="2015-10-20">
-  <obsolete>
-    As of 10/2015 this has been replaced by
-    BackgroundSync.Event.OneShotResultPattern.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <summary>Records whether a one-shot sync event succeeded or failed.</summary>
-</histogram>
-
-<histogram name="BackgroundSync.Event.PeriodicResult" enum="BooleanSuccess"
-    expires_after="2015-10-20">
-  <obsolete>
-    As of 10/2015 this has been replaced by
-    BackgroundSync.Event.PeriodicResultPattern.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <summary>Records whether a periodic sync event succeeded or failed.</summary>
-</histogram>
-
-<histogram name="BackgroundSync.LaunchTask.CancelSuccess" enum="BooleanSuccess"
-    expires_after="M86">
-  <obsolete>
-    Removed as of 09/2019.
-  </obsolete>
-  <owner>nator@chromium.org</owner>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Records the result of attempting to cancel a future browser launch using the
-    GCM Network Manager on Android.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundSync.LaunchTask.ScheduleSuccess"
-    enum="BooleanSuccess" expires_after="M86">
-  <obsolete>
-    Removed as of 09/2019.
-  </obsolete>
-  <owner>nator@chromium.org</owner>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Records the result of attempting to schedule a future browser launch using
-    the GCM Network Manager on Android.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundSync.OptionConditionsChanged"
-    enum="BooleanOptionConditionsChanged" expires_after="M75">
-  <obsolete>
-    Removed as of 03/2019.
-  </obsolete>
-  <owner>rayankans@chromium.org</owner>
-  <summary>
-    Whether the Background Sync dispatch conditions changed between scheduling
-    the operation and dispatching the event. This is collected right before the
-    event is dispatched.
-  </summary>
-</histogram>
-
-<histogram name="BackgroundSync.Unregistration.OneShot"
-    enum="BackgroundSyncStatus" expires_after="2016-02-26">
-  <obsolete>
-    Stopped recording as of 2/2016.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <summary>
-    Records the result of attempting to unregister a one-shot sync.
-  </summary>
-</histogram>
-
-<histogram name="Badging.AppBadgeUpdate.Win.Result" enum="Hresult"
-    expires_after="M85">
-  <obsolete>
-    Removed 6/3/2020. No longer needed.
-  </obsolete>
-  <owner>phillis@chromium.org</owner>
-  <owner>cmumford@chromium.org</owner>
-  <summary>The result from updating the app badge on Windows.</summary>
-</histogram>
-
-<histogram name="Blacklist.Blocked" enum="DllHash" expires_after="2019-07-25">
-  <obsolete>
-    The blacklist is deprecated in favor of third-party DLL blocking.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <summary>
-    Records the name hashes of all the dlls that are blocked from the browser
-    process.
-  </summary>
-</histogram>
-
-<histogram name="Blacklist.PatchedInRenderer" enum="BooleanHit"
-    expires_after="2015-07-09">
-  <obsolete>
-    Removed at 2015 July.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <summary>
-    Counts the number of times a renderer process is started with the browser
-    blacklist patch. This should never be hit.
-  </summary>
-</histogram>
-
-<histogram name="Blacklist.RetryAttempts.Success" units="units"
-    expires_after="2019-07-26">
-  <obsolete>
-    Replaced by ChromeElf.Beacon.RetryAttemptsBeforeSuccess after the old
-    blacklist was deprecated.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <owner>proberge@google.com</owner>
-  <summary>
-    Records the number of attempts needed before the blacklist is properly set
-    up. This is logged immediately after a successful setup.
-  </summary>
-</histogram>
-
-<histogram name="Blacklist.Setup" enum="BlacklistSetup"
-    expires_after="2019-07-26">
-  <obsolete>
-    Replaced by ChromeElf.Beacon.SetupStatus after the old blacklist was
-    deprecated.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <summary>
-    Records the successes and failures when running the browser blacklist setup
-    code. Used to determine if the blacklist is working as intended during
-    startup (since the blacklist runs before crash reporting is set up). This
-    only occurs on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeMainLocalWindowProxy"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed as of 04/2019 with the removal of field trial experiment settings.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing LocalWindowProxy during a page loading in main
-    windows.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeMainRemoteWindowProxy"
-    units="microseconds" expires_after="2019-04-16">
-  <obsolete>
-    Removed as of 04/2019 with the removal of field trial experiment settings.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing RemoteWindowProxy during a page loading in main
-    frame of OOPIF.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeMainWindowProxy" units="microseconds"
-    expires_after="2017-03-26">
-  <obsolete>
-    Removed as of 03/2017. This metric was split into two metrics depending if
-    it figures time for local window proxies or remote ones.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing WindowProxy during a page loading in main windows.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeNonMainLocalWindowProxy"
-    units="microseconds" expires_after="2019-04-16">
-  <obsolete>
-    Removed as of 04/2019 with the removal of field trial experiment settings.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing LocalWindowProxy during a page loading in non-main
-    windows, e.g. iframe.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeNonMainRemoteWindowProxy"
-    units="microseconds" expires_after="2019-04-16">
-  <obsolete>
-    Removed as of 04/2019 with the removal of field trial experiment settings.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing RemoteWindowProxy during a page loading in OOPIF.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeNonMainWindowProxy"
-    units="microseconds" expires_after="2017-03-26">
-  <obsolete>
-    Removed as of 03/2017. This metric was split into two metrics depending if
-    it figures time for local window proxies or remote ones.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>
-    Time spent initializing WindowProxy during a page loading in non-main
-    windows, e.g. iframe.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Binding.InitializeWindowProxy" units="microseconds"
-    expires_after="2016-11-01">
-  <obsolete>
-    Removed as of 10/2016. This metric was split into two metrics depending if
-    it figures time for main windows.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <summary>Time spent initializing WindowProxy during a page loading.</summary>
-</histogram>
-
-<histogram name="Blink.BudgetAPI.QueryBudget" units="budget"
-    expires_after="2018-08-20">
-  <obsolete>
-    Removed as of 08/2018 (M70) with the removal of the Budget API.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Whenever the Budget API framework receives a query for the current budget,
-    this records the total budget available to the origin, which is an internal
-    Chrome value for the amount of background processing an origin can do
-    without visibly alerting the user. Scale for the budget is 0 to 100. Care
-    should be taken when drawing conclusions from this metric, as budget is
-    based on both engagement and usage, so could vary significantly based on
-    user behaviour and origin.
-  </summary>
-</histogram>
-
-<histogram name="Blink.BudgetAPI.Reserve" enum="BooleanSuccess"
-    expires_after="2018-08-20">
-  <obsolete>
-    Removed as of 08/2018 (M70) with the removal of the Budget API.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Whenever the Budget API framework receives a request to reserve budget for a
-    future background operation, this records whether the reserve request
-    succeeded or not.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.2DLayerBridgeIsDeferred" enum="BooleanSuccess"
-    expires_after="2021-01-31">
-  <obsolete>
-    Removed as the deferral path is always used now - 11/2019.
-  </obsolete>
-  <owner>aaronhk@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Records if a 2D Layer Bridge is using deferred rendering when it is
-    destroyed. Emitted in Canvas2DLayerBridge::~Canvas2DLayerBridge.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.DrawImage" units="microseconds"
-    expires_after="2021-01-31">
-  <obsolete>
-    Replaced with Blink.Canvas.DrawImage.Duration in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent on 2D canvas drawImage API call.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.GetImageData" units="microseconds"
-    expires_after="2018-10-26">
-  <obsolete>
-    Replaced with Blink.Canvas.GetImageDataScaledDuration in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent on 2D canvas getImageData API call.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.GPUAccelerated2DCanvasDisableDeferralReason"
-    enum="CanvasGPUAccelerated2DCanvasDisableDeferralReason"
-    expires_after="2019-12-31">
-  <obsolete>
-    Canvas doesn't disable deferral anymore since July 2019.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>aaronhk@chromium.org</owner>
-  <summary>
-    The reasons why a GPU accelerated canvas stopped deferring its rendering
-    operations.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.OffscreenCommitTimer" units="microseconds"
-    expires_after="2018-11-01">
-  <obsolete>
-    Removed in 10/2018. Offscreen Canvas no longer needs commits.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>xidachen@chromium.org</owner>
-  <summary>
-    Wall clock durations of OffscreenCanvas.commit() calls.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.PutImageData" units="microseconds"
-    expires_after="2018-10-26">
-  <obsolete>
-    Replaced with Blink.Canvas.PutImageDataScaledDuration in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent on 2D canvas putImageData API call.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.ToBlob.IdleEncodeDuration" units="microseconds"
-    expires_after="2017-12-04">
-  <obsolete>
-    Replaced with Blink.Canvas.ToBlob.CompleteEncodingDelay in 2017/12.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>aaronhk@chromium.org</owner>
-  <summary>
-    This metric measures the total time spent on encoding all the rows of an
-    image (jpeg or png), excluding the waiting time of next idle periods. This
-    is part of a canvas.toBlob API call. Encoding occurs during one or more idle
-    periods on the main thread.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.ToBlobDuration" units="microseconds"
-    expires_after="2018-10-30">
-  <obsolete>
-    Replaced with Blink.Canvas.ToBlob.ScaledDuration in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>aaronhk@chromium.org</owner>
-  <summary>
-    Time spent on 2D canvas toBlob API call.
-
-    In addition, metric values from OffscreenCanvas.convertToBlob API call are
-    also gathered into this histogram, because the logic flow is exactly the
-    same as canvas.toBlob. It's worth to note that the values can come from idle
-    tasks on either main or worker thread.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Canvas.ToDataURL" units="microseconds"
-    expires_after="2018-11-02">
-  <obsolete>
-    Replaced with Blink.Canvas.ToDataURLScaledDuration in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent on 2D canvas toDataURL API call.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.CheckerableImageCount" enum="CheckerableImageType"
-    expires_after="2018-05-08">
-  <obsolete>
-    Removed on 2018-05-04.
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    The number of images which could have been checkered (async decoded) for a
-    performance gain, split by the DOM element type on which they were used.
-    This is recorded each time an image for an element created by the page is
-    loaded, either from the network or the local cache. The browser heuristics
-    define an image to be checkerable if it is expected to have a long decode
-    duration. Since these images may be on the rendering critical path, decoding
-    them asychronously from painting other content can provide better
-    performance be reducing overall content checkerboarding.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorGamut.Source" enum="Gamut" expires_after="M80">
-  <obsolete>
-    No useful signal. Deprecated 7/2019.
-  </obsolete>
-  <owner>brianosman@chromium.org</owner>
-  <owner>mcasas@google.com</owner>
-  <owner>ccameron@chromium.org</owner>
-  <summary>Gamut properties of image color space.</summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.ExtractedRawData"
-    enum="ColorSpaceExtractedRawDataResult" expires_after="2017-02-28">
-  <obsolete>
-    Merged into Blink.ColorSpace.Destination.ICCResult on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Whether or not the output color space ICC profile was able to produce raw
-    transfer function tables.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.ICCResult"
-    enum="ICCProfileAnalyzeResult" expires_after="2020-03-08">
-  <obsolete>
-    No useful signal. Deprecated 2020-03-03.
-  </obsolete>
-  <owner>brianosman@chromium.org</owner>
-  <owner>mcasas@google.com</owner>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The result of analyzing the destiation color space's ICC profile.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.LinearFitError" units="units"
-    expires_after="2017-02-28">
-  <obsolete>
-    Linear fit found to be always inaccurate on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The L-infinity error (in 8-bit values) of the numerical approximation of
-    table-based ICC profile transfer functions, when falling back to a linear
-    approximation.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.Matrix"
-    enum="ColorSpaceMatrixResult" expires_after="2017-02-28">
-  <obsolete>
-    Merged into Blink.ColorSpace.Destination.ICCResult on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Whether or not to-XYZD50 matrix was extracted from the output color space
-    ICC profile.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.NonlinearFitConverged"
-    enum="ColorSpaceNonlinearFitConverged" expires_after="2018-05-17">
-  <obsolete>
-    Nonlinear fit code moved to skcms on 2018-04-25.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Whether or not the nonlinear least squares fit of the table-based ICC
-    profile transfer function for a single channel converged.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.NonlinearFitError" units="units"
-    expires_after="2018-05-17">
-  <obsolete>
-    Nonlinear fit code moved to skcms on 2018-04-25.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The L-infinity error (in 8-bit values) of the numerical approximation of
-    table-based ICC profile transfer functions for a single channel, when the
-    nonlinear approximation converged.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.Numerical"
-    enum="ColorSpaceNumericalResult" expires_after="2017-02-28">
-  <obsolete>
-    Merged into Blink.ColorSpace.Destination.ICCResult on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Whether or not the output color space ICC profile has a numerical transfer
-    function.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.OneMinusTMax" units="units"
-    expires_after="2017-02-28">
-  <obsolete>
-    TMax found to almost always be 1 on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    One minus the maximum value of table-based ICC profile transfer functions as
-    an 8-bit fixed-point value. This histogram is temporary, to see if we can
-    bake in the assumption that it will almost always be 255.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Destination.TMin" units="units"
-    expires_after="2017-02-28">
-  <obsolete>
-    TMin found to almost always be 0 on 2017-02-28.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The minimum value of table-based ICC profile transfer functions as an 8-bit
-    fixed-point value. This histogram is temporary, to see if we can bake in the
-    assumption that it will almost always be 0.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ColorSpace.Source" enum="Gamma" expires_after="M77">
-  <obsolete>
-    No useful signal. Deprecated 7/2019.
-  </obsolete>
-  <owner>brianosman@chromium.org</owner>
-  <owner>mcasas@google.com</owner>
-  <owner>ccameron@chromium.org</owner>
-  <summary>Gamma properties of image color space.</summary>
-</histogram>
-
-<histogram name="Blink.Compositing.UpdateTime" units="microseconds"
-    expires_after="2021-03-01">
-  <obsolete>
-    Obsolete as of http://crrev.com/794384 and M86.
-  </obsolete>
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating compositing in the Blink document lifecycle. This is the
-    legacy compositing approach. BlinkGenPropertyTrees launches part of the new
-    compositing approach and will use both this and
-    Blink.CompositingCommit.UpdateTime.
-
-    Note: As of M70, this histogram has stopped recording metrics on machines
-    with low-resolution clocks.
-
-    TODO(crbug.com/1100711): This is being replaced soon by CompositingInputs +
-    CompositingAssignments (== Compositing).
-  </summary>
-</histogram>
-
-<histogram name="Blink.CookieJar.SyncCookiesSetTime" units="microseconds"
-    expires_after="2020-01-20">
-  <obsolete>
-    Removed as of 01/20/2020.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    Microseconds per sync IPC call to set cookies.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.CookieJar.SyncCookiesTime" units="microseconds"
-    expires_after="2020-01-20">
-  <obsolete>
-    Removed as of 01/20/2020.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    Microseconds per sync IPC call to fetch cookies.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.CanvasExpanded"
-    enum="BooleanCanvasExpanded" expires_after="2016-11-30">
-  <obsolete>
-    Removed as of 11/29/2016.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@google.com</owner>
-  <summary>
-    The original canvas dimensions were sufficient to determine image size. This
-    is logged once per image header decode, which happens typically twice per
-    image on the page.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.EffectiveDimensionsLocation" units="bytes"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed as of 11/29/2016.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@google.com</owner>
-  <summary>
-    How many bytes of the file were read before an image width and height were
-    determined. This is logged once per image header decode, which happens
-    typically twice per image on the page.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.JpegDensity" units="0.01 bits per pixel"
-    expires_after="2018-08-31">
-  <obsolete>
-    Removed as of 08/23/2018. Replaced by Blink.DecodedImage.JpegDensity.*
-  </obsolete>
-  <owner>deymo@google.com</owner>
-  <owner>compression-dev@google.com</owner>
-  <summary>
-    The compressed image density measured in 0.01 bits per pixel. This is logged
-    once per image load after the whole image is loaded and only for JPEGs with
-    at least 100 pixels on each dimension.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.JpegDensity.1000px"
-    units="0.01 bits per pixel" expires_after="2020-08-10">
-  <obsolete>
-    Removed in M79. Replaced by Blink.DecodedImage.JpegDensity.KiBWeighted.
-  </obsolete>
-  <owner>deymo@google.com</owner>
-  <owner>compression-dev@google.com</owner>
-  <summary>
-    The compressed image density measured in 0.01 bits per pixel. This is logged
-    once per image load after the whole image is loaded and only for JPEGs with
-    at least 1000 pixels on the smallest dimension (width or height).
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.JpegDensity.100px"
-    units="0.01 bits per pixel" expires_after="2020-02-23">
-  <obsolete>
-    Removed in M79. Replaced by Blink.DecodedImage.JpegDensity.KiBWeighted.
-  </obsolete>
-  <owner>deymo@google.com</owner>
-  <owner>compression-dev@google.com</owner>
-  <summary>
-    The compressed image density measured in 0.01 bits per pixel. This is logged
-    once per image load after the whole image is loaded and only for JPEGs with
-    at least 100 pixels on the smallest dimension (width or height) but less
-    than 400 pixels on the smallest dimension.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.JpegDensity.400px"
-    units="0.01 bits per pixel" expires_after="2020-02-23">
-  <obsolete>
-    Removed in M79. Replaced by Blink.DecodedImage.JpegDensity.KiBWeighted.
-  </obsolete>
-  <owner>deymo@google.com</owner>
-  <owner>compression-dev@google.com</owner>
-  <summary>
-    The compressed image density measured in 0.01 bits per pixel. This is logged
-    once per image load after the whole image is loaded and only for JPEGs with
-    at least 400 pixels on the smallest dimension (width or height) but less
-    than 1000 pixels on the smallest dimension.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.XCanvasExpansion" units="pixels"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed as of 11/29/2016.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@google.com</owner>
-  <summary>
-    How much the canvas width needed to be expanded as a result of the first
-    frame's width and x-offset being larger than the initial canvas width. This
-    is logged once per image header decode, which happens typically twice per
-    image on the page.
-  </summary>
-</histogram>
-
-<histogram name="Blink.DecodedImage.YCanvasExpansion" units="pixels"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed as of 11/29/2016.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@google.com</owner>
-  <summary>
-    How much the canvas height needed to be expanded as a result of the first
-    frame's height and y-offset being larger than the initial canvas height.
-    This is logged once per image header decode, which happens typically twice
-    per image on the page.
-  </summary>
-</histogram>
-
-<histogram name="Blink.EventListenerDuration.Resize" units="microseconds"
-    expires_after="2018-01-17">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>bokan@chromium.org</owner>
-  <summary>
-    Time it takes to execute all the `resize` event listeners on a page when a
-    resize event is fired. Tracked only for the main frame.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Fonts.HarfBuzzFaceZeroCopyAccess" enum="BooleanSuccess"
-    expires_after="M88">
-  <obsolete>
-    Removed as of 10/15/2020.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <owner>layout-dev@chromium.org</owner>
-  <summary>
-    Counts success or failure of attempting to access font tables using the zero
-    copy instantiation method in the HarfBuzz integration layer. This value is
-    only recorded on non-Mac platforms. Reported each time a HarfBuzz face
-    object is created.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Gesture.Merged" enum="GestureMergeState"
-    expires_after="M77">
-  <obsolete>
-    UserActivationV2 made UserGestureTokens obselete, so the merge stats is now
-    irrelevant.
-  </obsolete>
-  <owner>jyasskin@chromium.org</owner>
-  <owner>domenic@google.com</owner>
-  <summary>
-    How many times two user gesture tokens were merged by UserGestureIndicator,
-    and whether each token had an active gesture. One of the new token's
-    gestures, if any, is moved to the old token.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.MainFrame.ProxyCommitRatio" units="%"
-    expires_after="2020-11-08">
-  <obsolete>
-    Replaced with separate ImplCompositorCommit and WaitForCommit metrics and
-    removed in M84.
-  </obsolete>
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" -->
-
-  <summary>
-    The percentage of time between a BeginMainFrame and paint results commit in
-    Blink that is used for committing the layer tree to the impl thread.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.MainFrame.StyleAndLayoutRatio" units="%"
-    expires_after="2020-06-21">
-  <obsolete>
-    Replaced with separate Style and Layout metrics and removed in M81.
-  </obsolete>
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" -->
-
-  <summary>
-    The percentage of time between a BeginMainFrame and paint results commit in
-    Blink that is used for computing Style and Layout.
-  </summary>
-</histogram>
-
-<histogram name="Blink.MediaDocument.DownloadButton"
-    enum="MediaDocumentDownloadButtonType" expires_after="2017-08-22">
-  <obsolete>
-    Removed 08/2017 as it is integrated into media controller.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Records how the download button on the MediaDocument is used.
-  </summary>
-</histogram>
-
-<histogram name="Blink.MediaElement.Autoplay" enum="MediaElementAutoPlay"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016 in Issue 666370 with the deprecation of Autoplay experiment.
-  </obsolete>
-  <owner>oysteine@chromium.org</owner>
-  <summary>
-    Records user observation and interaction with Media HTML elements that
-    feature autoplay, either script-controlled or through the attribute.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Paint.IndexedItemPercentage" units="%"
-    expires_after="2020-03-01">
-  <obsolete>
-    Not very useful for identifying performance issues.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Percentage of display items that are put into the index because of
-    out-of-order display item matching. Higher value means lower performance
-    beause of the cost of out-of-order matching and indexing. Recorded when we
-    finish updating paint in the Blink document lifecycle.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Paint.NumDisplayItems" units="count"
-    expires_after="2020-03-01">
-  <obsolete>
-    Not very useful for identifying performance issues.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total number of display items (including cached and repainted) in the
-    painted result. Recorded when we finish updating paint in the Blink document
-    lifecycle.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Paint.NumPaintChunks" units="count"
-    expires_after="2020-03-01">
-  <obsolete>
-    Not very useful for identifying performance issues.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total number of paint chunks in the painted result. Recorded when we finish
-    updating paint in the Blink document lifecycle.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Paint.NumSubsequences" units="count"
-    expires_after="2020-03-01">
-  <obsolete>
-    Not very useful for identifying performance issues.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total number of subsequences (including cached and repainted) in the painted
-    result. Recorded when we finish updating paint in the Blink document
-    lifecycle.
-  </summary>
-</histogram>
-
-<histogram name="Blink.PaintInvalidation.UpdateTime" units="microseconds"
-    expires_after="2018-02-22">
-  <obsolete>
-    SlimmingPaintInvalidation is enabled by default, so this histogram is no
-    longer being logged. Was removed in 02-2018.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating paint invalidation in the Blink document lifecycle. Not
-    available when SlimmingPaintInvalidation or SlimmingPaintV2 is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ProxyCommit.UpdateTime" units="microseconds"
-    expires_after="2020-11-08">
-  <obsolete>
-    Replaced with separate ImplCompositorCommit and WaitForCommit metrics and
-    removed in M84.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
-
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
-
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimeAggregatedSuffixes" -->
-
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent commiting the layer tree to the impl thread in a main frame
-    update.
-
-    Note: This histogram does not record metrics on machines with low-resolution
-    clocks.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ResourceFetcher.StaleWhileRevalidate"
-    enum="BooleanAttempted" expires_after="2020-01-26">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>Count of resources attempted Stale Revalidation.</summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.DecodedBytes"
-    units="bytes" expires_after="2018-08-06">
-  <obsolete>
-    Removed as of 8/2018.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>toyoshim@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>Count received data size in bytes for each resource.</summary>
-</histogram>
-
-<histogram name="Blink.ResourceLoadScheduler.DecodedBytes.KBPerFrameStatus"
-    enum="RendererSchedulerFrameType2" expires_after="2020-04-30">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total decoded size of resources associated with frames of a particular type.
-    Recorded when a fetch has been completed.
-
-    Each bucket of the histogram cointains the total size of all requests
-    associated with frames with a particular frame status in kilobytes.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.PeakRequests"
-    units="requests" expires_after="M80">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>ksakamoto@chromium.org</owner>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>
-    The largest number of outstanding resource requests issued by a frame until
-    the network 2-quiet (no more than 2 active network requests for 1 seconds).
-  </summary>
-</histogram>
-
-<histogram name="Blink.ResourceLoadScheduler.RequestCount"
-    enum="ResourceLoadSchedulerCircumstance" expires_after="2020-04-30">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Count resource request circumstance, e.g. from the main frame vs sub-frames,
-    or in throttled state vs in not-throttled state, on each resource load
-    completion.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ResourceLoadScheduler.ThrottlingStateChangeCount"
-    units="changes" expires_after="M77">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Count how many times the scheduler has changed throttling status from the
-    frame creation until network activity quiets.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.TotalDecodedBytes"
-    units="bytes" expires_after="M80">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>toyoshim@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total received data size in bytes to load resources from the frame creation
-    until network activity quiets.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.TotalRequestCount"
-    units="requests" expires_after="M80">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>toyoshim@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Total number of resource requests completed from the frame creation until
-    network activity quiets.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.TotalTrafficBytes"
-    units="bytes" expires_after="M80">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>toyoshim@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total traffic data in bytes transferred over networks to load resources from
-    the frame creation until network activity quiets.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Blink.ResourceLoadScheduler.TrafficBytes"
-    units="bytes" expires_after="2018-08-06">
-  <obsolete>
-    Removed as of 8/2018.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ResourceLoadScheduler.FrameType" -->
-
-  <owner>toyoshim@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Count traffic data size in bytes transferred over networks to load each
-    resource.
-  </summary>
-</histogram>
-
-<histogram name="Blink.RestoredCachedStyleSheet"
-    enum="RestoredCachedStyleSheet" expires_after="2016-01-20">
-  <obsolete>
-    Removed 01/2016 and replaced by Blink.RestoredCachedStyleSheet2
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    On each link stylesheet tag resolve, record whether a Blink MemoryCached
-    StyleSheetContents was reused.
-  </summary>
-</histogram>
-
-<histogram name="Blink.RestoredCachedStyleSheet2" enum="StyleSheetCacheStatus"
-    expires_after="2017-04-11">
-  <obsolete>
-    Removed 04/2017.
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    On each link stylesheet tag resolve, record which cache Blink hit.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ScriptValueSerializer.DOMWrapperCount" units="objects"
-    expires_after="2016-11-15">
-  <obsolete>
-    Used to justify distribution of serialized data in the wild, but unlikely to
-    be useful to track long-term.
-  </obsolete>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Number of DOM wrappers serialized as part of an object passed to
-    postMessage, IndexedDB, or another API that serializes script values.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ScriptValueSerializer.JSObjectCount" units="objects"
-    expires_after="2016-11-15">
-  <obsolete>
-    Used to justify distribution of serialized data in the wild, but unlikely to
-    be useful to track long-term.
-  </obsolete>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Number of JavaScript objects (other than DOM wrappers) serialized as part of
-    an object passed to postMessage, IndexedDB, or another API that serializes
-    script values.
-  </summary>
-</histogram>
-
-<histogram name="Blink.ScriptValueSerializer.PrimitiveCount" units="values"
-    expires_after="2016-11-15">
-  <obsolete>
-    Used to justify distribution of serialized data in the wild, but unlikely to
-    be useful to track long-term.
-  </obsolete>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Number of primitive values (numbers, strings, etc.) serialized as part of an
-    object passed to postMessage, IndexedDB, or another API that serializes
-    script values.
-  </summary>
-</histogram>
-
-<histogram name="Blink.SharedBuffer.FailedLock" enum="ResourceType"
-    expires_after="M85">
-  <obsolete>
-    Removed 08/2016 since SharedBuffer::unlock() was successfully removed.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    Number of failed SharedBuffer::lock() calls for each resource type.
-    https://crbug.com/603791
-  </summary>
-</histogram>
-
-<histogram name="Blink.SharedBuffer.SuccessfulLock" enum="ResourceType"
-    expires_after="M85">
-  <obsolete>
-    Removed 08/2016 since SharedBuffer::unlock() was successfully removed.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    Number of successful SharedBuffer::lock() calls for each resource type.
-    https://crbug.com/603791
-  </summary>
-</histogram>
-
-<histogram name="Blink.SharedBuffer.Unlock" enum="ResourceType"
-    expires_after="M85">
-  <obsolete>
-    Removed 08/2016 since SharedBuffer::unlock() was successfully removed.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    Number of SharedBuffer::unlock() calls for each resource type.
-    https://crbug.com/603791
-  </summary>
-</histogram>
-
-<histogram name="Blink.Sms.Receive.RequestedTimeout" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 9/2019 since the concept of timeouts have been removed.
-    https://crbug.com/1000376
-  </obsolete>
-  <owner>goto@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <owner>ayui@chromium.org</owner>
-  <summary>
-    Records the timeout value specified when the API is called regardless of
-    whether or not the call actually timed out. The value of 0 indicates that no
-    value was specified.
-  </summary>
-</histogram>
-
-<histogram name="Blink.Sms.Receive.TimeTimeoutExceeded" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 9/2019 since the concept of timeouts have been removed.
-    https://crbug.com/1000376
-  </obsolete>
-  <owner>goto@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <owner>ayui@chromium.org</owner>
-  <summary>
-    Records the duration from when the API is called to when the user gets timed
-    out of the SMS verification flow because no SMS was received within the
-    specified timeout window.
-  </summary>
-</histogram>
-
-<histogram name="Blink.StyleAndLayout.UpdateTime" units="microseconds"
-    expires_after="2020-08-10">
-  <obsolete>
-    Replaced with separate Style and Layout metrics and removed in M81.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
-
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
-
-<!-- Name completed by histogram_suffixes name="BlinkUpdateTimeAggregatedSuffixes" -->
-
-  <owner>schenney@chromium.org</owner>
-  <owner>layout-dev@chromium.org</owner>
-  <summary>
-    Time spent updating style and layout in the Blink document lifecycle.
-
-    Note: As of M70, this histogram has stopped recording metrics on machines
-    with low-resolution clocks.
-  </summary>
-</histogram>
-
-<histogram
-    name="Blink.UseCounter.AnimatedCSSProperties_TestBrowserProcessLogging"
-    enum="MappedCSSProperties" expires_after="2018-06-12">
-  <obsolete>
-    Renamed to Blink.UseCounter.AnimatedCSSProperties in 03/2018, M69. The old
-    blink UseCounter is flawed in OOPIF, so moved to the browser side instead.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Records usage of animated CSS properties used across all frames in a page,
-    either statically or dynamically, from the time the page is initialised to
-    when it is closed or navigated away from. Each property is counted at most
-    once per page view except kTotalPagesMeasuredCSSSampleId which represents a
-    page load (enum value of 1) and is counted exactly once per page view.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.CSSProperties_TestBrowserProcessLogging"
-    enum="MappedCSSProperties" expires_after="2018-06-12">
-  <obsolete>
-    Renamed to Blink.UseCounter.CSSProperties in 03/2018, M69. The old blink
-    UseCounter is flawed in OOPIF, so moved to the browser side instead.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Records usage of CSS properties used across all frames in a page, either
-    statically or dynamically, from the time the page is initialised to when it
-    is closed or navigated away from. Each property is counted at most once per
-    page per view except kTotalPagesMeasuredCSSSampleId which represents a page
-    load (enum value of 1) and is counted exactly once per page view.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.FeaturePolicy.ImageDownscalingRatio"
-    units="%" expires_after="2020-08-16">
-  <obsolete>
-    Feature moved from feature policy to document policy in M82. Histogram and
-    recording code removed for feature policy. Histogram and recording code will
-    be added for document policy.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Logs downscaling ratio in percentage for images enforced by feature policy
-    oversized-images policy going into origin trials in M75. If an image's
-    downscaling ratio is 1, it will be represented as 10 percent, if an image's
-    downscaling ratio is 5, it will be represented as 50 percents. Recorded when
-    oversized-images policy is enforced and the image is about to be painted.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.FeaturePolicy.ImageFormats"
-    enum="FeaturePolicyImageCompressionFormat" expires_after="M80">
-  <obsolete>
-    Feature moved from feature policy to document policy in M82. Histogram and
-    recording code removed for feature policy. Histogram and recording code will
-    be added for document policy.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Counts ImageFileFormats (lossy, lossless, webp animation, others) of images
-    enforced by feature policy unoptimized-images policy going into origin
-    trials in M75. Recorded when images finish decoding the mime type.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.FeaturePolicy.LosslessImageCompression"
-    units="%" expires_after="M80">
-  <obsolete>
-    Feature moved from feature policy to document policy in M82. Histogram and
-    recording code removed for feature policy. Histogram and recording code will
-    be added for document policy.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Logs compression ratio in percentage with 1KB overhead for lossless type
-    images enforced by feature policy unoptimized-lossless-images policy going
-    into origin trials in M75. If an image's compression ratio is 0.1, it will
-    be represented as 1 percent, if an image's compression ratio is 5, it will
-    be represented as 50 percents. Recorded when unoptimized-lossless-images
-    policy is enforced and the image finishes decoding its mime type.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.FeaturePolicy.LossyImageCompression"
-    units="%" expires_after="M80">
-  <obsolete>
-    Feature moved from feature policy to document policy in M82. Histogram and
-    recording code removed for feature policy. Histogram and recording code will
-    be added for document policy.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Logs compression ratio with 1KB overhead for lossy type images enforced by
-    feature policy unoptimized-lossy-images policy going into origin trials in
-    M75. If an image's compression ratio is 0.1, it will be represented as 1
-    percent, if an image's compression ratio is 5, it will be represented as 50
-    percents. Recorded when unoptimized-lossy-images policy is enforced and the
-    image finishes decoding its mime type.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.FeaturePolicy.StrictLosslessImageCompression"
-    units="%" expires_after="M80">
-  <obsolete>
-    Feature moved from feature policy to document policy in M82. Histogram and
-    recording code removed for feature policy. Histogram and recording code will
-    be added for document policy.
-  </obsolete>
-  <owner>iclelland@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Logs compression ratio with 10KB overhead for lossless type images enforced
-    by feature policy unoptimized-lossless-images-strict policy going into
-    origin trials in M75. If an image's compression ratio is 0.1, it will be
-    represented as 1 percent, if an image's compression ratio is 5, it will be
-    represented as 50 percents. Recorded when unoptimized-lossless-images-strict
-    policy is enforced and the image finishes decoding its mime type.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.Features_Legacy" enum="FeatureObserver"
-    expires_after="M81">
-  <obsolete>
-    Replaced by Blink.UseCounter.Features in M67. See crbug.com/849695.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Count of how many page loads use various features. The PageVisits bucket is
-    incremented for each page load, and the other buckets incremented at most
-    once per PageVisit via the blink::UseCounter class.
-
-    This histogram recorded values in the renderer process. With the addition of
-    OOPIF, the counts could be inaccurate due to multiple renderer processes for
-    a page. It was replaced by an implementation that records values in the
-    browser process.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.Features_TestBrowserProcessLogging"
-    enum="FeatureObserver" expires_after="2018-03-13">
-  <obsolete>
-    Renamed to Blink.UseCounter.Features in 03/2018, M67. The old blink
-    UseCounter is flawed in OOPIF, so moved to the browser side (this) instead.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Count of how many page loads use various features across all frames in a
-    page. The PageVisits bucket is incremented for each page load, and the other
-    buckets incremented at most once per PageVisit via the WebCore::UseCounter
-    class. This counter lives in browser process.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.SVGImage.AnimatedCSSProperties"
-    enum="MappedCSSProperties" expires_after="2018-06-19">
-  <obsolete>
-    Removed in 06/2018, M69 since the histogram is not really useful. See
-    https://crbug.com/804645.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Like Blink.UseCounter.AnimatedCSSProperties but specifically for the case of
-    CSS properties used inside of an SVG image.
-
-    Warning: This histogram represents pre-renderer metrics and so is flawed
-    under OOPIF.
-
-    This histogram counts usage of animated CSS properties only. Refer to
-    Blink.UseCounter.SVGImage.CSSProperties for details.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.SVGImage.CSSProperties"
-    enum="MappedCSSProperties" expires_after="2018-06-19">
-  <obsolete>
-    Removed in 06/2018, M69 since the histogram is not really useful. See
-    https://crbug.com/804645.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>feature-control@chromium.org</owner>
-  <summary>
-    Like Blink.UseCounter.CSSProperties but specifically for the case of CSS
-    properties used inside of an SVG image.
-
-    Warning: This histogram represents pre-renderer metrics and so is flawed
-    under OOPIF.
-
-    The 'Total pages measured' bucket is incremented each time a new SVG image
-    is created. Note that the same SVG image can be used across multiple tabs in
-    a single renderer but this counts as a single usage. See
-    http://crbug.com/236262.
-  </summary>
-</histogram>
-
-<histogram name="Blink.UseCounter.SVGImage.Features" enum="FeatureObserver"
-    expires_after="2019-05-15">
-  <obsolete>
-    Removed in 05/2019, M76. Every SVGImage has it's own Page instance and
-    multiple web pages can share the usage of a single SVGImage. Previously
-    Blink.UseCounter.Features was recorded on the Blink side per Page; metrics
-    from SVGImage needed to be recorded in a separate histogram. Now that
-    metrics are recorded on the browser side, feature usage from SVGImage is
-    measured via page load metrics, on Blink.UseCounter.Features, once per page
-    load. This histogram is no longer needed.
-  </obsolete>
-  <summary>
-    Like Blink.UseCounter.Features except specifically for the case of SVG
-    Images.
-
-    Warning: This histogram represents pre-renderer metrics and so is flawed
-    under OOPIF.
-
-    Count of how many SVG images use various features. The PageVisits bucket is
-    incremented each time a new SVG image is created. Note that the same SVG
-    image can be used across multiple tabs in a single renderer but this counts
-    as a single usage. See http://crbug.com/236262.
-  </summary>
-</histogram>
-
-<histogram name="Blink.XHR.setRequestHeader.HeaderValueCategoryInRFC7230"
-    enum="XMLHttpRequestHeaderValueCategoryInRFC7230"
-    expires_after="2017-06-01">
-  <obsolete>
-    Removed 06/2017 in Issues 455099 and 681769 (M61).
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    The count of XMLHttpRequest.setRequestHeader() calls where header values are
-    invalid/valid but affected by normalization/valid in RFC 7230.
-    https://crbug.com/455099.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.AtomicPhaseMarking" units="ms" expires_after="M81">
-  <obsolete>
-    See BlinkGC.TimeForAtomicPhaseMarking.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of finishing marking the transitive closure of objects during the
-    final Blink garbage collection pause. Recorded at the end of each garbage
-    collection.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.CollectGarbage" units="ms" expires_after="2018-06-07">
-  <obsolete>
-    Removed 06/2018. The sample taken here was a mix of marking, sweeping and
-    compaction. Replaced by BlinkGC.AtomicPhaseMarking for the marking phase and
-    BlinkGC.TimeForTotalCollectGarbage for the overal time.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>
-    Duration of time taken to run Heap::collectGarbage(). Recorded at the end of
-    each garbage collection.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.CommittedSize" units="MB" expires_after="2020-02-16">
-  <obsolete>
-    Removed as of 07/2019. Use Memory.Renderer.* and
-    Memory.Experimental.Renderer2.* instead.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>
-    The committed memory size in Blink GC. The value is reported when we see the
-    highest memory usage we've ever seen in the renderer process.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.CompleteSweep" units="ms" expires_after="M81">
-  <obsolete>
-    Removed 07/2019. Replaced by BlinkGC.TimeForCompleteSweep.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>Duration of time taken to run ThreadState::completeSweep().</summary>
-</histogram>
-
-<histogram name="BlinkGC.PerformPendingSweep" units="ms"
-    expires_after="2015-03-30">
-  <obsolete>
-    Removed at 2014 Jan.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>
-    Duration of time taken to run ThreadState::performPendingSweep().
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.SlowIncrementalMarkingFinalize.AtomicPhaseMarking"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of finishing marking the transitive closure of objects during the
-    final Blink garbage collection pause. Only recorded when incremental marking
-    finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.SlowIncrementalMarkingFinalize.EagerSweep" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time taken to run eager sweep finalizers finalizers. Only
-    recorded when incremental marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram
-    name="BlinkGC.SlowIncrementalMarkingFinalize.IncrementalMarkingFinalize"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time for incremental marking finalization. Only recorded when
-    incremental marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.SlowIncrementalMarkingFinalize.InvokePreFinalizers"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time taken to invoke pre finalizers. Only recorded when
-    incremental marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.SlowIncrementalMarkingFinalize.MarkWeakProcessing"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time taken for weak processing. Only recorded when incremental
-    marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram
-    name="BlinkGC.SlowIncrementalMarkingFinalize.VisitCrossThreadPersistents"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time taken to visit cross thread persistents. Only recorded when
-    incremental marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.SlowIncrementalMarkingFinalize.VisitDOMWrappers"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Data gathering finished with the result that slow marking
-    finalization was mostly caused by visiting DOM wrappers or premature
-    finalization.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <owner>oilpan-reviews@chromium.org</owner>
-  <summary>
-    Duration of time taken to visit DOM wrappers. Only recorded when incremental
-    marking finalization took at least 40ms.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.TimeForCoalesce" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019. Coalescing is not used anymore.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Duration of memory coalesce operation in the Blink GC. Reported once per
-    coalesce operation.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.TimeForStoppingThreads" units="ms"
-    expires_after="2017-02-13">
-  <obsolete>
-    As of 02/2017, the code to stop Blink threads was removed.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>
-    Duration of time taken to stop all Blink threads before starting a GC.
-  </summary>
-</histogram>
-
-<histogram name="BlinkGC.TimeForSweepingAllObjects" units="ms"
-    expires_after="M77">
-  <obsolete>
-    As of 07/2019, this metric is replaced by BlinkGC.TimeForSweepingSum.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>Accumulated time taken to sweep all objects.</summary>
-</histogram>
-
-<histogram name="BlinkGC.TimeForThreadLocalWeakProcessing" units="ms"
-    expires_after="2017-02-26">
-  <obsolete>
-    As of 02/2017, the code for thread-local weak processing was removed.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>Duration of time taken to run thread-local weak processing.</summary>
-</histogram>
-
-<histogram name="BloatedRenderer.HandlingInBrowser"
-    enum="BloatedRendererHandlingInBrowser" expires_after="M80">
-  <obsolete>
-    Obsolete as of 05/2019.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    Records how a bloated renderer was handled in the browser process.
-  </summary>
-</histogram>
-
-<histogram name="BloatedRenderer.HandlingInResourceCoordinator"
-    enum="BloatedRendererHandlingInResourceCoordinator" expires_after="M80">
-  <obsolete>
-    Obsolete as of 05/2019.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    Records how a bloated renderer was handled in the resource coordinator
-    service.
-  </summary>
-</histogram>
-
-<histogram name="BloatedRenderer.V8.NearV8HeapLimitHandling"
-    enum="NearV8HeapLimitHandling" expires_after="M80">
-  <obsolete>
-    Obsolete as of 05/2019.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    Records how a bloated V8 heap was handled in the renderer process. It is
-    emitted the first time V8 heap reaches the heap limit and invokes the
-    NearHeapLimitCallback. Subsequent invocations of the callback are ignored.
-    Thus it is emitted once per renderer process run.
-  </summary>
-</histogram>
-
-<histogram name="Bluetooth.Availability" enum="BluetoothAvailability"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed as of 04/2019, and replaced by Bluetooth.Availability.v2. This
-    metric was double-reporting on an error condition.
-  </obsolete>
-  <owner>kenrb@chromium.org</owner>
-  <owner>kpaulhamus@chromium.org</owner>
-  <summary>
-    Determines the availability and capabilities of the Bluetooth driver. This
-    metric is logged on startup.
-  </summary>
-</histogram>
-
-<histogram name="Bluetooth.GATTErrors" enum="BluetoothGATTErrors"
-    expires_after="2015-08-14">
-  <obsolete>
-    As of 08/2015 this has been replaced by
-    Bluetooth.Web.Characteristic.ReadValue and
-    Bluetooth.Web.Characteristic.WriteValue.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records how many times each GATT Error has occured. The results will be used
-    to determine how common this errors are and if we need to provide better
-    error messages to the users.
-  </summary>
-</histogram>
-
-<histogram name="Bluetooth.RequestDevice.Outcome"
-    enum="WebBluetoothRequestDeviceOutcome" expires_after="2015-08-12">
-  <obsolete>
-    Removed 08/2015 and replaced by Bluetooth.Web.RequestDevice.Outcome.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the result of a navigator.bluetooth.requestDevice() call. Used to
-    understand what errors developers are getting so we can target efforts
-    toward the most common ones. Multiple outcomes may result for a given
-    RequestDevice, such as rescan multiple times and then select a device.
-  </summary>
-</histogram>
-
-<histogram name="Bluetooth.Web.Blacklist.ParsedNonEmptyString"
-    enum="BooleanSuccess" expires_after="2016-11-23">
-  <obsolete>
-    Removed as of 11/2016, replaced by
-    Bluetooth.Web.Blocklist.ParsedNonEmptyString.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the result of BluetoothBlacklist::Add parsing a non-empty string.
-    These strings will be updated dynamically by a server, and this histogram
-    provides feedback that parsing is functioning correctly on clients.
-
-    False values are BAD, a blacklist is failing to be applied correctly.
-  </summary>
-</histogram>
-
-<histogram name="Bluetooth.Web.FunctionCall.Count" enum="WebBluetoothFunction"
-    expires_after="2017-03-30">
-  <obsolete>
-    Removed as of 3/2017. Replaced by using blink IDL annotation MeasureAs which
-    appear in Blink.UseCounter.Features.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Counts the number of times each call to a WebBluetooth function is done.
-  </summary>
-</histogram>
-
-<histogram name="BlueZ.ChipLost" units="seconds" expires_after="2018-08-16">
-  <obsolete>
-    Replaced 08/2018 by BlueZ.ChipLost2 for more suspend/resume filtering even
-    when the Bluetooth adapter is turned off.
-  </obsolete>
-  <owner>sonnysasaka@chromium.org</owner>
-  <summary>
-    This is specific to Chrome OS. Records a duration of a Bluetooth adapter
-    being lost caused by hardware disconnection. This helps us better understand
-    the Bluetooth controller drop issue in the field.
-  </summary>
-</histogram>
-
-<histogram name="BookmarkManager.CommandExecutedFromKeyboard"
-    enum="BookmarkManagerCommand" expires_after="2020-06-01">
-  <obsolete>
-    Removed as of May 2020.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>johntlee@chromium.org</owner>
-  <summary>
-    Logs when a keyboard shortcut triggers a command in the bookmark manager.
-
-    Revised in M-76 when the &quot;Open (double click/enter)&quot; bucket was
-    split into two separate buckets, one for bookmarks and one for folders.
-  </summary>
-</histogram>
-
-<histogram name="BookmarkManager.NumDraggedInSession" units="bookmarks"
-    expires_after="M82">
-  <obsolete>
-    Removed as of July 2020.
-  </obsolete>
-  <owner>jhimawan@google.com</owner>
-  <owner>twellington@google.com</owner>
-  <summary>
-    Logs the number of drag actions that are performed in one session (defined
-    as the time between a user's opening a folder and closing said folder).
-  </summary>
-</histogram>
-
-<histogram name="BookmarkManager.NumReorderButtonInSession" units="bookmarks"
-    expires_after="M82">
-  <obsolete>
-    Removed as of July 2020.
-  </obsolete>
-  <owner>jhimawan@google.com</owner>
-  <owner>twellington@google.com</owner>
-  <summary>
-    Logs the number of uses of the Move Up / Down buttons in one session
-    (defined as the time between a user's opening a folder and closing said
-    folder).
-  </summary>
-</histogram>
-
-<histogram name="Bookmarks.Count.OnProfileLoad.EmptyTitle" units="bookmarks"
-    expires_after="2020-05-24">
-  <obsolete>
-    Removed as of 05/2020.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    The number of bookmarks a user has saved with an empty title (strictly
-    speaking, i.e. does not count whitespace-only titles), including folders and
-    excluding the root. Recorded when bookmarks are loaded into storage from
-    disk if there is at least one node with an empty title.
-  </summary>
-</histogram>
-
-<histogram name="Bookmarks.FileSize" units="KB" expires_after="2020-03-29">
-  <obsolete>
-    Removed as of 05/2020.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    The size of the file used to persist bookmarks. It's recorded every time the
-    file is loaded in memory.
-  </summary>
-</histogram>
-
-<histogram name="Bookmarks.LaunchDepth" units="units" expires_after="M77">
-  <obsolete>
-    Removed as of 6/2019. This histogram is no longer necessary.
-  </obsolete>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Logs the depth of the bookmark in the bookmark tree hierarchy every time a
-    bookmark is launched. Depth indicates how many levels below a permanent
-    bookmark folder the bookmark was found in (e.g. a bookmark immediately in
-    the bookmark bar has depth 1).
-  </summary>
-</histogram>
-
-<histogram name="Bookmarks.OpenAction" enum="BookmarksOpenAction"
-    expires_after="2016-02-01">
-  <obsolete>
-    Removed as of 1/2016.
-  </obsolete>
-  <owner>kkimlabs@chromium.org</owner>
-  <summary>
-    Logs how user is opening a bookmark on Android. For example, user can long
-    press and select &quot;Open in a new tab&quot; or &quot;Open in incognito
-    tab&quot;.
-  </summary>
-</histogram>
-
-<histogram name="BootTime.Total" units="ms" expires_after="2017-08-24">
-  <obsolete>
-    Replaced 08/2016 by BootTime.Total2 with larger range and more buckets.
-  </obsolete>
-  <owner>bccheng@chromium.org</owner>
-  <owner>semenzato@chromium.org</owner>
-  <summary>Time from power on to login panel ready (Chrome OS).</summary>
-</histogram>
-
-<histogram name="BrotliFilter.GzipHeaderDetected" enum="BooleanPresent"
-    expires_after="M75">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>eustas@chromium.org</owner>
-  <summary>Indicates whether the gzip-like header was detected.</summary>
-</histogram>
-
-<histogram name="Browser.Metal.TestShaderCompileTime" units="ms"
-    expires_after="2020-05-18">
-  <obsolete>
-    Removed 05/2020. Was not substantially different from results in the GPU
-    process.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Compiling a MTLLibrary will sometimes hang forever. When initializing the
-    browser process, a test shader is compiled to see if the MTLCompilerService
-    is responding or not. This records the time that it took for the compile to
-    succeeded, up to 1 minute. After 1 minute, a timeout sentinel value of 3
-    minutes is reported.
-  </summary>
-</histogram>
-
-<histogram name="Browser.Metal.TestShaderMethodTime" units="ms"
-    expires_after="2020-05-18">
-  <obsolete>
-    Removed 05/2020. Did not reveal interesting results.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Compiling a MTLLibrary will sometimes hang forever. When initializing the
-    browser process, a test shader is compiled to see if the MTLCompilerService
-    is responding or not. This records the time that it took for the compile
-    method to finish (not including the time for the compile itself to finish),
-    up to 1 minute. After 1 minute, a timeout sentinel value of 3 minutes is
-    reported.
-  </summary>
-</histogram>
-
-<histogram name="BrowserActions.NumTabCreatedInBackground" units="tabNum"
-    expires_after="M80">
-  <obsolete>
-    Removed in M77 with the removal of Browser Actions.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    The number of tabs currently opened when users tap &quot;Open in new Chrome
-    tab&quot; from Browser Actions context menu. This includes the new tab
-    created from the tap.
-  </summary>
-</histogram>
-
-<histogram name="BrowserActions.SelectedOption" enum="BrowserActionsMenuOption"
-    expires_after="M80">
-  <obsolete>
-    Removed in M77 with the removal of Browser Actions.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    The option that the user selected from a Browser Actions context menu.
-  </summary>
-</histogram>
-
-<histogram name="BrowserDialogs.ExternalProtocol.RememberCheckbox"
-    enum="BooleanChecked" expires_after="2017-09-06">
-  <obsolete>
-    Removed 09/2017. This histogram has been replaced with
-    ExternalProtocol.HandleState.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    Whether or not the user checked the option in the external protocol dialog
-    to remember their choice of opening or not opening the specified app.
-    Recorded each time the user interacts with the External Protocol Dialog
-    (either accepting or cancelling/dismissing).
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.KeepAliveDuration" units="ms"
-    expires_after="2020-02-23">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    How long a render process is kept alive by additional customers such as
-    shared workers and service workers.
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.KeepAliveDuration.Fetch" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    How long fetch is alive which in turn keeps the render process alive.
-    TODO(panicker): Remove after investigation of crbug/823482, likely in M68.
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.KeepAliveDuration.ServiceWorker"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    How long service worker is alive which in turn keeps the render process
-    alive. TODO(panicker): Remove after investigation of crbug/823482, likely in
-    M68.
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.KeepAliveDuration.SharedWorker"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    How long shared worker is alive which in turn keeps the render process
-    alive. TODO(panicker): Remove after investigation of crbug/823482, likely in
-    M68.
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.KeepAliveDuration.Unload" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    How long the renderer process is kept alive by a subframe unload handler.
-    TODO(panicker): Remove after investigation of crbug/823482.
-  </summary>
-</histogram>
-
-<histogram name="BrowserRenderProcessHost.OnChannelError" enum="BooleanHit"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed Feb 2020.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    Number of times BrowserRenderProcessHost::OnChannelError was called.
-  </summary>
-</histogram>
-
-<histogram name="BrowserServices.TwaOpenTime" units="ms" expires_after="M78">
-  <obsolete>
-    Retired in M77 in favour of BrowserServices.TwaOpenTime.V2 which uses a more
-    appropriate timescale.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Triggered when a TrustedWebActivity is paused, recording the time since it
-    had been resumed.
-  </summary>
-</histogram>
-
-<histogram name="BrowserWindow.Resize.Duration" units="ms" expires_after="M77">
-  <obsolete>
-    Obsolete since 01/2020: mus+ash project was canceled, and these metrics are
-    no longer useful.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>mustash-team@google.com</owner>
-  <summary>
-    Duration of an interactive resize from start to end. Measured only on
-    Windows.
-  </summary>
-</histogram>
-
-<histogram name="BrowserWindow.Resize.StepBoundsChange" units="pixels"
-    expires_after="M81">
-  <obsolete>
-    Obsolete since 01/2020: mus+ash project was canceled, and these metrics are
-    no longer useful.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    Size changed between two consecutive steps during browser-window resize.
-    Measured only on Windows.
-  </summary>
-</histogram>
-
-<histogram name="BrowserWindow.Resize.StepCount" units="steps"
-    expires_after="M77">
-  <obsolete>
-    Obsolete since 01/2020: mus+ash project was canceled, and these metrics are
-    no longer useful.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    Number of intermediate resize-steps taken to complete the resize from start
-    to end. Measured only on Windows.
-  </summary>
-</histogram>
-
-<histogram name="BrowserWindow.Resize.StepInterval" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Obsolete since 01/2020: mus+ash project was canceled, and these metrics are
-    no longer useful.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    Time-interval between two consecutive steps during browser-window resize. An
-    interactive resize can have many number of small steps. This measures the
-    interval between two steps. 'Duration' measures the interval between the
-    first and last steps. Measured only on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.Close.Accepted" enum="BubbleType" expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was closed because the user accepted it.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.Canceled" enum="BubbleType" expires_after="M78">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>
-    An open bubble was closed because the user didn't accept it.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.Close.FocusLost" enum="BubbleType" expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was closed because of a focus change.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.Forced" enum="BubbleType" expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was forced to close.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.FrameDestroyed" enum="BubbleType"
-    expires_after="M85">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was dismissed because a frame was destroyed.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.FullscreenToggled" enum="BubbleType"
-    expires_after="M85">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>
-    An open bubble was dismissed because fullscreen was toggled.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.Close.Navigated" enum="BubbleType" expires_after="M78">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>
-    An open bubble was dismissed because the page was navigated.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.Close.TabDetached" enum="BubbleType"
-    expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was closed because a tab was detached.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.TabSwitched" enum="BubbleType"
-    expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>An open bubble was closed because a tab was switched.</summary>
-</histogram>
-
-<histogram name="Bubbles.Close.UserDismissed" enum="BubbleType"
-    expires_after="M85">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>
-    An open bubble was dismissed by the user without making a decission.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.DisplayTime.All" units="ms" expires_after="M77">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>
-    Log the amount of time any bubble was visible. Only bubbles that are shown
-    will have a visible time.
-  </summary>
-</histogram>
-
-<histogram name="Bubbles.NeverShown" enum="BubbleType" expires_after="M85">
-  <obsolete>
-    No longer used; generating code removed in M81.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <summary>A bubble was given to the bubble manager but not shown.</summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.Events" enum="ImageFetcherEvent"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.Events on 04/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Events that track the lifecycle and performance of the cached_image_fetcher.
-    The events reported include: success/failure conditions, various recoverable
-    errors and a couple of dead-end errors.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.ImageLoadFromCacheTime" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.ImageLoadFromCacheTime on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes for cached_image_fetcher to load an image from the cache
-    in native.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.ImageLoadFromCacheTimeJava" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.ImageLoadFromCacheTimeJava on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes for cached_image_fetcher to load an image from the cache
-    in Java.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.ImageLoadFromNativeTimeJava" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.ImageLoadFromNativeTimeJava on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes for cached_image_fetcher to load an image from native
-    code. Only recorded on successful loads.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit"
-    units="ms" expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.ImageLoadFromNetworkAfterCacheHit on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes for cached_image_fetcher to load an image from the network
-    after a cache hit.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.ImageLoadFromNetworkTime" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.ImageLoadFromNetworkTime on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes for cached_image_fetcher to load an image from the
-    network.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.LoadImageMetadata" units="ms"
-    expires_after="2020-06-30">
-  <obsolete>
-    Renamed to ImageFetcher.LoadImageMetadata on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time it takes to load an image's metadata from the metadata store.
-  </summary>
-</histogram>
-
-<histogram name="CachedImageFetcher.TimeSinceLastCacheLRUEviction" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Renamed to ImageFetcher.TimeSinceLastCacheLRUEviction on 06/2019.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    The time since the last LRU eviction from the image cache. Recorded when two
-    LRU evictions occur within closure proximity to one another. Will be used to
-    determine if LRU eviction is happening too frequently.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.ContextType" enum="CanvasContextType"
-    expires_after="2018-10-23">
-  <obsolete>
-    Replaced with Blink.Canvas.ContextType in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>kbr@chromium.org</owner>
-  <summary>
-    Records the context type names used to create canvas rendering contexts.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.CreateImageBitmapSource"
-    enum="CanvasCreateImageBitmapSource" expires_after="2018-11-01">
-  <obsolete>
-    Replaced with Blink.Canvas.CreateImageBitmapSource in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>zakerinasab@chromium.org</owner>
-  <summary>
-    The source from which an ImageBitmap is created by a createImageBitmap call.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.DisplayListFallbackReason"
-    enum="CanvasDisplayListFallbackReason" expires_after="2017-12-04">
-  <obsolete>
-    Removed 11/2017 with removal of Display List Canvas 2D mode.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    The reasons why a canvas initially set to display list mode had to fall back
-    to direct rasterization mode.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.GPUAccelerated2DCanvasDisableDeferralReason"
-    enum="CanvasGPUAccelerated2DCanvasDisableDeferralReason"
-    expires_after="2018-11-01">
-  <obsolete>
-    Replaced with Blink.Canvas.GPUAccelerated2DCanvasDisableDeferralReason in
-    10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    The reasons why a GPU accelerated canvas stopped deferring its rendering
-    operations.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.HibernationEvents" enum="CanvasHibernationEvent"
-    expires_after="2018-11-01">
-  <obsolete>
-    Replaced with Blink.Canvas.HibernationEvents in 10/2018.
-  </obsolete>
-  <owner>fserb@chromium.org</owner>
-  <owner>aaronhk@chromium.org</owner>
-  <summary>
-    Records the occurrence of events related to 2D canvas GPU resource
-    hibernation.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.Offscreen.CommitType" enum="OffscreenCanvasCommitType"
-    expires_after="2018-10-23">
-  <obsolete>
-    Removed 10/2018 with Blink.OffscreenCanvas histograms
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    The type of code path that OffscreenCanvas's commit API goes through.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.Repaint.Bounds.Percentage" units="%"
-    expires_after="M84">
-  <obsolete>
-    The experiment finishes and removed in 03/2020
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    measure the percentage of Canvas is dirty before each repaint by using
-    cc::Rect. Note that we record this metrics for all canvas that has an area
-    of more than 65k pixel^2 (256x256).
-  </summary>
-</histogram>
-
-<histogram name="Canvas.Repaint.Region.Percentage" units="%"
-    expires_after="M84">
-  <obsolete>
-    The experiment finishes and removed in 03/2020
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    measure the percentage of Canvas is dirty before each repaint by using
-    cc::Region. Note that we record this metrics for all canvas that has an area
-    of more than 65k pixel^2 (256x256).
-  </summary>
-</histogram>
-
-<histogram name="Canvas.RequestedImageMimeTypes" enum="RequestedImageMimeType"
-    expires_after="2018-11-01">
-  <obsolete>
-    Replaced with Blink.Canvas.RequestedImageMimeTypes in 10/2018.
-  </obsolete>
-  <owner>aaronhk@chromium.org</owner>
-  <summary>
-    Records the occurence of image file formats passed into toDataURL and toBlob
-    functions in canvas.
-  </summary>
-</histogram>
-
-<histogram name="Canvas.TextMetrics.MeasureText" units="microseconds"
-    expires_after="2019-08-14">
-  <obsolete>
-    Removed 2019/08, this metrics doesn't reflect the measurement speed because
-    it is dependent on the length of text.
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent in microseconds to perform calls to measure TextMetrics for
-    Canvas2d. It's measured each time TextMetrics is called.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="CAPSUpdater.Step" enum="CAPSUpdaterStep"
-    expires_after="2016-08-18">
-  <obsolete>
-    Removed 08/2016 with removal of Chrome Crash Service component.
-  </obsolete>
-  <owner>scottmg@chromium.org</owner>
-  <summary>
-    Tracks the component updater steps for the Chrome Crash Service.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Notification.Status"
-    enum="CaptivePortalNotificationStatus" expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Count of displayed and not displayed due to errors notifications about
-    captive portal.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Notification.UserAction"
-    enum="CaptivePortalNotificationUserAction" expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>pmarko@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Count of clicked, closed and ignored captive portal notifications.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.OOBE.DetectionDuration" units="ms"
-    expires_after="2020-08-09">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Duration of the captive portal detection process for a particular network at
-    OOBE. Detection duration is recorded each time portal detection is completed
-    for an active network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.OOBE.DetectionResult" enum="CaptivePortalStatus"
-    expires_after="2020-08-09">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts performed at OOBE. Detection
-    result is recorded when portal detection is completed for an active network
-    and when it differs from the previous result for the same network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.OOBE.DiscrepancyWithShill" units="units"
-    expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts at OOBE if it diverges from
-    network manager results. Detection result is recorded each time portal
-    detection is completed for an active network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.OOBE.PortalToOnlineTransition" units="ms"
-    expires_after="2020-08-16">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Number of milliseconds passed between consecutive reports for the same
-    network about portal and online states.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.RedirectTime" units="ms"
-    expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>pmarko@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Number of milliseconds between start of request to gstatic.com/generate_204
-    and receipt of response with redirect to captive portal login page.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.DetectionDuration" units="ms"
-    expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>pmarko@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <summary>
-    Duration of the captive portal detection process for a particular network in
-    user session. Detection duration is recorded each time portal detection is
-    completed for an active network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.DetectionResult"
-    enum="CaptivePortalStatus" expires_after="2020-12-20">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>pmarko@chromium.org</owner>
-  <owner>michaeldo@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts performed in user session.
-    Detection result is recorded when portal detection is completed for an
-    active network and when it differs from the previous result for the same
-    network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.DiscrepancyWithShill"
-    enum="CaptivePortalStatus" expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts in session if it diverges
-    from network manager results. Detection result is recorded each time portal
-    detection is completed for an active network.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.PortalToOnlineTransition" units="ms"
-    expires_after="2020-06-07">
-  <obsolete>
-    Retired in M85.
-  </obsolete>
-  <owner>rsorokin@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Number of milliseconds passed between consecutive reports for the same
-    network about portal and online states.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.SecureConnectionFailed"
-    enum="CaptivePortalStatus" expires_after="M84">
-  <obsolete>
-    Retired in M86.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts performed in user session.
-    Detection result is recorded when portal detection is completed for a failed
-    secure connection.
-  </summary>
-</histogram>
-
-<histogram name="CaptivePortal.Session.TimeoutDetectionResult"
-    enum="CaptivePortalStatus" expires_after="M84">
-  <obsolete>
-    Retired in M86.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <owner>cros-networking@google.com</owner>
-  <summary>
-    The result of captive portal detection attempts performed in user session.
-    Detection result is recorded when portal detection is completed for a
-    request which timed out or hadn't yet replied within eight seconds.
-  </summary>
-</histogram>
-
-<histogram name="Cast.Sender.CastButtonShown" enum="BooleanEnabled"
-    expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Records the number of times the cast button was shown to the user. The value
-    will be true if the button is enabled, and false if the button is disabled.
-    Note that depending on the current UX, it's possible that we hide the button
-    entirely if it's disabled, so it's possible for the false values to be 0.
-  </summary>
-</histogram>
-
-<histogram name="Cast.Sender.CastButtonShownInitialFullscreen"
-    enum="BooleanEnabled" expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Records the number of times the cast button was shown to the user when the
-    video is fullscreened. The value will only be recorded on entering
-    fullscreen. The value will be true if the button is enabled, and false if
-    the button is disabled. Note that depending on the current UX,it's possible
-    that we hide the button entirely if it's disabled, so it's possible for the
-    false values to be 0.
-  </summary>
-</histogram>
-
-<histogram name="Cast.Sender.CastPlaySuccess" enum="BooleanSuccess"
-    expires_after="2014-05-02">
-  <obsolete>
-    Removed 04/2014, and replaced by Cast.Sender.CastPlayerResult.
-  </obsolete>
-  <owner>maybelle@chromium.org</owner>
-  <owner>miguelg@chromium.org</owner>
-  <summary>
-    Records the result of a request to play remotely. The value will be true if
-    the playback succeeded, and false if there was an error.
-  </summary>
-</histogram>
-
-<histogram name="Cast.Sender.Overlay" enum="CastOverlayEvents"
-    expires_after="2017-07-14">
-  <obsolete>
-    Removed July 2017 in favor of Media.Controls.CTR.CastOverlayButton.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records events and user interactions related to the Cast overlay shown on
-    video elements.
-  </summary>
-</histogram>
-
-<histogram name="Cellular.ActivationFailure" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of cellular device activation failures (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="Cellular.ActivationTry" units="units" expires_after="M85">
-  <obsolete>
-    Removed 07/2020 because the histogram is neither logged nor owned.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The count of cellular device activation tries (Chrome OS).</summary>
-</histogram>
-
-<histogram name="Cellular.ConnectionFailed" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of cellular reconnect failures during activation (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="Cellular.ConnectionRetry" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of cellular device reconnect tries during activation (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="Cellular.MobileSetupFailed" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of successful cellular plan established (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="Cellular.MobileSetupStart" units="units" expires_after="M77">
-  <obsolete>
-    Removed 07/2020 because it is unowned and did not appear to be needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of initiated cellular device setup starts (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="Cellular.MobileSetupSucceeded" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed logging on 07/2020; the histogram is unowned and has been marked as
-    obsolete since 04/2016.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The count of failed cellular plan setup tries (Chrome OS).</summary>
-</histogram>
-
-<histogram name="Cellular.PaymentFailed" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed logging on 07/2020; the histogram is unowned and has been marked as
-    obsolete since 04/2016.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The count of failed cellular plan purchases (Chrome OS).</summary>
-</histogram>
-
-<histogram name="Cellular.PaymentReceived" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed logging on 07/2020; the histogram is unowned and has been marked as
-    obsolete since 04/2016.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of successfully completed cellular plan purchases (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="CertificateType" units="units" expires_after="2013-08-09">
-  <obsolete>
-    Removed as of 8/2013. This histogram only considered the leaf certificate
-    expiry date as a proxy for whether a certificate was in-scope for the BRs,
-    but did not consider the issuance date. As some CAs have issued long-lived
-    certs prior to the BRs, this disproportionately reported those certs as
-    being subject to the BRs, but non-compliant, when in reality they're not
-    subject.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Information about the certificate algorithms and sizes in use on the web, to
-    examine compliance with the CA/Browser Forum requirements and security best
-    practice.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.Crashed" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 3/2013. Renamed to ChildProcess.Crashed2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Count of child process crashes grouped by process type.</summary>
-</histogram>
-
-<histogram name="ChildProcess.CrashedWasAlive" enum="ProcessType"
-    expires_after="2015-10-29">
-  <obsolete>
-    Removed as of 10/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process crashes that we miscounted because we took the exit
-    code too early. Grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.Crashes" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 10/2011. Renamed to ChildProcess.Crashed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Count of child process crashes grouped by process type.</summary>
-</histogram>
-
-<histogram name="ChildProcess.CrashesWasAlive" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 10/2011. Renamed to ChildProcess.CrashedWasAlive.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process crashes that we miscounted because we took the exit
-    code too early. Grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.DefaultCase" enum="ProcessType"
-    expires_after="2015-10-29">
-  <obsolete>
-    Removed as of 10/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process crashes for which we were not able to understand the
-    exit code, grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.Disconnected" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 3/2013. Renamed to ChildProcess.Disconnected2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process abnormal channel disconnects grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.DisconnectedAlive" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 3/2013. Renamed to ChildProcess.DisconnectedAlive2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process abnormal channel disconnects that are not classified
-    and reported because we took the exit code too early. Grouped by process
-    type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.HangRendererType" enum="RendererUnresponsiveType"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed 3/2017.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    What the browser was waiting for from the renderer when it was reported as
-    hung.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.HungRendererCause"
-    enum="RendererUnresponsiveCause" expires_after="M74">
-  <obsolete>
-    Removed 4/2019.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    What the browser was waiting for from the renderer when it was reported as
-    hung.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.InvalidSandboxStateCrash.NoStartupWindow"
-    enum="BooleanPresent" expires_after="M77">
-  <obsolete>
-    Removed 6/2019.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    Whether the browser command line had the switch --no-startup-window when a
-    child process crashed due to invalid sandbox state. Recorded when a child
-    process crashes if the exit code from the child process is
-    RESULT_CODE_INVALID_SANDBOX_STATE.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.Killed" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 3/2013. Renamed to ChildProcess.Killed2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Count of child process kills grouped by process type.</summary>
-</histogram>
-
-<histogram name="ChildProcess.KilledWasAlive" enum="ProcessType"
-    expires_after="2015-10-29">
-  <obsolete>
-    Removed as of 10/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process kills that we miscounted because we took the exit
-    code too early. Grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="ChildProcess.Kills" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 10/2011. Renamed to ChildProcess.Killed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Count of child process kills grouped by process type.</summary>
-</histogram>
-
-<histogram name="ChildProcess.KillsWasAlive" enum="ProcessType"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed 10/2011. Renamed to ChildProcess.KilledWasAlive.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of child process kills that we miscounted because we took the exit
-    code too early. Grouped by process type.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.Android.Activity.CrashCounts" enum="AndroidActivityId"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates how many times each particular type of Activity was in the
-    foreground when a UMA session was terminated abnormally. UMA sessions last
-    as long as Chrome remains in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.Android.Activity.LaunchCounts" enum="AndroidActivityId"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates how many times each particular type of Activity was brought to the
-    foreground when a UMA session was active (i.e. launched at some point). UMA
-    sessions last as long as Chrome remains in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.Browser.CrashedExecutionPhase" enum="ExecutionPhase"
-    expires_after="2018-12-05">
-  <obsolete>
-    Removed 12/2019.
-  </obsolete>
-  <owner>manzagop@chromium.org</owner>
-  <summary>
-    Indicates the execution phase the browser was in when the browser crashed.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.Browser.ExecutionPhase" enum="ExecutionPhase"
-    expires_after="2013-11-14">
-  <obsolete>
-    Removed as of 11/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates the execution phase the browser was in when browser didn't exit
-    cleanly.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.BrowserCrashDumpAttempts" units="units"
-    expires_after="2015-03-31">
-  <obsolete>
-    Removed as of 04/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total number of times the browser process has attempted to generate a
-    crash dump. This should be the sum of Chrome.BrowserDumpsWithCrash and
-    Chrome.BrowserDumpsWithNoCrash.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.BrowserDumpsWithCrash" units="units"
-    expires_after="2015-03-31">
-  <obsolete>
-    Removed as of 04/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times the browser process has attempted to generate a crash
-    dump because of an actual browser crash.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.BrowserDumpsWithNoCrash" units="units"
-    expires_after="2015-03-31">
-  <obsolete>
-    Removed as of 04/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times the browser process has attempted to generate a crash
-    dump in a non-crashing (i.e., reporting only) context.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.CommandLineFlagCount" units="switches"
-    expires_after="M79">
-  <obsolete>
-    Removed in 07/2020 because the histogram is unused.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    The number of command line switches that were present at the start of a
-    chrome session.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.CommandLineUncommonFlagCount" units="switches"
-    expires_after="M79">
-  <obsolete>
-    Removed in 07/2020 because the histogram is unused.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    The number of command line switches that were present at the start of a
-    chrome session, excluding App Mode and User Data Directory switches.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows"
-    enum="WinGetLastError" expires_after="2017-12-01">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <owner>aseren@yandex-team.ru</owner>
-  <summary>
-    The error code of remote process termination on Windows in case when remote
-    process hung. This histogram has been replaced by
-    Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows histogram.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExempt" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user not in the search engine dialog
-    experiment.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExperiment" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user in the search engine dialog
-    experiment.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExperimentSlot1" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user in slot 1 of a randomized
-    search engine dialog.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExperimentSlot2" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user in slot 2 of a randomized
-    search engine dialog.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExperimentSlot3" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user in slot 3 of a randomized
-    search engine dialog.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.SearchSelectExperimentSlot4" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The default search engine selected by a user in slot 4 of a randomized
-    search engine dialog.
-  </summary>
-</histogram>
-
-<histogram name="Chrome.UmaPageloadCounter" enum="BooleanHit"
-    expires_after="2017-06-06">
-  <obsolete>
-    Removed 6/2017. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records when a page load happens, based on the same logic as the PageLoad
-    user action.
-  </summary>
-</histogram>
-
-<histogram name="ChromeColors.AppliedColor" enum="ChromeColorsInfo"
-    expires_after="2020-07-06">
-  <obsolete>
-    Removed 12/2019. No longer tracked.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    Records applied color id every time its applied from Colors menu.
-  </summary>
-</histogram>
-
-<histogram name="ChromeColors.ChangesConfirmed"
-    enum="BooleanChromeColorsChangesConfirmed" expires_after="2020-05-03">
-  <obsolete>
-    Removed 12/2019. No longer tracked.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    Records whether color/theme changes were confirmed or reverted by
-    ChromeColorsService.
-  </summary>
-</histogram>
-
-<histogram name="ChromeColors.RevertReason" enum="ChromeColorsRevertReason"
-    expires_after="2020-07-06">
-  <obsolete>
-    Removed 12/2019. No longer tracked.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    Records the reason color/theme changes were reverted by ChromeColorsService.
-  </summary>
-</histogram>
-
-<histogram name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime"
-    units="ms" expires_after="2016-10-13">
-  <obsolete>
-    Removed 10/2016 in favor of .IntentToFirstCommitNavigationTime2.*.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Time between the intent arrival in a Chrome generated custom tab and the
-    first navigation commit, if the navigation is successful. Similar in
-    principle to Startup.FirstCommitNavigationTime.
-  </summary>
-</histogram>
-
-<histogram name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime2"
-    units="ms" expires_after="2017-09-04">
-  <obsolete>
-    Removed 2017-08 in favor of
-    ChromeGeneratedCustomTab.IntentToFirstNavigationStartTime.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    In &quot;Herb&quot; mode shows the time between the intent arrival in a
-    Chrome generated custom tab and the first navigation start (note: not the
-    navigation commit, as the name suggests). Recorded when the page has
-    finished loading.
-  </summary>
-</histogram>
-
-<histogram name="ChromeNotifierService.Actions"
-    enum="ChromeNotifierServiceActionType" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The actions to enable or disable services sending synced notifications.
-    Synced Notification Sending services can be individually disabled by the
-    user in the Chrome Notification center settings dialog.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.CWP.CollectHeap"
-    enum="ChromeOSProfileCollectionStatus" expires_after="2020-02-01">
-  <obsolete>
-    Removed 01/2020 in Issue 1036859 with the removal of the heap collection
-    code.
-  </obsolete>
-  <owner>aalexand@google.com</owner>
-  <owner>gmx@chromium.org</owner>
-  <summary>
-    A count of successes and various failure modes related to the collection and
-    processing of Chrome heap sample profiles on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.CWP.UploadHeap" units="reports"
-    expires_after="2020-02-01">
-  <obsolete>
-    Removed 01/2020 in Issue 1036859 with the removal of the heap collection
-    code.
-  </obsolete>
-  <owner>aalexand@google.com</owner>
-  <owner>gmx@chromium.org</owner>
-  <summary>
-    Records the number of &quot;heap&quot; reports included in an UMA upload on
-    Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.DetachableBase.PairResult"
-    enum="DetachableBasePairResult" expires_after="2017-10-20">
-  <obsolete>
-    Removed 10/2017 and replaced by Platform.DetachableBase.PairResult.
-  </obsolete>
-  <owner>kitching@google.com</owner>
-  <summary>Result of a Chrome OS detachable base pair operation.</summary>
-</histogram>
-
-<histogram name="ChromeOS.DetachableBase.ROUpdateMetric"
-    enum="DetachableBaseROUpdateResult" expires_after="2017-10-20">
-  <obsolete>
-    Removed 10/2017 and replaced by Platform.DetachableBase.ROUpdateMetric.
-  </obsolete>
-  <owner>kitching@google.com</owner>
-  <summary>Result of a Chrome OS detachable base RO firmware update.</summary>
-</histogram>
-
-<histogram name="ChromeOS.DetachableBase.RWUpdateMetric"
-    enum="DetachableBaseRWUpdateResult" expires_after="2017-10-20">
-  <obsolete>
-    Removed 10/2017 and replaced by Platform.DetachableBase.RWUpdateMetric.
-  </obsolete>
-  <owner>kitching@google.com</owner>
-  <summary>Result of a Chrome OS detachable base RW firmware update.</summary>
-</histogram>
-
-<histogram name="ChromeOS.Display.ColorProfile" enum="ChromeOSColorProfile"
-    expires_after="2017-08-19">
-  <obsolete>
-    Removed 8/2017.
-  </obsolete>
-  <owner>xiaowenx@chromium.org</owner>
-  <owner>mukai@chromium.org</owner>
-  <summary>
-    The name of the current color calibration of the display on Chrome OS. This
-    value is sent when the color calibration is changed by the user.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.GAIA.WebViewFlow" enum="BooleanGAIAWebViewFlow"
-    expires_after="M85">
-  <obsolete>
-    Removed in 2020/06 as the histogram is no longer in use. The instrumentation
-    code is long gone. The iframe flow is not used since 2015.
-  </obsolete>
-  <owner>achuith@chromium.org</owner>
-  <summary>
-    Whether a user signed in using the new WebView-based GAIA flow. This value
-    is sent after the GAIA screen has completed user authentication.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.PlatformKeysService.{Operation}.{KeyType}"
-    enum="BooleanSuccess" expires_after="2022-03-19">
-  <obsolete>
-    Removed in 2022/03 as part of https://crbug.com/1294874 and
-    https://crbug.com/1294873
-  </obsolete>
-  <owner>omorsi@google.com</owner>
-  <owner>mgawad@google.com</owner>
-  <summary>
-    Tracks the final result of performing {Operation} operation on an {KeyType}
-    key in PlatformKeysService.
-  </summary>
-  <token key="Operation">
-    <variant name="GenerateKey"/>
-    <variant name="SignKey"/>
-  </token>
-  <token key="KeyType">
-    <variant name="EC"/>
-    <variant name="RSA"/>
-  </token>
-</histogram>
-
-<histogram name="ChromeOS.PlatformVerification.ExpiryStatus"
-    enum="ChromeOSPlatformVerificationExpiryStatus" expires_after="M80">
-  <obsolete>
-    Removed in 2019/08 as the histogram is no longer in use. (crbug/975047)
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    The result of a certificate expiry check during a platform verification
-    attempt for content protection on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.SAML.APIUsed" enum="BooleanUsage"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed as of 10/2019. Replaced with ChromeOS.SAML.APILogin that correctly
-    records various login flows.
-  </obsolete>
-  <owner>bartfab@chromium.org</owner>
-  <summary>
-    Whether a Chrome OS login via SAML used the principals API. This is recorded
-    during login on Chrome OS if SAML is being used for authentication.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.SAML.Scraping.PasswordCount" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 10/2019. Replaced with ChromeOS.SAML.Scraping.PasswordCountAll
-    that fixes the main case of a single scraped password.
-  </obsolete>
-  <owner>bartfab@chromium.org</owner>
-  <summary>
-    The number of passwords that were scraped during a Chrome OS login via SAML.
-    This is set only when the principals API is not used.
-  </summary>
-</histogram>
-
-<histogram name="ChromeOS.Settings.BrowserBannerInteraction"
-    enum="CrosSettingsBrowserBannerInteraction" expires_after="2020-06-01">
-  <obsolete>
-    Removed as of 05/2020 (crbug/1072514).
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <owner>cros-system-services@google.com</owner>
-  <summary>
-    Records whether the &quot;try your Chrome browser settings&quot; banner was
-    shown when the user opened a new Chrome OS settings window and also records
-    interactions with the banner.
-  </summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.BrowserStates"
-    enum="ChromiumAndroidLinkerBrowserState" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>digit@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Whether relro sharing was attempted for the browser process, and if
-    attempted, whether it succeeded.
-  </summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.IsLowMemoryDevice" enum="Boolean"
-    expires_after="2014-10-13">
-  <obsolete>
-    Removed 10/2014 in Issue 419010, and replaced by
-    ChromiumAndroidLinker.BrowserStates.
-  </obsolete>
-  <owner>simonb@chromium.org</owner>
-  <summary>Is low memory device.</summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.LibraryLoadFromApkStatus"
-    enum="LibraryLoadFromApkStatus" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>petrcermak@chromium.org</owner>
-  <summary>
-    Whether the device supports loading a library directly from the APK file.
-    The functionality is checked and reported during every Chromium browser
-    process start up.
-  </summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.LoadedAtFixedAddressFailed"
-    enum="Boolean" expires_after="2014-10-13">
-  <obsolete>
-    Removed 10/2014 in Issue 419010, and replaced by
-    ChromiumAndroidLinker.RendererStates.
-  </obsolete>
-  <owner>simonb@chromium.org</owner>
-  <summary>Load at fixed address failed.</summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.LoadLibraryStatus"
-    enum="LoadLibraryStatus" expires_after="2020-08-02">
-  <obsolete>
-    Removed 2020-02 as part of crbug.com/1021156.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Status of each attempt to load the native library with a custom linker.
-    Recorded after each attempt to load. Not recorded when all attempts fail in
-    a process.
-  </summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.RelinkerFallbackCount"
-    enum="BooleanIsUseRelinker" expires_after="M80">
-  <obsolete>
-    Removed 2019-07 in crbug.com/981599.
-  </obsolete>
-  <owner>agrieve@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The total number of times Chrome uses relinker fallback to extract and load
-    native libraries.
-  </summary>
-</histogram>
-
-<histogram name="ChromiumAndroidLinker.RendererStates"
-    enum="ChromiumAndroidLinkerRendererState" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>simonb@chromium.org</owner>
-  <summary>
-    Whether relro sharing was attempted for a renderer process, and if
-    attempted, whether it succeeded.
-  </summary>
-</histogram>
-
-<histogram name="clickjacking.discard_download" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 07/2020 because this unowned histogram is no longer being used and
-    has expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The length of time between a dangerous download appearing on the downloads
-    shelf, and the &quot;Discard&quot; button being clicked.
-  </summary>
-</histogram>
-
-<histogram name="clickjacking.dismiss_download" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 07/2020 because this unowned histogram is no longer being used and
-    has expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The length of time between a dangerous download appearing on the downloads
-    shelf, and the &quot;Dismiss&quot; button being clicked. Deprecated since
-    M54.
-  </summary>
-</histogram>
-
-<histogram name="clickjacking.launch_url" units="ms" expires_after="2018-08-30">
-  <obsolete>
-    Removed 07/2020 because this unowned histogram is no longer being used and
-    has expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The length of time between the external protocol dialog being shown and the
-    &quot;Launch Application&quot; button being clicked.
-  </summary>
-</histogram>
-
-<histogram name="clickjacking.open_download" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 07/2020 because this unowned histogram is no longer being used and
-    has expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The length of time between a download appearing on the download shelf, and
-    the user opening it by clicking the item or pressing return.
-  </summary>
-</histogram>
-
-<histogram name="clickjacking.report_and_discard_download" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time between &quot;Report and Discard&quot; button being shown and it being
-    clicked.
-  </summary>
-</histogram>
-
-<histogram name="ClientHints.CountRulesReceived" units="count"
-    expires_after="M88">
-  <obsolete>
-    Removed M86 since what it's measuring no longer happens.
-  </obsolete>
-  <owner>yoavweiss@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <owner>mkwst@chromium.org</owner>
-  <summary>
-    Count of client hints that were received by the render process. Recorded
-    approximately at the time of the renderer startup.
-  </summary>
-</histogram>
-
-<histogram name="Clipboard.ConstructedHasher" enum="BooleanSuccess"
-    expires_after="2017-04-13">
-  <obsolete>
-    Launched briefly in M-59 dev, then refactoring made obsolete.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Whether Android's Clipboard.java successfully constructed a hasher to hash
-    clipboard entries. Recorded on construction of the class, which happens only
-    on startup.
-  </summary>
-</histogram>
-
-<histogram name="Clipboard.IncognitoUseCase" enum="ClipboardAction"
-    expires_after="2013-04-08">
-  <obsolete>
-    Removed as of 4/2013, experiment confirmed correctness of our patch.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Counts how often the user writes or reads from the clipboard and whether the
-    write was from an incognito window or not.
-  </summary>
-</histogram>
-
-<histogram name="CloudPrint.CapsUpdateInterval" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The amount of time between capabilities updates.</summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceProcessSocketLength" units="units"
-    expires_after="2015-12-01">
-  <obsolete>
-    Removed 12/2015. http://crbug.com/466644
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Temporarily histogram with size of IPC sockets in default location.
-  </summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilityCapsFailTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The amount of time used to fail to collect printer capabilities.
-  </summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilityCapsTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The amount of time used to collect printer capabilities.</summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilityDisconnectTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The amount of time the utility process runs before disconnect.
-  </summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilityMetafileFailTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The amount of time used to fail to generate metafile.</summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilityMetafileTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The amount of time used to generate metafile.</summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilitySemanticCapsFailTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The amount of time used to fail to collect printer capabilities.
-  </summary>
-</histogram>
-
-<histogram name="CloudPrint.ServiceUtilitySemanticCapsTime" units="ms"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The amount of time used to collect printer capabilities.</summary>
-</histogram>
-
-<histogram name="CloudPrint.XmppTimeout" units="ms" expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017. http://crbug.com/643570
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Xmpp timeout option value provided by server.</summary>
-</histogram>
-
-<histogram name="CompositeDocToPdf.Status" enum="PdfCompositionStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed in July 2019
-  </obsolete>
-  <owner>weili@chromium.org</owner>
-  <summary>
-    Tracks the status of PDF document composition and generation conducted in
-    PDF compositor service.
-  </summary>
-</histogram>
-
-<histogram name="CompositePageToPdf.Status" enum="PdfCompositionStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed in July 2019
-  </obsolete>
-  <owner>weili@chromium.org</owner>
-  <summary>
-    Tracks the status of PDF page composition and generation conducted in PDF
-    compositor service.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.CachedImagesCount" units="count"
-    expires_after="M80">
-  <obsolete>
-    Removed 05/2019 because it no longer reports. To be superseded by a
-    measurement related to percentage of cache/discardable memory used by image
-    caching.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    The maximum number of images that were cached in the browser over the
-    lifetime of the image decode cache. This is recorded at the image cache
-    destruction. It is further split up by Software and Gpu rasterization.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.CompositorFrame.Quads" units="quads"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019 because the research it was used for is complete.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The total number of quads in all render passes in a CompositorFrame. This is
-    logged as the CompositorFrame is submitted to its surface.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Browser.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="M80">
-  <obsolete>
-    Removed 05/2016. See Blink.Paint.UpdateTime as a related alternate metric.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when display list recording source is updated (in a
-    browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.DisplayListRecordingSource.UpdateUs"
-    units="microseconds" expires_after="2016-05-10">
-  <obsolete>
-    Removed 05/2016. See Blink.Paint.UpdateTime as a related alternate metric.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a display list, in microseconds.
-    Recorded when display list is updated (in a browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.DrawResult" enum="DrawResult"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    How often the layer compositor successfully submitted content to the display
-    compositor, or what caused an abort. This is reported fairly late in the
-    pipeline, during the final stages of submitting content.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.PictureMemoryUsageKb" units="KB"
-    expires_after="M85">
-  <obsolete>
-    Has not produced data for over a year prior to removal in 03/2020.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total estimated memory used by SkPictures in the layer tree, in kilobytes.
-    Recorded once per frame, before the frame is drawn (in a browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.PicturePile.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="M85">
-  <obsolete>
-    Obsolete since 2015.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when picture pile is updated (in a browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.PicturePile.UpdateUs" units="microseconds"
-    expires_after="M85">
-  <obsolete>
-    Obsolete since 2015.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a picture pile, in microseconds.
-    Recorded when picture pile is updated (in a browser process).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.RasterTask.RasterPixelsPerMs"
-    units="pixels/ms" expires_after="2016-11-29">
-  <obsolete>
-    Removed 11/2016. Increased the max tracking range to accomendate GPU raster,
-    and will require new baskets.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Rasterized area, in pixels, divided by rasterization time, in milliseconds,
-    of a compositor rasterization task. Recorded after the task finishes (in a
-    browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.RasterTask.RasterPixelsPerMs2"
-    units="pixels/ms" expires_after="2019-4-24">
-  <obsolete>
-    Removed 04/2019. Was unused.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Rasterized area, in pixels, divided by rasterization time, in milliseconds,
-    of a compositor rasterization task. Recorded after the task finishes (in a
-    browser process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Browser.RasterTask.RasterUs" units="microseconds"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2019. Was unused.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent completing a compositor rasterization task, in microseconds.
-    Recorded after the task finishes (in a browser process).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Browser.RenderPass.AppendQuadData.NumMissingTilesNoImageContent"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 02/2016. We'd learned as much as we could from this metric and it
-    made no sense to keep it around.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    Tracks the number of missing tiles that had some image content in the
-    browser process.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Browser.RenderPass.AppendQuadData.NumMissingTilesSomeImageContent"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 02/2016. We'd learned as much as we could from this metric and it
-    made no sense to keep it around.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    Tracks the number of missing tiles that did not have any image content in
-    the browser process.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.CompositorFrameSinkSupport.SubmitResult"
-    enum="CompositorFrameSinkSubmitResult" expires_after="2020-03-01">
-  <obsolete>
-    Expired 2020-03-01.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The result of submitting a CompositorFrame to a CompositorFrameSink.
-    ACCEPTED means the frame was accepted by the CompositorFrameSink.
-    COPY_OUTPUT_REQUESTS_NOT_ALLOWED means an unprivileged client attempted to
-    readback a texture. SURFACE_INVARIANTS_VIOLATION means size or device scale
-    factor changed but a new viz::LocalSurfaceId was not allocated.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.CopyFromSurfaceTimeSynchronous" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Made obsolete 04/2016. Logging removed 08/2020.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time taken for the sync readback of pixels is measured here.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Display.Draw.Occlusion.Drawing.Area.Saved"
-    units="px" expires_after="2018-02-28">
-  <obsolete>
-    Removed 02/2018, replaced by similar metric
-    Compositing.Display.Draw.Occlusion.Drawing.Area.Saved2.
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <summary>
-    It records the total drawing area skipped to show on screen as a result of
-    applying draw occlusion. This is logged once per frame, when the frame is
-    drawn.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Display.Draw.Quads" units="quads"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019 because the research it was used for is complete.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    This is logged once per frame, when the frame is drawn. The total number of
-    quads in all render passes in the CompositorFrame that is produced by
-    surface aggregation.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Display.Draw.Quads.With.Complex.Transform.Area"
-    units="px" expires_after="2018-03-18">
-  <obsolete>
-    Removed 03/2018. We'd learned enough from this metric and it made no sense
-    to keep it around.
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <summary>
-    This is logged once per frame, when the frame is drawn. Captures area of all
-    draw quads that need to go through no scale and no translation transforms.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="M80">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when display list recording source is updated.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.DisplayListRecordingSource.UpdateUs"
-    units="microseconds" expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a display list, in microseconds.
-    Recorded when display list is updated.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.LayerTreeImpl.FindClosestMatchingLayerUs"
-    units="microseconds" expires_after="2017-05-26">
-  <obsolete>
-    Removed 05/2017 in Issue 710306. Histogram was used temporarily for tracking
-    a potential performance regression.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent finding the closest matching layer to a given point, in
-    microseconds. Recorded each time we do hit testing on LayerTreeImpl.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.MainFrameSynchronization.Duration" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Expired M81
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The amount of time it took for a main frame with unresolved dependencies to
-    activate. Note that some activations may be triggered due to a deadline
-    hitting.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.NumActiveLayers" units="units"
-    expires_after="2016-04-20">
-  <obsolete>
-    Removed 04/2016, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>dneto@chromium.org</owner>
-  <summary>
-    The number of layers in the active tree for each compositor frame. This is
-    logged once per frame, before the frame is drawn.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.PictureMemoryUsageKb" units="KB"
-    expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total estimated memory used by SkPictures in the layer tree, in kilobytes.
-    Recorded once per frame, before the frame is drawn.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.PicturePile.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when picture pile is updated.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.PicturePile.UpdateUs" units="microseconds"
-    expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a picture pile, in microseconds.
-    Recorded when picture pile is updated.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RasterTask.RasterPixelsPerMs" units="pixels/ms"
-    expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Rasterized area, in pixels, divided by rasterization time, in milliseconds,
-    of a compositor rasterization task. Recorded after the task finishes.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RasterTask.RasterUs" units="microseconds"
-    expires_after="2015-09-04">
-  <obsolete>
-    Removed 09/2015, replaced by similar metrics under Compositing.Renderer and
-    Compositing.Browser, depending on which process it occurs in.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent completing a compositor rasterization task, in microseconds.
-    Recorded after the task finishes.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.CachedImagesCount" units="count"
-    expires_after="M80">
-  <obsolete>
-    Removed 05/2019 because it no longer reports. To be superseded by a
-    measurement related to percentage of cache/discardable memory used by image
-    caching.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    The maximum number of images that were cached in the renderer over the
-    lifetime of the image decode cache. This is recorded at the image cache
-    destruction. It is further split up by Software and Gpu rasterization.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.CheckerImagingDecision"
-    enum="CheckerImagingDecision" expires_after="M81">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    The outcome for whether an image could be sucessfully deferred for
-    asynchronous decode in the renderer compositor. If not, the reason for using
-    a synchronous decode. An image which is decoded asynchronously will be
-    checkerboarded on the rasterized tiles until the decode is finished, as
-    opposed to synchronous decodes where the tile rasterization is blocked on
-    the image decode completing.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.CompositorFrame.Quads" units="quads"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019 because the research it was used for is complete.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    The total number of quads in all render passes in a CompositorFrame. This is
-    logged as the CompositorFrame is submitted to its surface.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.DirectlyCompositedImage.AvoidRasterAdjustmentWithTransformTrigger"
-    units="boolean" expires_after="M87">
-  <obsolete>
-    Removed September 2020 because the research it was used for is complete.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records instances of directly composited images that did not need to
-    recalculate raster scale in response to scale changes. The boolean value
-    indicates whether will-change:transform is set or a scale transforms is
-    animating. This metric will be used to determine the impact on raster CPU
-    usage if we were to scope the directly composited images feature.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.DirectlyCompositedImage.RasterScaleDirectlyComposited"
-    units="boolean" expires_after="M87">
-  <obsolete>
-    Removed September 2020 because the research it was used for is complete.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records whether or not a PictureLayerImpl that has a single drawImage paint
-    operation is able to apply directly composited image optimization. See
-    PictureLayerImpl::ShouldDirectlyCompositeImage for more details.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.DirectlyCompositedImage.TileAreaAdded"
-    units="pixels" expires_after="M87">
-  <obsolete>
-    Removed September 2020 because the research it was used for is complete.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records the number of tile pixels added when directly composited image is
-    applied to a layer. If the raster scale is greater than it otherwise would
-    be, the difference in pixels used for tiling the layer is logged in this
-    histogram.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.DirectlyCompositedImage.TileAreaMatches"
-    units="boolean" expires_after="M87">
-  <obsolete>
-    Removed September 2020 because the research it was used for is complete.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records whether or not the chosen raster scale for a directly composited
-    image matches the ideal raster scale. In cases where the scale does not
-    match (i.e. false values for this histogram), either TileAreaAdded or
-    TileAreaSaved will be logged to provide an indication on the effects on
-    memory usage.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.DirectlyCompositedImage.TileAreaSaved"
-    units="pixels" expires_after="M87">
-  <obsolete>
-    Removed September 2020 because the research it was used for is complete.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records the number of tile pixels saved when directly composited image is
-    applied to a layer. If the raster scale is lower than it otherwise would be,
-    the difference in pixels used for tiling the layer is logged in this
-    histogram.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="M80">
-  <obsolete>
-    Removed 05/2016. See Blink.Paint.UpdateTime as a related alternate metric.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when display list recording source is updated (in a
-    renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.DisplayListRecordingSource.UpdateUs"
-    units="microseconds" expires_after="2016-05-10">
-  <obsolete>
-    Removed 05/2016. See Blink.Paint.UpdateTime as a related alternate metric.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a display list, in microseconds.
-    Recorded when display list is updated (in a renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.DrawResult" enum="DrawResult"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    How often the layer compositor successfully submitted content to the display
-    compositor, or what caused an abort. This is reported fairly late in the
-    pipeline, during the final stages of submitting content.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.LCDTextEligiblePixelPercentage" units="%"
-    expires_after="2020-05-08">
-  <obsolete>
-    Replaced by Compositing.Renderer.LCDTextDisallowedReason* on 2020-05-08.
-  </obsolete>
-  <owner>wangxianzhu@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records the percentage of approximate number of pixels covered by text
-    drawing operations that are LCD-text eligible, in that of all text drawing
-    operations. This is recorded when the renderer is idle, at minimum interval
-    of the longer of 1 minute and 500 begin frames for each local frame tree.
-    Note that LCD-text eligible text may rasterize in non-LCD-text mode when
-    e.g. LCD-text is not supported by the font or LCD-text doesn't appreciably
-    improve quality.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.PercentPictureLayersWithTextButLCDTextDisabled"
-    units="%" expires_after="2020-05-01">
-  <obsolete>
-    Removed in 03/2020 because changes in the data are difficult to reason about
-    as the number of layers also tends to change at the same time.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="CompositingLCDTextDisabledCountSuffixes" -->
-
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    The number of PictureLayers in the active tree for each compositor frame
-    that have both text drawing operations and do not permit lcd text. This is
-    logged once per frame, before the frame is drawn (in a renderer process).
-    Suffixed with the count of number of picture layers with text.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.PictureMemoryUsageKb" units="KB"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removal in 03/2020 because it is not very useful.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Total estimated memory used by SkPictures in the layer tree, in kilobytes.
-    Recorded once per frame, before the frame is drawn (in a renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.PicturePile.UpdateInvalidatedAreaPerMs"
-    units="pixels/ms" expires_after="M85">
-  <obsolete>
-    Obsolete since 2015.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Area of invalidated content, in pixels, divided by update (i.e. record), in
-    milliseconds. Recorded when picture pile is updated (in a renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.PicturePile.UpdateUs"
-    units="microseconds" expires_after="M85">
-  <obsolete>
-    Obsolete since 2015.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent updating (i.e. recording) a picture pile, in microseconds.
-    Recorded when picture pile is updated (in a renderer process).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.RasterTask.RasterPixelsPerMs"
-    units="pixels/ms" expires_after="2016-11-29">
-  <obsolete>
-    Removed 11/2016. Increased the max tracking range to accomendate GPU raster,
-    and will require new baskets.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Rasterized area, in pixels, divided by rasterization time, in milliseconds,
-    of a compositor rasterization task. Recorded after the task finishes (in a
-    renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.RasterTask.RasterPixelsPerMs2"
-    units="pixels/ms" expires_after="2019-4-24">
-  <obsolete>
-    Removed 04/2019. Was unused.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Rasterized area, in pixels, divided by rasterization time, in milliseconds,
-    of a compositor rasterization task. Recorded after the task finishes (in a
-    renderer process).
-  </summary>
-</histogram>
-
-<histogram name="Compositing.Renderer.RasterTask.RasterUs" units="microseconds"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2019. Was unused.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Time spent completing a compositor rasterization task, in microseconds.
-    Recorded after the task finishes (in a renderer process).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.RenderPass.AppendQuadData.NumMissingTilesNoImageContent"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 02/2016. We'd learned as much as we could from this metric and it
-    made no sense to keep it around.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    Tracks the number of missing tiles that had some image content in the
-    renderer process.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Renderer.RenderPass.AppendQuadData.NumMissingTilesSomeImageContent"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 02/2016. We'd learned as much as we could from this metric and it
-    made no sense to keep it around.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    Tracks the number of missing tiles that did not have any image content in
-    the renderer process.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RenderPass.AppendQuadData.MaskLayerPercent"
-    units="%" expires_after="2019-02-01">
-  <obsolete>
-    Removed as being no longer useful to track.
-  </obsolete>
-  <owner>enne@chromium.org</owner>
-  <owner>chrishtr@chromium.org</owner>
-  <summary>
-    Percent of layers drawn that frame that are mask layers. A sample is
-    recorded on the first draw per commit.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RenderPass.AppendQuadData.RCMaskArea"
-    units="pixels" expires_after="2019-02-01">
-  <obsolete>
-    Removed as being no longer useful to track.
-  </obsolete>
-  <owner>enne@chromium.org</owner>
-  <owner>chrishtr@chromium.org</owner>
-  <summary>
-    Total visible area of layers drawn that frame that are mask layers and also
-    are simple rounded corner masks. A sample is recorded on the first draw per
-    commit.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RenderPass.AppendQuadData.RCMaskAreaPercent"
-    units="%" expires_after="2019-02-01">
-  <obsolete>
-    Removed as being no longer useful to track.
-  </obsolete>
-  <owner>enne@chromium.org</owner>
-  <owner>chrishtr@chromium.org</owner>
-  <summary>
-    Percent of visible area of layers drawn that frame that are mask layers and
-    also are simple rounded corner masks. A sample is recorded on the first draw
-    per commit.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.RenderPass.AppendQuadData.RCMaskLayerPercent"
-    units="%" expires_after="2019-02-01">
-  <obsolete>
-    Removed as being no longer useful to track.
-  </obsolete>
-  <owner>enne@chromium.org</owner>
-  <owner>chrishtr@chromium.org</owner>
-  <summary>
-    Percent of layers drawn that frame that are mask layers and also are simple
-    rounded corner masks. A sample is recorded on the first draw per commit.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.SurfaceAggregator.LatestInFlightSurface.ManhattanDistanceToPrimary"
-    units="surfaces" expires_after="M80">
-  <obsolete>
-    Removed 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>akaba@chromium.org</owner>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The distance between the latest inflight surface and the primary surface.
-    This is logged for each call to HandleSurfaceQuad().
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceAggregator.SurfaceDrawQuad.MissingSurface"
-    units="quads" expires_after="2018-07-25">
-  <obsolete>
-    Removed 07/2018 in issue 865597 in order to avoid spurious error messages on
-    Viz process crash.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of SurfaceDrawQuads where the surface doesn't exist. This is
-    logged for each call to Aggregate().
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceAggregator.SurfaceDrawQuad.NoActiveFrame"
-    units="quads" expires_after="2018-07-25">
-  <obsolete>
-    Removed 07/2018 in issue 865597 in order to avoid spurious error messages on
-    Viz process crash.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of SurfaceDrawQuads where the surface exists but doesn't have an
-    active CompositorFrame. This is logged for each call to Aggregate().
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.SurfaceAggregator.SurfaceDrawQuad.UsingFallbackSurface"
-    units="quads" expires_after="M80">
-  <obsolete>
-    Removed 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of SurfaceDrawQuads where the primary SurfaceId does not have a
-    corresponding active CompositorFrame and so the fallback surface is used
-    instead. This is logged for each call to Aggregate().
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceAggregator.SurfaceDrawQuad.ValidSurface"
-    units="quads" expires_after="2018-10-16">
-  <obsolete>
-    Removed 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of SurfaceDrawQuads where the surface exists and has an active
-    CompositorFrame. This is logged for each call to Aggregate().
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceDependencyDeadline.DeadlineHit"
-    enum="Boolean" expires_after="2018-10-17">
-  <obsolete>
-    Removed as of 10/2018. This metric didn't end up being useful.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    Tracks whether an activation of a surface was due to due to a deadline or
-    the resolution of dependencies.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceInvariantsViolations" units="violations"
-    expires_after="2018-09-11">
-  <obsolete>
-    Removed as of 2018/09/10 in favor of
-    Compositing.CompositorFrameSinkSupport.SubmitResult.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of times a renderer in this browser session has violated a
-    surface synchronization invariant. This manifests as a skipped frame.
-    Ideally this metric should always report 0, but realistically there are
-    races in the system and this tracks the frequency that we hit these races.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceManager.NumOldTemporaryReferences"
-    units="units" expires_after="2018-01-29">
-  <obsolete>
-    Removed 2018/01/24.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The number of temporary references that have existed for at least 10 seconds
-    and are most likely orphaned. This is logged every 10 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceManager.RemovedTemporaryReference"
-    enum="TemporaryReferenceRemovedReason" expires_after="M81">
-  <obsolete>
-    Expired M81.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>Tracks the reason for removing a temporary reference.</summary>
-</histogram>
-
-<histogram name="Compositing.SurfaceManager.TemporaryReferences"
-    units="references" expires_after="M81">
-  <obsolete>
-    Expired M81.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    Tracks the number of temporary references after each garbage collection
-    operation.
-  </summary>
-</histogram>
-
-<histogram name="CompositorImplAndroid.TearDownDisplayTime" units="ms"
-    expires_after="2019-03-30">
-  <obsolete>
-    Obsolete after 03/2019. For temporary debugging of CompositorImpl hangs.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Tracks the amount of time it takes to synchronously tear down the display
-    when the CompositorImpl becomes invisible or is destroyed. Recorded after
-    display teardown completes in CompositorImpl::
-    TearDownDisplayAndUnregisterRootFrameSink.
-  </summary>
-</histogram>
-
-<histogram name="CompositorLatency.MissedFrame" units="microseconds"
-    expires_after="2020-08-31">
-  <obsolete>
-    Removed on 01/2020. MissedFrame changed to DroppedFrame for more clarity.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Tracks the duration of various stages in the pipeline as a single frame goes
-    through the various stages in the compositor. This is reported for frames
-    that the user did not see: this includes frames that are dropped in various
-    stages inside chromium, or even frames that went through all stages in
-    chromium, but ultimately was not presented to the user.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="CompositorLatency.MissedFrameLatencyIncrease"
-    units="microseconds" expires_after="2020-08-31">
-  <obsolete>
-    Removed on 9/2019. Did not provide enough information about latency.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    The latency increase of an abnormally long activation stage on the
-    multithread thread compositor pipeline when the frame is missed.
-
-    These latency increases are determined by comparing the stage duration to
-    the times from past non-missed frames. These times are also reported to
-    &quot;CompositorLatency.MissedFrame.&lt;StageName&gt;&quot;
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDetector.FromSystem" enum="Boolean"
-    expires_after="2019-03-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether or not the network connectivity info, i.e. validated, is provided by
-    the system. We will use it if it is available from the system. Otherwise, we
-    will do our own http probes to find it out. This UMA will not be recorded if
-    a flag in about:flags is set to bypass this logic to always favor the check
-    by http probes.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDetector.Probe.HttpResponseCode"
-    enum="HttpResponseCode" expires_after="2019-03-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The HTTP response code returned from a HTTP probe for the purpose of
-    checking network connectivity.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDetector.Probe.Result" enum="ProbeResult"
-    expires_after="2019-03-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The result from a HTTP probe for the purpose of checking network
-    connectivity.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDetector.Probe.ValidationTime" units="ms"
-    expires_after="2019-03-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The total duration measuring all the HTTP probes and backoff time taken when
-    the network connectivity is successfully validated.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDetector.Probe.ValidationUrl" enum="ProbeUrlType"
-    expires_after="2019-03-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Records type of url, default or fallback URL, resulting in successful
-    connectivity validation.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDiagnostics.HTTP_LATENCY" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 04/2020. No longer used.
-  </obsolete>
-  <owner>ebeach@google.com</owner>
-  <summary>
-    HTTP latency seen by the Connectivity Diagnostics.
-
-    HTTP latency is computed using the chrome.socket API to make an HTTP GET
-    request to the /generate_204 page of three randomly generated Google
-    hostnames (*-ccd-testing-v4.metric.gstatic.com). The time taken from issuing
-    the HTTP request to receiving a response is clocked in JavaScript and the
-    arithmetic mean of the three times is used as the HTTP latency.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDiagnostics.TestVerdict"
-    enum="ConnectivityDiagnosticsTestVerdict" expires_after="M81">
-  <obsolete>
-    Removed 04/2020. No longer used.
-  </obsolete>
-  <owner>ebeach@google.com</owner>
-  <summary>
-    Connectivity Diagnostics App: Outcome of the connectivity tests.
-  </summary>
-</histogram>
-
-<histogram name="ConnectivityDiagnostics.TimeTaken" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 04/2020. No longer used.
-  </obsolete>
-  <owner>ebeach@google.com</owner>
-  <summary>
-    Connectivity Diagnostics App: Amount of time taken to run each of the
-    connectivity tests.
-  </summary>
-</histogram>
-
-<histogram name="ContentCapture.CaptureOneContentTime" units="microseconds"
-    expires_after="M75">
-  <obsolete>
-    Expired
-  </obsolete>
-  <owner>michaelbai@chromium.org</owner>
-  <summary>The estimated time taken to capture one on-screen content.</summary>
-</histogram>
-
-<histogram name="ContentSettings.DefaultHandlersSetting" enum="ContentSetting"
-    expires_after="2014-07-07">
-  <obsolete>
-    Removed 07/2014 since it is not referenced anywhere in the code.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>The default handler setting at profile open.</summary>
-</histogram>
-
-<histogram name="ContentSettings.DefaultKeygenSetting" enum="ContentSetting"
-    expires_after="2016-12-21">
-  <obsolete>
-    Support for keygen was removed.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    The default setting for using key generation in forms at profile open.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.DefaultMediaStreamSetting"
-    enum="ContentSetting" expires_after="2015-09-24">
-  <obsolete>
-    This setting was deprecated in r322364 and replaced with separate settings
-    for camera and microphone. See
-    ContentSettings.DefaultMediaStreamCameraSetting and
-    ContentSettings.DefaultMediaStreamMicSetting.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>msramek@chromium.org</owner>
-  <summary>The default MediaStream setting at profile open.</summary>
-</histogram>
-
-<histogram name="ContentSettings.DefaultMouseCursorSetting"
-    enum="ContentSetting" expires_after="M85">
-  <obsolete>
-    Removed on 2020-07-07. This histogram is no longer recorded.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>The default mouse cursor setting at profile open.</summary>
-</histogram>
-
-<histogram name="ContentSettings.DefaultPushMessagingSetting"
-    enum="ContentSetting" expires_after="M85">
-  <obsolete>
-    Removed on 2020-07-07. This histogram is no longer recorded.
-  </obsolete>
-  <owner>miguelg@chromium.org</owner>
-  <summary>
-    The default permission setting for push messages at profile open.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.LastSettingParsed" enum="LastSettingParsed"
-    expires_after="2015-10-05">
-  <obsolete>
-    Removed 2015-10-05 in Issue 433475. Histogram was used temorarily for
-    diagnosing crash causes.
-  </obsolete>
-  <owner>scheib@chromium.org</owner>
-  <summary>
-    Numer of results of parsing WebsiteSettingsHandler::last_setting_ success or
-    failure in WebsiteSettingsHandler methods.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.MixedScript"
-    enum="ContentSettingMixedScriptAction" expires_after="M80">
-  <obsolete>
-    Removed 2020-01-06. Histogram had already expired and metrics are no longer
-    required after the mixed content shield removal.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Tracks whether the mixed content shield was shown, and how the user
-    interacted with it.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.NumberOfAllowCookiesExceptions" units="units"
-    expires_after="2018-10-22">
-  <obsolete>
-    Removed Oct 2018 in favor of ContentSettings.Exceptions.cookies.Allow
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <summary>
-    The number of user defined cookies setting exceptions for allowing cookies
-    at browser start.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.NumberOfBlockCookiesExceptions" units="units"
-    expires_after="2018-10-22">
-  <obsolete>
-    Removed Oct 2018 in favor of ContentSettings.Exceptions.cookies.Block
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <summary>
-    The number of user defined cookies setting exceptions for blocking cookies
-    at browser start.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.NumberOfSessionOnlyCookiesExceptions"
-    units="units" expires_after="2018-10-22">
-  <obsolete>
-    Removed Oct 2018 in favor of ContentSettings.Exceptions.cookies.SessionOnly
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <summary>
-    The number of user defined cookies setting exceptions for 'clearing cookies
-    on browser exit' at browser start.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.PermissionActions" enum="PermissionAction"
-    expires_after="2015-11-22">
-  <obsolete>
-    Removed 11/2015 in favor of Permissions.Action.*
-  </obsolete>
-  <owner>miguelg@chromium.org</owner>
-  <summary>
-    Tracks whether a permission was granted, rejected, etc. The suffix of the
-    histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.PermissionActionsInsecureOrigin"
-    enum="PermissionAction" expires_after="2015-11-22">
-  <obsolete>
-    Removed 11/2015 in favor of Permissions.Action.InsecureOrigin.*
-  </obsolete>
-  <owner>miguelg@chromium.org</owner>
-  <summary>
-    Tracks whether a permission was granted, rejected, etc on an insecure
-    origin. The suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.PermissionActionsSecureOrigin"
-    enum="PermissionAction" expires_after="2015-11-22">
-  <obsolete>
-    Removed 11/2015 in favor of Permissions.Action.SecureOrigin.*
-  </obsolete>
-  <owner>miguelg@chromium.org</owner>
-  <summary>
-    Tracks whether a permission was granted, rejected, etc on a secure origin.
-    The suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.Popups.FirstDocumentEngagementTime" units="ms"
-    expires_after="2017-10-02">
-  <obsolete>
-    Removed in favor of ContentSettings.Popups.FirstDocumentEngagementTime2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the total duration a popup WebContents is visible / foregrounded
-    for the duration of its first document load. This time is measured from the
-    first navigation commit to the time either the WebContents is destroyed or
-    when a new navigation commits.
-  </summary>
-</histogram>
-
-<histogram name="ContentSettings.Popups.StrongBlockerActivationPosition"
-    enum="SafeBrowsingActivationPosition" expires_after="M77">
-  <obsolete>
-    Removed in favor of
-    SubresourceFilter.PageLoad.Activation.RedirectPosition2.Enforcement
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>ericrobinson@chromium.org</owner>
-  <summary>
-    For pages that trigger Safe Browsing triggered popup blocker (in warn or
-    enforce modes), records the position in the redirect chain for the page the
-    activation was triggered by. If SubresourceFilterConsiderRedirects is
-    disabled, then always returns &quot;Only navigation&quot;.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.AppLifecycleEvents"
-    enum="AppLifecycleEvent" expires_after="2019-10-01">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.AppLifecycle.Events.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>
-    Android: count of app lifecycle events reported to the Feed library.
-    Recorded as these events occur; e.g. when Chrome is foregrounded,
-    backgrounded, or the user clears cached browsing data.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.Image.FetchResult"
-    enum="FeedImageFetchResult" expires_after="2019-02-13">
-  <obsolete>
-    Removed in favor of CachedImageFetcher.Events.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: Represents success/failure of Feed image loading. Recorded upon
-    each individual image retrieved from the feed_image_cache. Feed v1 only.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.Image.LoadFromCacheTime" units="ms"
-    expires_after="2019-02-13">
-  <obsolete>
-    Removed in favor of CachedImageFetcher.Events.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The time it takes for Feed to load an image from the cache.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.Image.LoadFromNetworkTime" units="ms"
-    expires_after="2019-02-13">
-  <obsolete>
-    Removed in favor of CachedImageFetcher.Events.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The time it takes for Feed to load an image from the network.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.InitialSuccess" enum="BooleanSuccess"
-    expires_after="2019-10-01">
-  <obsolete>
-    Removed 4/2019 in favor of ProtoDB.InitStatus.*.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>
-    Tracks the Feed storage success rate during initial storage.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.LoadKeysSuccess" enum="BooleanSuccess"
-    expires_after="2019-10-01">
-  <obsolete>
-    Removed 4/2019 in favor of ProtoDB.LoadKeysSuccess.*.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>Tracks the Feed storage success rate during load keys.</summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.LoadSuccess" enum="BooleanSuccess"
-    expires_after="2019-10-01">
-  <obsolete>
-    Removed 4/2019 in favor of ProtoDB.LoadEntriesSuccess.*.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>Tracks the Feed storage success rate during load entries.</summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.ManageInterestsOpened" units="index"
-    expires_after="M90">
-  <obsolete>
-    This implementation is incorrect and we are now using
-    NewTabPage.ActionAndroid2 instead. Marked obsolete in 01-2020
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <owner>freedjm@chromium.org</owner>
-  <owner>feed@chromium.org</owner>
-  <summary>
-    The position of a card in the feed from which the user has opened the Manage
-    Interests page. Recorded when the Manage Interest item is clicked in the
-    card menu.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.NetworkRequestStatusCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Network.RequestStatusCode.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The integer status code of network requests made by the feed
-    library's networking host. This code includes both protocol(1xx-5xx) and
-    non-protocol(-xxx) errors. Recorded when a request completes.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.OperationCommitSuccess"
-    enum="BooleanSuccess" expires_after="2019-10-01">
-  <obsolete>
-    Removed 4/2019 in favor of ProtoDB.UpdateSuccess.*.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>
-    Tracks the Feed storage success rate during commit operations.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.RequestSizeKB.Compressed" units="KB"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of
-    ContentSuggestions.Feed.Network.RequestSizeKB.Compressed.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: the size in kb of gzip-compressed requests sent by the Feed's
-    networking host. Recorded when a request is sent.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.ResponseSizeKB" units="KB"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Network.ResponseSizeKB.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: the uncompressed size in KB of responses received by the Feed's
-    networking host. Recorded when a successful response is received.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.TokenCompleted.ContentCount"
-    units="count" expires_after="2020-02-25">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.TokenCompleted.ContentCount2.
-    Removed 03/2019. http://crbug.com/943838
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    How many top level features were in the continuation response, typically
-    clusters. Recorded when the fetch completes successfully.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.Feed.TokenFetchStatus"
-    enum="GoogleServiceAuthError" expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Network.TokenFetchStatus.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: failure reason when attempting to fetch an OAuth token for the
-    feed. Recorded when an artcile fetch completes.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.FetchPendingPlaceholder.VisibleDuration"
-    units="ms" expires_after="2017-10-12">
-  <obsolete>
-    Removed in favor of ContentSuggestions.FetchPendingSpinner.VisibleDuration.
-  </obsolete>
-  <owner>dgn@chromium.org</owner>
-  <owner>ntp-dev+metrics@chromium.org</owner>
-  <summary>
-    Android: How long the content suggestion placeholder is shown. This is
-    tracked based on when the placeholder is enabled in the UI, not how long it
-    is actually visible on screen. Depending on the screen size, the used value
-    could be bigger.
-  </summary>
-</histogram>
-
-<histogram name="ContentSuggestions.FetchPendingSpinner.VisibleDuration"
-    units="ms" expires_after="2019-01-16">
-  <obsolete>
-    Removed in favor of
-    ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration.
-  </obsolete>
-  <owner>dgn@chromium.org</owner>
-  <owner>ntp-dev+metrics@chromium.org</owner>
-  <summary>
-    Android: How long the content suggestion loading spinner is shown. This is
-    tracked based on when the spinner is enabled in the UI, not how long it is
-    actually visible on screen. Depending on the screen size, the used value
-    could be bigger.
-  </summary>
-</histogram>
-
-<histogram name="ContextMenu.DOMElementFetchDuration" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019. iFrame Context Menu feature shipped.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <summary>
-    How long it takes to fetch the details of the DOM element the user is
-    selecting for the context menu. On iOS, JavaScript must be run in order to
-    get the details of the DOM element. If the element is not inside the main
-    frame, latency could be added due to the communication between frames. Only
-    logged on iOS.
-  </summary>
-</histogram>
-
-<histogram base="true" name="ContextMenu.SelectedOption"
-    enum="ContextMenuOption" expires_after="M80">
-  <obsolete>
-    Removed from code as of 5/2019. WARNING: The code emitting this histogram
-    was broken on desktop, and logged many items that should not have been
-    logged at all into bucket 0. The values for bucket 0 are wrong and should
-    not be relied upon. The replacements are ContextMenu.SelectedOptionDesktop,
-    ContextMenu.SelectedOptionAndroid, and ContextMenu.SelectedOptionIOS.
-  </obsolete>
-  <owner>lzbylut@google.com</owner>
-  <summary>
-    The option that the user selected from a context menu. This mis-logged and
-    thus was removed.
-  </summary>
-</histogram>
-
-<histogram name="ContextMenu.UnexpectedFindElementResultHandlerMessage"
-    enum="BooleanHit" expires_after="M77">
-  <obsolete>
-    Removed 06/2019. iFrame Context Menu feature shipped.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <summary>
-    Logged when an unexpected FindElementResultHandler message was received by
-    the application. An unexpected message may be sent by a malicious frame.
-    Only logged on iOS.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.EnabledState" enum="BooleanEnabled"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: Whether contextual suggestions are enabled. Recorded when the
-    enabled state changes. Note that this may be recorded multiple times per
-    session.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.Events"
-    enum="ContextualSuggestions.Event" expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Records each event handled by the Contextual Suggestions backend. Recorded
-    when the event is sent to the backend, typically when a UI or network action
-    is registered. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchErrorCode" enum="NetErrorCodes"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The net::Error status code of contextual suggestion fetches.
-    Recorded when a fetch completes.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchLatencyMilliseconds" units="ms"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>
-    Android: the amount of time taken elapsed between a contextual suggestion
-    fetch starting and ending. Recorded when a fetch is completed.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchRequestProtoSizeKB" units="KB"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The size of the serialized and base64-encoded proto sent to the
-    server when fetching contextual suggestions. Recorded when a fetch is
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchResponseCode"
-    enum="HttpResponseCode" expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The http status code of contextual suggestion fetches. Recorded
-    when a fetch completes.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchResponseNetworkBytes" units="bytes"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M75
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The number of bytes in the response received when a contextual
-    suggestions fetch completes. Recorded when the response is received.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.FetchResponseSizeKB" units="KB"
-    expires_after="2018-06-04">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Android: The size of the response body received when a contextual
-    suggestions fetch completes. Recorded when the response is received.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.PageViewClickLength"
-    enum="ContextualSuggestions.ClickDuration" expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The length of a visit on a page. Reported for HTTP and HTTPS pages
-    provided there was something visible printed to the screen. Selecting a tab
-    or loading a new URL in current tab starts timing a visit. Switching to a
-    different tab, closing the tab or loading a new URL finishes timing and
-    reports the time if the page did a visually non-empty paint or finished
-    loading. Bucketed by short/medium/long.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.PageViewTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The length of a visit on a page. Reported for HTTP and HTTPS pages
-    provided there was something visible printed to the screen. Selecting a tab
-    or loading a new URL in current tab starts timing a visit. Switching to a
-    different tab, closing the tab or loading a new URL finishes timing and
-    reports the time if the page did a visually non-empty paint or finished
-    loading.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.Preference.State" enum="BooleanEnabled"
-    expires_after="M80">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: Whether the user preference for contextual suggestions is enabled.
-    Recorded on cold start and when the user has changed the preference state.
-    Note that this may be recorded multiple times per session.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.ResultsReturnedInOverviewMode"
-    enum="BooleanEnabled" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2019, no longer needed
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: Whether the contextual suggestions results are returned to the
-    UI-layer while the user is in overview mode.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.SuggestionClickPosition.Cluster"
-    units="index" expires_after="2019-05-30">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: The position of the clicked contextual suggestion card within its
-    cluster.
-  </summary>
-</histogram>
-
-<histogram name="ContextualSuggestions.SuggestionClickPosition.Global"
-    units="index" expires_after="2019-05-30">
-  <obsolete>
-    This feature was deprecated in M74
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: The position of the clicked contextual suggestion card within the
-    entire list of suggestions.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.BetweenAccessIntervalMinutes" units="minutes"
-    expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-17 as part of cookie histogram cleanup
-    (https://crbug.com/521135).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Intervals between access time updates for each cookie.</summary>
-</histogram>
-
-<histogram name="Cookie.CookieDeleteEquivalent" enum="CookieDeleteEquivalent"
-    expires_after="2020-05-10">
-  <obsolete>
-    Removed 2019-10-23 as part of cookie histogram cleanup
-    (https://crbug.com/993120).
-  </obsolete>
-  <owner>mkwst@chromium.org</owner>
-  <summary>
-    Record when at attempt is made to delete an equivalent cookie on a set
-    cookie operation and when such a cookie is found and deleted. Also measure
-    when strict secure cookie rules affect this outcome and prevent a cookie
-    from being deleted.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.CookieLineCookieValueValidity" enum="BooleanValid"
-    expires_after="2017-07-14">
-  <obsolete>
-    Removed 2017-07-14 as it demonstrated that making cookie parsing rules
-    stricter was not feasible. See https://crbug.com/638117.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Indicates whether a cookie initialised from a Set-Cookie header value was
-    valid or not. This is only logged after cookies containing control
-    characters have already been rejected, so &quot;Invalid&quot; here means
-    that the cookie contains quotes, commas, backslashes or top-bit-set
-    characters.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.DBSizeInKB" units="KB" expires_after="M81">
-  <obsolete>
-    Removed as of March 9, 2020.
-  </obsolete>
-  <owner>dmikurube@chromium.org</owner>
-  <summary>
-    The size, on disk, of the cookie database as it is being loaded.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.DeletionCause" enum="CookieDeletionCause"
-    expires_after="M80">
-  <obsolete>
-    Removed Jul 2017 for lack of use.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    For each cookie removed from the store, the reason it was removed.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.DomainCount" units="units" expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-17 as part of cookie histogram cleanup
-    (https://crbug.com/521135).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For each domain, number of cookies in that domain (recorded every 10 minutes
-    of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="Cookie.DomainPerEtldp1Count" units="units"
-    expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-17 as part of cookie histogram cleanup
-    (https://crbug.com/521135).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For every top level domain, number of subdomains in that top level domain
-    (recorded every 10 minutes of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="Cookie.Etldp1Count" units="units" expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-17 as part of cookie histogram cleanup
-    (https://crbug.com/521135).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For every top level domain, number of cookies in that domain (recorded every
-    10 minutes of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="Cookie.EvictedLastAccessMinutes" units="minutes"
-    expires_after="M80">
-  <obsolete>
-    Removed Jul 2017 for lack of use.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    For each evicted (not expired) cookie, the amount of time since it was last
-    used
-  </summary>
-</histogram>
-
-<histogram name="Cookie.GetCookieListCompletionTime" units="ms"
-    expires_after="2019-02-20">
-  <obsolete>
-    Removed Feb 2019 as further data collection is no longer necessary.
-  </obsolete>
-  <owner>rockot@google.com</owner>
-  <summary>
-    The length of time between when the network stack receives a request for a
-    cookie list and when it actually responds to the request or abandons it (for
-    e.g. a closed renderer).
-  </summary>
-</histogram>
-
-<histogram name="Cookie.LaxAllowUnsafeCookieIncludedAge" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020. No longer needed because results are expected to be
-    stable.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The age in milliseconds of a cookie that activates the Lax-allow-unsafe
-    intervention. Emitted whenever a cookie is included in a request with an
-    unsafe HTTP method, where the cookie has an unspecified SameSite attribute
-    and is only included because it is new enough to fall under the age
-    threshold for allowing Lax-allow-unsafe.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.NetworkSecurity" enum="CookieNetworkSecurity"
-    expires_after="2020-05-03">
-  <obsolete>
-    Removed 2019-10-31 as part of cookie histogram cleanup
-    (https://crbug.com/993120).
-  </obsolete>
-  <owner>tnagel@chromium.org</owner>
-  <summary>
-    Degree of protection against cookie theft. Recorded for each cookie when
-    setting the `Cookie` header for a request.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.NumberOfLoadedCookies" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-07-03. Cookie.Count measures similar things with different
-    timing.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    This histogram records the total number of cookies loaded from disk,
-    including any cookies that are discarded during loading (for whatever
-    reason).
-  </summary>
-</histogram>
-
-<histogram name="Cookie.ParsedCookieStatus" enum="ParsedCookieStatus"
-    expires_after="2013-09-21">
-  <obsolete>
-    Removed as of 9/2013. Experiment to measure control characters in cookies is
-    finished.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When parsing a cookie, indicates if control characters were present in any
-    of the cookie values and if any of the cookie values were invalid.
-    Specifically, checks that all of the parsed values are valid according to
-    the valid token definition in Section 2.2 of RFC2616 which specifies a token
-    must have no separators (i.e. no characters from the following string,
-    ignoring the starting and ending single quote: '()&lt;&gt;@,;:\&quot;/[]?={}
-    \t') and no control characters.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.ReinstatedCookies" units="seconds"
-    expires_after="2015-08-20">
-  <obsolete>
-    Removed as of 8/2015.
-  </obsolete>
-  <owner>huangs@chromium.org</owner>
-  <summary>
-    The duration in seconds between a cookie getting evicted (due to the number
-    of cookies exceeding a domain limit), and subsequently reinstated.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SameSiteDifferentSchemeRequest"
-    enum="SameSiteCookieContext" expires_after="M90">
-  <obsolete>
-    Removed Apr 2020 as this metric doesn't capture the correct information.
-    https://crbug.com/1066231
-  </obsolete>
-  <owner>bingler@chromium.org</owner>
-  <owner>kaustubhag@chromium.org</owner>
-  <summary>
-    The value of the SameSiteCookieContext if a Lax or Strict cookie is being
-    sent http-to-https or https-to-http for the site-for-cookies to the request.
-    Logged once per cookie sent with the above conditions.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SameSiteDifferentSchemeResponse"
-    enum="SameSiteCookieContext" expires_after="M90">
-  <obsolete>
-    Removed Apr 2020 as this metric doesn't capture the correct information.
-    https://crbug.com/1066231
-  </obsolete>
-  <owner>bingler@chromium.org</owner>
-  <owner>kaustubhag@chromium.org</owner>
-  <summary>
-    The value of the SameSiteCookieContext if a Lax or Strict cookie is being
-    set http-to-https or https-to-http for the site-for-cookies from the
-    response. Logged once per cookie sent with the above conditions.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SameSiteUnspecifiedTooOldToAllowUnsafe" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020. No longer needed because results are expected to be
-    stable.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The age in milliseconds of a cookie that would have activated the
-    Lax-allow-unsafe intervention except for the fact that it is too old.
-    Emitted whenever a cookie is excluded from being sent on a request with an
-    unsafe method, where the cookie has an unspecified SameSite attribute and is
-    too old to fall under the age threshold to allow Lax-allow-unsafe.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SetAttributePairCharsValidity" enum="BooleanValid"
-    expires_after="2013-09-21">
-  <obsolete>
-    Removed as of 9/2013. Experiment to measure control characters in cookies is
-    finished.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates whether a cookie attribute pair was set with both a valid key and
-    a valid attribute value or not. For the key, this implies that it was a
-    valid token as defined in Section 2.2 of RFC2616 which specifies a token
-    must have no separators (i.e. no characters from the following string,
-    ignoring the starting and ending single quote: '()&lt;&gt;@,;:\&quot;/[]?={}
-    \t') and no control characters. For the value, this implies that it
-    contained no control characters and no semicolon.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SetNameValidity" enum="BooleanValid"
-    expires_after="2013-09-21">
-  <obsolete>
-    Removed as of 9/2013. Experiment to measure control characters in cookies is
-    finished.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates whether a cookie name was set with a valid token. A valid token is
-    defined in Section 2.2 of RFC2616 which specifies a token must have no
-    separators (i.e. no characters from the following string, ignoring the
-    starting and ending single quote: '()&lt;&gt;@,;:\&quot;/[]?={} \t') and no
-    control characters.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.SetValueCookieValueValidity" enum="BooleanValid"
-    expires_after="2013-09-21">
-  <obsolete>
-    Removed as of 9/2013. Experiment to measure control characters in cookies is
-    finished.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicates whether a cookie value was valid or invalid when there was an
-    attempt to set it, where a valid value is defined in RFC 6265 as ASCII
-    characters excluding controls, whitspace, comma, semicolon, and backslash.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.Shutdown.NumberOfCookiesDeleted" units="units"
-    expires_after="2015-09-10">
-  <obsolete>
-    Removed as of 9/2015. The associated experiment was flawed.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The number of session cookies deleted on shutdown. This metric is emitted
-    even if no cookies are deleted.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.Shutdown.TimeSpentDeletingCookies" units="ms"
-    expires_after="2015-09-10">
-  <obsolete>
-    Removed as of 9/2015. The associated experiment was flawed.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The amount of time required to delete session cookies on shutdown. This
-    metric is emitted even if no cookies are deleted.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.TimeDatabaseMigrationToV5" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed as of 04/2015. The migration has finished for most users.
-  </obsolete>
-  <summary>The amount of time (ms) to migrate a v4 database to v5.</summary>
-</histogram>
-
-<histogram name="Cookie.TimeDatabaseMigrationToV6" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed as of 04/2015. The migration has finished for most users.
-  </obsolete>
-  <summary>The amount of time (ms) to migrate a v5 database to v6.</summary>
-</histogram>
-
-<histogram name="Cookie.TimeDatabaseMigrationToV7" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed as of 04/2015. The migration has finished for most users.
-  </obsolete>
-  <summary>The amount of time (ms) to migrate a v6 database to v7.</summary>
-</histogram>
-
-<histogram name="Cookie.TimeDatabaseMigrationToV8" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed as of 04/2015. The migration has finished for most users.
-  </obsolete>
-  <summary>The amount of time (ms) to migrate a v7 database to v8.</summary>
-</histogram>
-
-<histogram name="Cookie.TimeGet" units="ms" expires_after="2014-11-20">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time (ms) to get cookies for each URL request.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.TimeInitializeDomainMap" units="ms" expires_after="M77">
-  <obsolete>
-    Removed as part of histogram expiry. See discussion in crbug.com/975202.
-  </obsolete>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    The amount of time (ms) to read and parse the domain map from the cookies
-    database.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.TimeLoadDomains" units="ms" expires_after="M77">
-  <obsolete>
-    Removed as part of histogram expiry. See discussion in crbug.com/975202.
-  </obsolete>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    The amount of time (ms) to read the domain map from the cookies database.
-  </summary>
-</histogram>
-
-<histogram name="Cookie.TimeParseDomains" units="ms" expires_after="M77">
-  <obsolete>
-    Removed as part of histogram expiry. See discussion in crbug.com/975202.
-  </obsolete>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    The amount of time (ms) to parse the domains already loaded from the cookies
-    database and put them in the domain map.
-  </summary>
-</histogram>
-
-<histogram name="Cookie{Age}{CookieConnectionType}{CookieSiteAffinity}"
-    units="days" expires_after="M82">
-  <obsolete>
-    Removed 2019-10-31 as part of cookie histogram cleanup
-    (https://crbug.com/993120).
-  </obsolete>
-  <owner>mkwst@chromium.org</owner>
-  <owner>tnagel@chromium.org</owner>
-  <summary>
-    Records the age (in days) of {Age} cookie delivered along with a request.
-    Recorded when setting the `Cookie` header for a given request.
-    {CookieConnectionType} {CookieSiteAffinity}
-  </summary>
-  <token key="Age">
-    <variant name=".AgeFor" summary="the oldest"/>
-    <variant name=".AllAgesFor" summary="all"/>
-  </token>
-  <token key="CookieConnectionType">
-    <variant name="NonSecure" summary="For non-secure,"/>
-    <variant name="Secure" summary="For secure,"/>
-  </token>
-  <token key="CookieSiteAffinity">
-    <variant name="CrossSiteRequest" summary="cross-site requests."/>
-    <variant name="SameSiteRequest" summary="same-site requests."/>
-  </token>
-</histogram>
-
-<histogram name="CrashReport.BreakpadCrashDumpOutcome" enum="DumpOutcome"
-    expires_after="2016-04-27">
-  <obsolete>
-    Removed as of 04/2016 as CrashPad does not implement this.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Reports the result of an attempt to report a crash dump via Breakpad.
-    Success indicates only that the out-of-process crash reporter succesfully
-    generated a dump. The success or failure of the eventual upload is not
-    measured. This stability metric is logged from the first Chrome launch
-    post-dump.
-  </summary>
-</histogram>
-
-<histogram name="CrashReport.BreakpadDumpWithoutCrashOutcome"
-    enum="DumpOutcome" expires_after="2016-04-27">
-  <obsolete>
-    Removed as of 04/2016 as CrashPad does not implement this.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Reports the result of an attempt to report a dump via Breakpad without
-    crashing. Success indicates only that the out-of-process crash reporter
-    succesfully generated a dump. The success or failure of the eventual upload
-    is not measured. This stability metric is logged from the first Chrome
-    launch post-dump.
-  </summary>
-</histogram>
-
-<histogram name="CrashReport.CrashBackgroundUploadDelay" units="ms"
-    expires_after="2018-11-05">
-  <obsolete>
-    Removed as of 03/2018 when Chrome for iOS stopped uploading crash dumps in
-    the background.
-  </obsolete>
-  <owner>olivierrobin@chromium.org</owner>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    Time delta between when the crash took place and when the crash was uploaded
-    by the app as a background task. Only logged on iOS.
-  </summary>
-</histogram>
-
-<histogram
-    name="CrashReport.DumpWithoutCrashingHandler.FromInitSharedMemoryIfNeeded"
-    enum="CrashHandler" expires_after="M86">
-  <obsolete>
-    07/2020: Investigation complete.
-  </obsolete>
-  <owner>iby@chromium.org</owner>
-  <owner>cros-telemetry@google.com</owner>
-  <summary>
-    Which crash handler (Breakpad or Crashpad) is handling
-    ProducerClient::InitSharedMemoryIfNeeded()'s attempt to do a
-    DumpWithoutCrashing. Investigating why Breakpad never seems to generate
-    InitSharedMemoryIfNeeded reports on some ChromeOS devices.
-  </summary>
-</histogram>
-
-<histogram
-    name="CrashReport.DumpWithoutCrashingResult.FromInitSharedMemoryIfNeeded"
-    enum="BooleanSuccess" expires_after="M86">
-  <obsolete>
-    06/2020: Removed in favor of
-    CrashReport.DumpWithoutCrashingResult.FromInitSharedMemoryIfNeeded2.
-  </obsolete>
-  <owner>iby@chromium.org</owner>
-  <owner>cros-telemetry@google.com</owner>
-  <summary>
-    Did the attempt to dump without crashing in
-    ProducerClient::InitSharedMemoryIfNeeded() succeed or fail? Investigating
-    why Breakpad never seems to generate InitSharedMemoryIfNeeded reports on
-    some ChromeOS devices.
-  </summary>
-</histogram>
-
-<histogram
-    name="CrashReport.DumpWithoutCrashingResult.FromInitSharedMemoryIfNeeded2"
-    enum="DumpWithoutCrashingResult" expires_after="M86">
-  <obsolete>
-    07/2020: Investigation complete.
-  </obsolete>
-  <owner>iby@chromium.org</owner>
-  <owner>cros-telemetry@google.com</owner>
-  <summary>
-    Did the attempt to dump without crashing in
-    ProducerClient::InitSharedMemoryIfNeeded() succeed or fail? Investigating
-    why Breakpad never seems to generate InitSharedMemoryIfNeeded reports on
-    some ChromeOS devices.
-  </summary>
-</histogram>
-
-<histogram name="CrashReport.PendingReportsOnBackgroundWakeUp" units="units"
-    expires_after="2018-11-05">
-  <obsolete>
-    Removed as of 03/2018 when Chrome for iOS stopped uploading crash dumps in
-    the background.
-  </obsolete>
-  <owner>olivierrobin@chromium.org</owner>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    The number of crash reports present when the app wakes up as a background
-    task to upload crash reports. Only logged on iOS.
-  </summary>
-</histogram>
-
-<histogram name="CrashReport.PermanentUploadFailure" enum="BooleanHit"
-    expires_after="2017-02-01">
-  <obsolete>
-    Removed 01/2017 in Issue 680162 with the removal of Kasko.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Counts crash reports that the Kasko crash reporter fails to upload and hands
-    off to Chrome. Kasko stores the failed reports in a location specified by
-    Chrome. Chrome records this metric when it detects new minidump files in
-    that location. Currently the reports are discarded, but they could
-    eventually be uploaded via the Chrome network stack.
-  </summary>
-</histogram>
-
-<histogram name="Cros.ClickOnShelf" enum="CrosShelfClickTarget"
-    expires_after="2013-12-13">
-  <obsolete>
-    Removed as of 12/2013. Default pinned apps trial is finished.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Chrome OS shelf clicks.</summary>
-</histogram>
-
-<histogram name="Crostini.DiskImageSize" units="GiB" expires_after="2019-11-20">
-  <obsolete>
-    Removed 10/2019 because it was never used.
-  </obsolete>
-  <owner>sidereal@google.com</owner>
-  <owner>nverne@chromium.org</owner>
-  <summary>
-    The maximum space allowed for a VM disk image, as set at install time. This
-    is recorded each time a disk image is successfully created.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceActivityGetter.AsyncTaskResult.ClientAppMetadataFetch"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async ClientAppMetadata retrieval needed for the
-    device activity getter. Recorded when the async callback is invoked or when
-    the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceActivityGetter.ExecutionTime.ClientAppMetadataFetch"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ClientAppMetadata retrieval needed
-    for the device activity getter. Recorded when the async callback is invoked
-    or when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceManager.AsyncTaskResult.ClientAppMetadataFetch"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async ClientAppMetadata retrieval during the
-    CryptAuth v2 DeviceSync flow. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceManager.ExecutionTime.ClientAppMetadataFetch"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the ClientAppMetadataFetch during the
-    CryptAuth v2 DeviceSync flow. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceNotifier.AsyncTaskResult.ClientAppMetadataFetch"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async ClientAppMetadata retrieval for the
-    CryptAuth device notifier. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceNotifier.ExecutionTime.ClientAppMetadataFetch"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ClientAppMetadata retrieval for the
-    CryptAuth device notifier. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.DeviceSyncer.ExecutionTime.ShareGroupPrivateKey"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-01-02 because metric was never used.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ShareGroupPrivateKey API call during
-    the CryptAuth v2 DeviceSync flow. Recorded when the async callback is
-    invoked or when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.FeatureStatusSetter.AsyncTaskResult.ClientAppMetadataFetch"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async ClientAppMetadata retrieval for the
-    CryptAuth feature status setter. Recorded when the async callback is invoked
-    or when the call times out.
-  </summary>
-</histogram>
-
-<histogram
-    name="CryptAuth.DeviceSyncV2.FeatureStatusSetter.ExecutionTime.ClientAppMetadataFetch"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ClientAppMetadata retrieval for the
-    CryptAuth feature status setter. Recorded when the async callback is invoked
-    or when the call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.AsyncTaskResult.ClientAppMetadataFetch"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async ClientAppMetadata retrieval during the
-    CryptAuth v2 Enrollment flow. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.AsyncTaskResult.GcmRegistration"
-    enum="CryptAuthAsyncTaskResult" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2019-12-11 in favor of
-    CryptAuth.EnrollmentV2.GcmRegistration.Success because the timeout was
-    removed.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the result of the async GCM registration call during the CryptAuth
-    v2 Enrollment flow. Recorded when the async callback is invoked or when the
-    call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.ExecutionTime.ClientAppMetadataFetch"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2019-09-12 in favor of
-    CryptAuth.EnrollmentV2.ExecutionTime.ClientAppMetadataFetch2 because too
-    many results were reaching the max time limit.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ClientAppMetadata retrieval during
-    the CryptAuth v2 Enrollment flow. Recorded when the async callback is
-    invoked or when the call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.ExecutionTime.ClientAppMetadataFetch2"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. ClientAppMetadata now fetched in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async ClientAppMetadata retrieval during
-    the CryptAuth v2 Enrollment flow. Recorded when the async callback is
-    invoked or when the call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.ExecutionTime.GcmRegistration"
-    units="ms" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2019-12-11 in favor of
-    CryptAuth.EnrollmentV2.GcmRegistration.AttemptTime because too many results
-    were reaching the max time limit.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async GCM registration call during the
-    CryptAuth v2 Enrollment flow. Recorded when the async callback is invoked or
-    when the call times out.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.GcmRegistration.AttemptTime" units="ms"
-    expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. GCM registration now occurs in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the execution time of the async GCM registration call during the
-    CryptAuth v2 Enrollment flow. Recorded when the async callback is invoked.
-  </summary>
-</histogram>
-
-<histogram name="CryptAuth.EnrollmentV2.GcmRegistration.Success"
-    units="boolean" expires_after="2021-02-02">
-  <obsolete>
-    Removed 2020-07-29. GCM registration now occurs in DeviceSync service.
-  </obsolete>
-  <owner>nohle@chromium.org</owner>
-  <owner>better-together-dev@google.com</owner>
-  <summary>
-    Records the success or failure of the async GCM registration call during the
-    CryptAuth v2 Enrollment flow. Recorded when the async callback is invoked.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.FreedGCacheDiskSpaceInMb" units="MB"
-    expires_after="2018-05-01">
-  <obsolete>
-    Removed 05/2018 in favor of Cryptohome.GCache.FreedDiskSpaceInMb.
-  </obsolete>
-  <owner>oka@chromium.org</owner>
-  <summary>
-    The amount of drive cache (MB) which was evicted by cryptohome due to
-    shortage of remaining disk space.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.FreeDiskSpaceTotalTime" units="ms"
-    expires_after="M90">
-  <obsolete>
-    Replaced by Cryptohome.FreeDiskSpaceTotalTime2 in M81.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Being replaced by Cryptohome.FreeDiskSpaceTotalTime2
-
-    In low disk space scenarios, Cryptohome performs a lot of disk space
-    operations to erase data. This is a number of milliseconds taken to perform
-    a cleanup. Reported only if longer than 5 ms.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.InstallAttributesUsage"
-    enum="InstallAttributesUsageEvent" expires_after="2020-07-13">
-  <obsolete>
-    Retired in M81.
-  </obsolete>
-  <owner>vsavu@google.com</owner>
-  <owner>igorcov@chromium.org</owner>
-  <summary>
-    Records the result of using the install_attributes.pb cache. This is logged
-    at each device boot.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.InstallAttributesValidation"
-    enum="InstallAttributesValidationEvent" expires_after="2020-07-13">
-  <obsolete>
-    Retired in M81.
-  </obsolete>
-  <owner>vsavu@google.com</owner>
-  <owner>igorcov@chromium.org</owner>
-  <summary>
-    Records the result of validating install_attributes.pb. This is logged at
-    each device boot.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.TimeToMountAsync" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019 as it is not used since crrev.com/c/1393048
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    The amount of time (ms) for Chrome OS cryptohome to mount the encrypted home
-    directory asynchronously.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.TimeToMountGuestSync" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it is not used since crrev.com/c/1183895 (8/2018).
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    The amount of time (ms) for Chrome OS cryptohome to mount the encrypted
-    guest home directory synchronously.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.TimeToMountSync" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it hasn't been reported since around crrev.com/185598
-    (~2014) and has been completely removed in crrev.com/c/1183895 (6/2020).
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    The amount of time (ms) for Chrome OS cryptohome to mount the encrypted home
-    directory synchronously.
-  </summary>
-</histogram>
-
-<histogram name="Cryptohome.TimeToTakeTpmOwnership" units="ms"
-    expires_after="2022-03-20">
-  <obsolete>
-    Removed 04/2022 as it is not used since crrev.com/c/2637147 (02/2021)
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    The amount of time (ms) for Chrome OS cryptohome daemon to take ownership of
-    the TPM.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.CreateActivityDelegateTime"
-    units="ms" expires_after="2020-02-29">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Time to create an activity delegate for a custom tabs dynamic module.
-    Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.CreatePackageContextTime" units="ms"
-    expires_after="2020-02-29">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Time to create the package context for a custom tabs dynamic module. Android
-    only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.DestructionReason"
-    enum="CustomTabsDynamicModuleDestructionReason" expires_after="2020-01-26">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Possible reasons for destroying a custom tabs dynamic module. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.EntryPointInitTime" units="ms"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>amalova@chromium.org</owner>
-  <summary>
-    Time to initialize the entry point class for a custom tabs dynamic module.
-    Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.EntryPointLoadClassTime" units="ms"
-    expires_after="2020-02-29">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Time to load the entry point class for a custom tabs dynamic module. Android
-    only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.EntryPointNewInstanceTime" units="ms"
-    expires_after="2020-02-29">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Time to instantiate the entry point class for a custom tabs dynamic module.
-    Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.LoadResult"
-    enum="CustomTabsDynamicModuleLoadResult" expires_after="2020-02-29">
-  <obsolete>
-    Removed in February 2020
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Possible results when loading a custom tabs dynamic module. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.ProportionalSet.OnModuleDestroy"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed in October 2019
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The proportional set size (PSS) of code pages occupied by a custom tabs
-    dynamic module. Recorded before the module destruction. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.ProportionalSet.OnModuleLoad"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed in October 2019
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The proportional set size (PSS) of code pages occupied by a custom tabs
-    dynamic module. Recorded when a module is loaded. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.ResidentSet.OnModuleDestroy"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed in October 2019
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The resident set size (RSS) of code pages occupied by a custom tabs dynamic
-    module. Recorded before the module destruction. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.DynamicModule.ResidentSet.OnModuleLoad" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Removed in October 2019
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The resident set size (RSS) of code pages occupied by a custom tabs dynamic
-    module. Recorded when a module is loaded. Android only.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.Experimental.Visible" enum="VisibleTab"
-    expires_after="2021-04-15">
-  <obsolete>
-    Finished experiment and replaced by CustomTabs.Visible in September 2020
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Experimental version of CustomTabs.Visible that is logged on a log start,
-    rather than log end, to check if this results in more logs being tagged.
-    Starting with M84 this is is also recorded for webapps/WebAPKs. Filter the
-    platform for just CCT/TWA data.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.IntentToFirstCommitNavigationTime" units="ms"
-    expires_after="2016-10-13">
-  <obsolete>
-    Removed 10/2016 in favor of .IntentToFirstCommitNavigationTime2.*.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Time between the intent arrival in Chrome and the first navigation commit,
-    if the navigation is successful. Similar in principle to
-    Startup.FirstCommitNavigationTime.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.IntentToFirstCommitNavigationTime2" units="ms"
-    expires_after="2017-09-04">
-  <obsolete>
-    Removed 2017-08 in favor of CustomTabs.IntentToFirstNavigationStartTime.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Time between the intent arrival to a Custom Tab and the navigation start
-    (note: not the navigation commit, as the name suggests). Recorded when the
-    page has finished loading. Non-&quot;Herb&quot; mode.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.NonDefaultSessionPrerenderMatched"
-    enum="BooleanMatched" expires_after="2018-04-12">
-  <obsolete>
-    Removed 4/2018 when prerender was removed from Custom Tabs.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Android: When there is a prerender for a session with non-default
-    parameters, whether the prerender was matched when navigating.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.PrerenderSessionUsesDefaultParameters"
-    enum="BooleanDefault" expires_after="2018-04-12">
-  <obsolete>
-    Removed 4/2018 when prerender was removed from Custom Tabs.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Android: When prerendering a URL for Custom Tabs, whether the client session
-    uses the default parameters.
-  </summary>
-</histogram>
-
-<histogram name="CustomTabs.SpareWebContents.Status"
-    enum="SpareWebContentsStatus" expires_after="2019-03-28">
-  <obsolete>
-    Replaced by CustomTabs.SpareWebContents.Status2 as of 03/2019.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Android: When a spare WebContents is created from Custom Tabs, record
-    creation, and whether it was used, killed or destroyed. Creation is recorded
-    to get the &quot;abandoned&quot; case, that is when Chrome is killed before
-    the renderer.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.AutoLoFiAccuracy"
-    enum="DataReductionProxyAutoLoFiAccuracy" expires_after="2016-04-19">
-  <obsolete>
-    Replaced by DataReductionProxy.LoFi.Accuracy.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts the accuracy of estimated network quality when using Lo-Fi. Counters
-    are incremented when a main frame URL request is handled by Data Reduction
-    Proxy and session was in Auto Lo-Fi enabled field trial.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.AutoLoFiRequestHeaderState"
-    enum="DataReductionProxyAutoLoFiRequestHeaderState"
-    expires_after="2017-08-24">
-  <obsolete>
-    Removed as of 8/2017, per server-directed preview decision.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts the changes in the state of Lo-Fi request header (q=low) being added
-    to the Chrome proxy request header. Counters are incremented when a main
-    frame URL request is handled by Data Reduction Proxy and session was in Auto
-    Lo-Fi enabled field trial.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BlockTypeFallback"
-    enum="DataReductionProxyBypassType" expires_after="M81">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to block the fallback
-    configuration of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BlockTypePrimary"
-    enum="DataReductionProxyBypassType" expires_after="M81">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to block the primary configuration
-    of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassInfoFallback"
-    enum="DataReductionProxyBypassEventType_Deprecated"
-    expires_after="2014-07-01">
-  <obsolete>
-    Removed as of 6/2014, replaced by DataReductionProxy.BypassTypeFallback.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to bypass the fallback
-    configuration of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassInfoPrimary"
-    enum="DataReductionProxyBypassEventType_Deprecated"
-    expires_after="2014-07-01">
-  <obsolete>
-    Removed as of 6/2014, replaced by DataReductionProxy.BypassTypePrimary.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to bypass the primary
-    configuration of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassOnNetworkErrorFallback"
-    enum="NetErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed as of March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Positive net error code that caused the fallback data reduction proxy to be
-    bypassed and put on the proxy retry list. Called after a failure to connect
-    or resolve a host name.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassOnNetworkErrorPrimary"
-    enum="NetErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed as of March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Positive net error code that caused the primary data reduction proxy to be
-    bypassed and put on the proxy retry list. Called after a failure to connect
-    or resolve a host name.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassTypeFallback"
-    enum="DataReductionProxyBypassType" expires_after="M81">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to bypass the fallback
-    configuration of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.BypassTypePrimary"
-    enum="DataReductionProxyBypassType" expires_after="M81">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts various events that trigger Chrome to bypass the primary
-    configuration of the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.CaptivePortalDetected.Platform"
-    enum="BooleanPresent" expires_after="2018-04-18">
-  <obsolete>
-    Removed 2018/04.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records if the platform detected that a captive portal is present on the
-    current network. Recorded at the time of Chrome startup and on IP change
-    event. Recorded only for users that have data saver enabled.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigFetchLostBytesCL" units="units"
-    expires_after="2016-02-10">
-  <obsolete>
-    Removed in Feb. 2016
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body. This is the actual number of bytes received,
-    which usually agrees with but is not necessarily the same as the size
-    specified by the Content-Length header. Only recorded if the request is sent
-    while a simulated Data Reduction Proxy configuration fetch is taking place.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigFetchLostBytesDiff" units="units"
-    expires_after="2016-02-10">
-  <obsolete>
-    Removed in Feb. 2016
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The difference between the size specified in the X-Original-Content-Length
-    header and the size of the response body. Only recorded if the request is
-    sent while a simulated Data Reduction Proxy configuration fetch is taking
-    place. Only positive values are logged, so if X-Original-Content-Length is
-    not specified or if it equals or exceeds the content length, it is not
-    logged.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigFetchLostBytesOCL" units="units"
-    expires_after="2016-02-10">
-  <obsolete>
-    Removed in Feb. 2016
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size specified in the X-Original-Content-Length header. If this header is
-    not present in the response, the size of the response body is used. Only
-    recorded if the request is sent while a simulated Data Reduction Proxy
-    configuration fetch is taking place.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigService.AuthExpiredSessionKey"
-    enum="DataReductionProxyConfigServiceAuthExpiredSessionKey"
-    expires_after="M83">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    On receiving an authentication failure from the data reduction proxy,
-    records whether the session key used in the request matches the current
-    session key.
-
-    Recorded every time Chrome receives an authentication failure from the data
-    saver proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigService.AuthFailure.LatencyPenalty"
-    units="ms" expires_after="M83">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Time from when the request starts to the time when the auth failure is
-    received from the data saver proxy.
-
-    Recorded every time an auth failure is received from the data saver proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigService.PersistedConfigIsExpired"
-    enum="BooleanExpired" expires_after="2018-04-18">
-  <obsolete>
-    Removed 2018/04.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records whether the persisted client config for data saver proxies read from
-    the disk at the time of Chrome startup was expired or not. Recorded once at
-    the time of Chrome startup.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ConfigService.SentVariationHeaders"
-    enum="BooleanSent" expires_after="2018-10-09">
-  <obsolete>
-    Removed in October 2018
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Records whether the client config client sent variation headers in the
-    config request.
-  </summary>
-</histogram>
-
-<histogram
-    name="DataReductionProxy.DaysSinceSavingsCleared.NegativeSystemClock"
-    units="days" expires_after="M78">
-  <obsolete>
-    Obsoleted in M-79.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the number of days since the data reduction savings were cleared
-    because the system clock moved back by more than 1 day. Recorded at Chrome
-    startup if data reduction proxy is enabled, and if the data reduction proxy
-    savings were cleared in some previous Chrome session.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperDetectionHTTP" units="units"
-    expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    For each carrier, the total number of HTTP responses that have been checked
-    for tampering. This assumes the data reduction proxy injected fingerprints
-    have not been tampered with. Only the data reduction proxy responses with
-    200 OK response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperDetectionHTTPS" units="units"
-    expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    For each carrier, the total number of HTTPS responses that have been checked
-    for tampering. This assumes the data reduction proxy injected fingerprints
-    have not been tampered with. Only the data reduction proxy responses with
-    200 OK response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTP"
-    units="units" expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    For each carrier, the total number of HTTP responses that passed the tamper
-    detection. This assumes the data reduction proxy injected fingerprints have
-    not been tampered with. Only the data reduction proxy responses with 200 OK
-    response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperDetectionPassHTTPS"
-    units="units" expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    For each carrier, the total number of HTTPs responses that passed the tamper
-    detection. This assumes the data reduction proxy injected fingerprints have
-    not been tampered with. Only the data reduction proxy responses with 200 OK
-    response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperedHTTP" units="units"
-    expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of HTTP responses that some part (specified by suffix name)
-    have been tampered with. This assumes the data reduction proxy injected
-    fingerprints have not been tampered with. Only the data reduction proxy
-    responses with 200 OK response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.HeaderTamperedHTTPS" units="units"
-    expires_after="2017-07-06">
-  <obsolete>
-    Removed in June 2017
-  </obsolete>
-  <owner>xingx@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of HTTPS responses that some part (specified by suffix
-    name) have been tampered with. This assumes the data reduction proxy
-    injected fingerprints have not been tampered with. Only the data reduction
-    proxy responses with 200 OK response code are checked.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.InvalidResponseHeadersReceived.NetError"
-    enum="NetErrorCodes" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Net error codes observed when invalid response headers were received from
-    data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.LoFi.Accuracy"
-    enum="DataReductionProxyAutoLoFiAccuracy" expires_after="2017-08-24">
-  <obsolete>
-    Removed as of 8/2017, per server-directed preview decision.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the accuracy of estimated network quality when using Lo-Fi. Network
-    quality predicted at the time of navigation start is compared with the
-    network quality observed during the specified time interval following the
-    start of the navigation. This metric is recorded only when the session is in
-    Lo-Fi enabled field trial.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.LoFi.ImplicitOptOutAction"
-    enum="DataReductionProxyLoFiImplicitOptOutAction"
-    expires_after="2017-10-16">
-  <obsolete>
-    Obsolete as of October 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    Counts of Lo-Fi implicit opt out actions. If the user chooses to &quot;Load
-    image&quot; for k pages in a session, LoFi is disabled for the remainder of
-    that session. If Lo-Fi is disabled for j consecutive sessions, Lo-Fi is
-    disabled for that user until the next implicit opt out epoch, which may be
-    in a later session, or never. k and j default to 3 and are assigned via the
-    DataReductionProxyLoFi field trial.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.LoFi.SessionState"
-    enum="DataReductionProxyLoFiSessionState" expires_after="2017-10-16">
-  <obsolete>
-    Removed as of October 2017 per transition to blacklist.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    Tracks Lo-Fi usage at the granularity of browser sessions. Counts for each
-    session if Lo-Fi was used or not. In the case where Lo-Fi was not used,
-    records if it was because the network quality was always good or because the
-    user had implicitly opted out. The session where a user permanently opts out
-    is counted in the Lo-Fi used bucket.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.LoFi.TransformationType"
-    enum="DataReductionProxyLoFiTransformationType" expires_after="M77">
-  <obsolete>
-    Functionality removed in M77.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts of pageloads that received or requested, but did not receive, various
-    Lo-Fi lite page transformations. Recorded when a lite page is requested or
-    received through Data compression proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.LoFi.UIAction"
-    enum="DataReductionProxyLoFiUIAction" expires_after="2016-09-14">
-  <obsolete>
-    Removed as of 9/2016, replaced by Previews.ContextMenuAction.LoFi.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    User interactions with the Lo-Fi snackbar and context menu option. These
-    include:
-
-    Displays and clicks on the &quot;Load images&quot; snackbar. Displays and
-    clicks on the &quot;Load image&quot; and &quot;Load images&quot;context menu
-    options. Count of pages where the user has clicked &quot;Load image&quot; at
-    least once.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.MissingViaHeader.Bytes" units="bytes"
-    expires_after="2018-04-17">
-  <obsolete>
-    Removed 2018/04.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>sclittle@chromium.org</owner>
-  <summary>
-    Counts the response bytes of responses that Chrome expected to come through
-    a data reduction proxy and have the data reduction proxy via header, but
-    where the data reduction proxy via header was missing. Note that this does
-    not include responses that were bypassed.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.MissingViaHeader.ResponseCode"
-    units="units" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>sclittle@chromium.org</owner>
-  <summary>
-    Counts the different HTTP response codes of responses that Chrome expected
-    to come through a data reduction proxy and have the data reduction proxy via
-    header, but where the data reduction proxy via header was missing.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.NetworkChangeEvents"
-    enum="DataReductionProxyNetworkChangeEvent" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Counts the number of times various events occur when the data reduction
-    proxy is enabled and the IP address of the client changes.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.NetworkProperties.CacheHit"
-    enum="BooleanCacheHit" expires_after="M81">
-  <obsolete>
-    Obsoleted in April 2020
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records if the network properties of a network were found in the cache or
-    not. Recorded every time there is a change in the connection type.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Pingback.Attempted" enum="BooleanAttempted"
-    expires_after="M81">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Counts the number of times that pageload metrics were queued to be attempted
-    or not queued based on the reporting fraction. Recorded once per pageload.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Pingback.CrashAction"
-    enum="DataReductionProxyPingbackCrashAction" expires_after="M81">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Counts various actions related to crash detection in the pingback client.
-    This is recorded only when a renderer crash occurs on a Data Reduction Proxy
-    page load.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Pingback.Succeeded" enum="BooleanSuccess"
-    expires_after="M81">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Counts the number of times that a batched pingback request succeeded or
-    failed at being sent to the server. Recorded everytime a pingback request is
-    attempted.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ProbeURL"
-    enum="DataReductionProxyProbeURLFetchResult" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Counts various outcomes of requesting the data reduction proxy's probe URL.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ProbeURLNetError" enum="NetErrorCodes"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Reports the type of network error when the data reduction proxy probe fails
-    due to a network error.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.PromoAction"
-    enum="DataReductionProxyPromoAction" expires_after="2015-04-01">
-  <obsolete>
-    Removed as of 3/2015, replaced by DataReductionProxy.UIAction.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Samples which method was used by the user to dismiss the proxy promo. This
-    is sampled when the promo leaves view, with the sampled value depending on
-    which of four possible controls the user used.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Protocol.AcceptTransform"
-    enum="DataReductionProxyProtocolAcceptTransformEvent"
-    expires_after="2019-12-12">
-  <obsolete>
-    Obsolete as of 10/2018.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the sending of accepted transform headers to the data reduction
-    proxy and also receiving transforms and policies from the data reduction
-    proxy. Recorded on a per page request basis and also on a per image resource
-    request basis for empty-image transforms. Headers for both types of requests
-    (pages and resources) are recorded here for convenience in viewing in a
-    single histogram. In general, the separate groups of request/receive buckets
-    for either page or resource types can be compared.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Protocol.NotAcceptingTransform"
-    enum="DataReductionProxyProtocolNotAcceptingTransformReason"
-    expires_after="2018-10-03">
-  <obsolete>
-    Obsolete as of 10/2018.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the reason that a page request is not accepting proxy server
-    transforms. Recorded on a per page request basis.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ProxySchemeUsed"
-    enum="DataReductionProxyProxySchemeUsed" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the scheme of the data reduction proxy server. Recorded for every
-    request that is fetched successfully through a data reduction proxy server.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Quic.DefaultAlternativeProxy"
-    enum="DataReductionProxyQuicDefaultAlternativeProxy"
-    expires_after="2017-05-10">
-  <obsolete>
-    Removed in 5/2017, since the experiment to use default QUIC alternative
-    proxy was deprecated.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Status of the availability of valid alternative data reduction proxy
-    servers. This metric is recorded only when data reduction proxy delegate is
-    queried for the value of the supported alternative proxy server.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Quic.OnAlternativeProxyBroken"
-    units="count" expires_after="2018-01-20">
-  <obsolete>
-    As of M66 this has been superceded by Net.AlternativeProxyFailed.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Number of times an alternative QUIC proxy was marked as broken.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.Quic.ProxyStatus"
-    enum="DataReductionProxyQuicProxyStatus" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the result of the attempt to use a data reduction proxy that
-    supports QUIC. The metric is logged for every request for which the resolved
-    proxy is a data reduction HTTPS proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.RequestCompletionErrorCodes"
-    enum="NetErrorCodes" expires_after="2016-03-11">
-  <obsolete>
-    Removed in 2/2016, since it didn't get recorded for many kinds of error
-    codes when it should have been recorded, and
-    Net.HttpRequestCompletionErrorCodes is a good enough replacement when
-    filtering for clients with the Data Reduction Proxy enabled.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Reports the different network errors that requests that try to use the data
-    reduction proxy are completing with, including OK and ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.RequestCompletionErrorCodes.MainFrame"
-    enum="NetErrorCodes" expires_after="2016-03-11">
-  <obsolete>
-    Removed in 2/2016, since it didn't get recorded for many kinds of error
-    codes when it should have been recorded, and
-    Net.HttpRequestCompletionErrorCodes is a good enough replacement when
-    filtering for clients with the Data Reduction Proxy enabled.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Reports the different network errors that main frame resource requests that
-    try to use the data reduction proxy are completing with, including OK and
-    ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ResourceContentType"
-    enum="DataReductionProxyResourceContentType" expires_after="2018-04-18">
-  <obsolete>
-    Removed 2018/04.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Content type of the resource determined by data reduction proxy. Used for
-    determining the data reduction proxy that should be used for fetching the
-    resource. Logged once per resource for only the resources that are eligible
-    for fetching by data reduction proxies.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.ResponseProxyServerStatus"
-    enum="DataReductionProxyResponseProxyServerStatus" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Reports the state of the proxy server field in the response seen by the Data
-    Reduction Proxy bypass logic.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.SavingsCleared.NegativeSystemClock"
-    enum="BooleanCleared" expires_after="2018-04-25">
-  <obsolete>
-    Replaced by DataReductionProxy.SavingsCleared.Reason in M68.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records if the data reduction savings were cleared because the system clock
-    moved back by more than 1 day. Recorded at Chrome startup if the data
-    reduction proxy is enabled.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.SecureProxyCheck.Latency" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Time from when the Data Reduction Proxy secure proxy check starts until it
-    completes.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.SettingsConversion"
-    enum="DataReductionProxySettingsConversion" expires_after="2015-04-01">
-  <obsolete>
-    Removed as of 3/2015, replaced by DataReductionProxy.UIAction.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Samples of user interactions with the ON/OFF switch in the settings menu for
-    reducing data usage. Only the setting changes between entering the reducing
-    data usage setting menu and leaving the menu will be sampled. So if a user
-    enters the menu with OFF and leaves it with OFF, it is counted as one OFF to
-    OFF conversion regardless of how many times they toggle the ON/OFF switch.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.SuccessfulRequestCompletionCounts"
-    units="count" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Count of the number of requests that were successfully fetched via data
-    reduction proxy. The bucket represents the index of the data reduction proxy
-    in the data reduction proxy list.
-  </summary>
-</histogram>
-
-<histogram
-    name="DataReductionProxy.SuccessfulRequestCompletionCounts.MainFrame"
-    units="count" expires_after="M81">
-  <obsolete>
-    Obsoleted March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Count of the number of main frame requests that were successfully fetched
-    via data reduction proxy. The bucket represents the index of the data
-    reduction proxy in the data reduction proxy list.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.TimeToFirstDataSaverRequest" units="ms"
-    expires_after="2018-04-18">
-  <obsolete>
-    Removed 2018/04.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the time duration between the data saver initialization and the
-    first HTTP request that is resolved through the data saver proxy. On IP
-    address changes, time duration between the IP address change event and the
-    next subsequent HTTP request that resolves through the data saver proxy is
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.UserViewedSavingsPercent" units="%"
-    expires_after="2018-08-06">
-  <obsolete>
-    Removed March 2018. Percent no longer displayed.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data savings displayed to users. Computed over the last 30
-    days. Recorded when the user views the data savings in the UI.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.FetchAttemptEvent"
-    enum="DataReductionProxyWarmupURLFetchAttemptEvent" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>Records the result of an attempt to fetch the warmup URL.</summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess"
-    units="count" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the total number of warmup URL (i.e., the probe URL) fetch attempts
-    that were made before the warmup URL was successfully fetched.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.FetchInitiated" units="count"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Number of times the data reduction proxy warm up URL was fetched.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.FetchSuccessful"
-    enum="BooleanSuccess" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>Whether the warm up URL was fetched succesfully.</summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.HasViaHeader" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Whether the response headers of the warm up URL had Chrome Proxy via header.
-    Recorded only when non-null response headers were available when the fetch
-    of warm up URL concludes.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.HttpResponseCode"
-    enum="HttpResponseCode" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP response code of the warm up URL. Set to 1 when HTTP response headers
-    were unavailable.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.NetError" enum="NetErrorCodes"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Net error codes observed when the fetch of the warm up URL concludes.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURL.ProxySchemeUsed"
-    enum="DataReductionProxyProxySchemeUsed" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Proxy scheme of the proxy server via which the warm up URL was fetched.
-    Recorded only when non-null response headers were available when the fetch
-    of warm up URL concludes.
-  </summary>
-</histogram>
-
-<histogram name="DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch"
-    enum="BooleanSuccess" expires_after="M81">
-  <obsolete>
-    Obsoleted in March 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Whether the warmup (or probe) URL was successfully fetched over a data saver
-    proxy.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.MatchingRulesCount.Invalid" units="count"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The number of invalid matching rules fetched from the platform external data
-    use observer. A sample is recorded everytime fetch done callback is called.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.MatchingRulesCount.Valid" units="count"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The number of valid matching rules fetched from the platform external data
-    use observer. A sample is recorded everytime fetch done callback is called.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.PageLoadSequence" units="Count"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the sequence number of the page load within a data usage tracking
-    session. Logged for each navigation in the tracking session.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.Perf.MatchingRuleFirstFetchDuration" units="ms"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The time taken in milliseconds to fetch the matching rules for the first
-    time from the platform external data use observer. This measures the
-    duration from the start time of Chromium to the time the rules are returned
-    asynchronously. A sample is recorded when the first fetch done callback is
-    called.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.Perf.ReportSubmissionDuration" units="ms"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The time taken in milliseconds to submit the data use reports to the
-    platform external data use observer. This measures the duration from the
-    time of report submission to the time report submission done asynchronous
-    callback is received. A sample is recorded everytime report submission done
-    callback is received.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.Perf.URLRegexMatchDuration" units="ms"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The time taken in milliseconds for a regular expression to parse an URL. A
-    sample is recorded evertime regular expression parsing is done for an URL.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.ReportSubmission.Bytes" units="bytes"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Count of bytes in the data use reports that were intended to be submitted to
-    the platform external data use observer.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.ReportSubmissionResult"
-    enum="DataUsageReportSubmissionResult" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>Result of data usage report submission.</summary>
-</histogram>
-
-<histogram name="DataUsage.TabModel.ExpiredActiveTabEntryRemovalDuration"
-    units="ms" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The duration from the start time of a tab entry's latest data usage tracking
-    session, till when the entry is expired and removed from the tab model. This
-    is for tab entries that are still actively tracking data usage for a
-    Chromium tab.
-
-    Tab model maintains the tab entries, each pertaining to tracking sessions of
-    a single Chromium tab. These entries are considered expired after some
-    duration and can be removed from the tab model after that. The sample is
-    taken when an expired tab entry still tracking data usage is removed from
-    the tab model.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TabModel.ExpiredInactiveTabEntryRemovalDuration"
-    units="ms" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The duration from the end time of a tab entry's latest data usage tracking
-    session, till when the entry is expired and removed from the tab model. This
-    is for tab entries that are not actively tracking data usage for a Chromium
-    tab.
-
-    Tab model maintains the tab entries, each pertaining to tracking sessions of
-    a single Chromium tab. These entries are considered expired after some
-    duration and can be removed from the tab model after that. The sample is
-    taken when an expired inactive tab entry is removed from the tab model.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TabModel.OldInactiveSessionRemovalDuration"
-    units="ms" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The duration from the end time of a data usage tracking session, till when
-    the tracking session is removed from the tab model. This is for old tracking
-    sessions that are not actively tracking data usage.
-
-    Tab model maintains a limited number of tracking sessions per Chromium tab.
-    When this limit is reached oldest inactive tracking sessions are removed.
-    The sample is taken when an old inactive tracking session of a tab is
-    removed from the tab model.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TabModel.TrackingSessionLifetime" units="ms"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The lifetime of a data usage tracking session of a Chromium tab, maintained
-    by the tab model. This is the duration between the time tracking started due
-    to an entry event and ended with an exit event. The sample is taken when the
-    data usage tracking session ends.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TabModel.UnexpiredTabEntryRemovalDuration"
-    units="ms" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The duration from the end time (start time, if still active) of a tab
-    entry's latest data usage tracking session, till when the entry is removed
-    from the tab model. This is for tab entries that are not expired yet, and
-    removed from the tab model.
-
-    Tab model maintains a limited number of entries, each pertaining to tracking
-    sessions of a single Chromium tab. When this limit is reached even after
-    removing expired tab entries, then oldest unexpired tab entries are removed.
-    The sample is taken when an unexpired tab entry is removed from the tab
-    model.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TrackingSessionEndReason"
-    enum="DataUsageTrackingSessionEndReason" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The reason for ending the data usage tracking session. Logged when the
-    tracking session ends.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.TrackingSessionStartReason"
-    enum="DataUsageTrackingSessionStartReason" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The reason for starting the data usage tracking session. Logged when the
-    tracking session was started.
-  </summary>
-</histogram>
-
-<histogram name="DataUsage.UIAction" enum="DataUsageUIAction"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    Samples of user interactions with the Data Use snackbar and dialog. These
-    samples include:
-
-    Displays of the snackbar that indicates the start of data use tracking and
-    clicks on its &quot;More&quot; button. Displays of snackbar that indicates
-    the end of data use tracking and clicks on its &quot;More&quot; button.
-    Displays of the dialog that indicates the end of data use tracking and the
-    user interactions with it, which include: clicking &quot;Continue&quot;,
-    clicking &quot;Cancel&quot;, clicking &quot;Learn more&quot;, and opting out
-    of seeing the dialog. If the user opts out of seeing the dialog, they will
-    see the snackbar that indicates the end of data use tracking from then on.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.AllServices.Background" enum="DataUseServices"
-    expires_after="2017-10-23">
-  <obsolete>
-    Replaced by KB version in October, 2017.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total background data use of Chrome's services broken down by service
-    name. It is logged only in Android when the URLRequest of a service
-    completes.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.AllServices.BackgroundKB" enum="DataUseServices"
-    expires_after="2018-06-30">
-  <obsolete>
-    Replaced by DataUse.AllServicesKB.* version in June, 2018.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total background data use of Chrome's services broken down by service
-    name. It is logged only in Android when the URLRequest of a service
-    completes.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.ContentType.Services" enum="DataUseContentType"
-    expires_after="2018-05-23">
-  <obsolete>
-    Removed 2018/05. Bytes are logged to DataUse.ContentType.ServicesKB.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Data use of Chrome services traffic by different content types. Recorded
-    when network bytes are received by Chrome.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.ContentType.ServicesKB" enum="DataUseContentType"
-    expires_after="M77">
-  <obsolete>
-    Removed since not needed.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Data use of Chrome services traffic by different content types. Recorded in
-    KB when network bytes are received by Chrome.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.ContentType.UserTraffic" enum="DataUseContentType"
-    expires_after="2017-05-04">
-  <obsolete>
-    Removed 2017/04. Bytes are logged to DataUse.ContentType.UserTrafficKB.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Data use of user traffic by different content types. Recorded when network
-    bytes are received by Chrome.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.MessageSize" units="bytes" expires_after="2018-02-28">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The request and response size of the messages exchanged by a service. It is
-    logged when the URLRequest of a service is completed. The service name is
-    added as a suffix to this histogram name.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.MessageSize.AllServices" enum="DataUseServices"
-    expires_after="2018-06-30">
-  <obsolete>
-    Replaced by DataUse.AllServicesKB.* version in June, 2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The request and response size of the messages exchanged by all the services.
-    Whenever a URLRequest of a service is completed, the number of exchanged
-    bytes is logged in this histogram. The buckets in this histogram are
-    services, so it makes it possible to compare the use of different services
-    in different conditions. Different conditions are added as suffixes to this
-    histogram. If the OS is not Android all the requests are considered
-    foreground.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.PageTransition.UserTraffic"
-    enum="DataUsePageTransition" expires_after="2018-05-23">
-  <obsolete>
-    Removed 2018/05. Bytes are logged to DataUse.PageTransition.UserTrafficKB.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Data use of user traffic by different core page transition types. Recorded
-    when the URL request finishes.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.Sync.Download.Bytes" enum="SyncModelTypes"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of downloaded bytes of different data types in Sync service for
-    received updates. It is updated when an update message is received from sync
-    server.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.Sync.Download.Count" enum="SyncModelTypes"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of downloaded entities of different data types in Sync service for
-    received updates. It is updated when an update message is received from sync
-    server.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.Sync.ProgressMarker.Bytes" enum="SyncModelTypes"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of downloaded bytes of ProgressMarker of different data types in Sync
-    service for received updates. It is updated when an update message is
-    received from sync server.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.Sync.Upload.Bytes" enum="SyncModelTypes"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of uploaded bytes of different data types in Sync service for sent
-    commits. Updated when a commit message is sent to sync server.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.Sync.Upload.Count" enum="SyncModelTypes"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of uploaded entities of different data types in Sync service for sent
-    commits. Updated when a commit message is sent to sync server.
-  </summary>
-</histogram>
-
-<histogram name="DataUse.TrafficSize.System" units="bytes" expires_after="M80">
-  <obsolete>
-    Removed in M74 and replaced by DataUse.AllServicesKB.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total data use of Chrome's services. There is no ResourceRequestInfo
-    attached to these requests. If the OS is not Android all the requests are
-    considered foreground.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowser.AsyncSetAsDefault.Duration" units="ms"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. Renamed to DefaultBrowser.SetDefaultAsyncDuration.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    How long it took to set Chrome as the default browser asynchronously in
-    Windows 10+. The duration is recorded only on Success, Failure, Abandoned
-    and Retry result codes.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowser.AsyncSetAsDefault.Result"
-    enum="DefaultBrowserAsyncAttemptResult" expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. Renamed to DefaultBrowser.SetDefaultResult.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The count of how many times users were successfully able to set Chrome as
-    the default browser asynchronously in Windows 10+.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowser.SetDefaultAsyncDuration" units="ms"
-    expires_after="2016-03-09">
-  <obsolete>
-    Removed 2016/03. The async set-as-default experiments are finished.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    How long it took to set Chrome as the default browser asynchronously in
-    Windows 10+. The duration is recorded only on Success, Failure, Abandoned,
-    Retry and NoErrorsNotDefault result codes.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowser.SetDefaultResult"
-    enum="SetDefaultAttemptResult" expires_after="2016-03-22">
-  <obsolete>
-    Removed 2016/03.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The outcome of an attempt to set Chrome as the user's default browser.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowserWarning.DontSetAsDefault" enum="BooleanHit"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. The same information is available as the value Failure in
-    DefaultBrowser.SetDefaultResult.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    In the make-default infobar, the user explicitly declined to set Chrome as
-    default. Or, on OSes requiring the SetAsDefaultUI, the user explicitly chose
-    another browser as default from the interactive UI. TODO(gab): Split the
-    interactive signal into a separate histogram.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowserWarning.Ignored" enum="BooleanHit"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. Renamed to DefaultBrowser.InfoBar.UserInteraction.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The user ignored the make-default infobar (it was eventually dismissed along
-    with its associated web content without the user interacting with it).
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowserWarning.SetAsDefault" enum="BooleanHit"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. Renamed to DefaultBrowser.Infobar.UserInteraction. There is
-    no longer a distinction between interactive or not.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    In the make-default infobar, the user clicked a button making Chrome the
-    default.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowserWarning.SetAsDefaultUI" enum="BooleanHit"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. Renamed to DefaultBrowser.Infobar.UserInteraction. There is
-    no longer a distinction between interactive or not.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Same as SetAsDefault, but in Win8+ (resulting in interactive UI instead of
-    automatic takeover). Successes == these reports minus reports for
-    DefaultBrowserWarning.SetAsDefaultUIFailed and some
-    DefaultBrowserWarning.DontSetAsDefault. TODO(gab): Improve reporting here.
-  </summary>
-</histogram>
-
-<histogram name="DefaultBrowserWarning.SetAsDefaultUIFailed" enum="BooleanHit"
-    expires_after="2015-11-19">
-  <obsolete>
-    Removed 2015/11. The same information is available as the value Failure in
-    DefaultBrowser.SetDefaultResult.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The user dismissed the interactive SetAsDefaultUI without making an explicit
-    choice (or the UI failed to come up for another reason).
-  </summary>
-</histogram>
-
-<histogram name="DefaultProtocolClient.SetDefaultResult"
-    enum="SetDefaultAttemptResult" expires_after="2016-03-22">
-  <obsolete>
-    Removed 2016/03.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The outcome of an attempt to set Chrome as the user's default client for a
-    protocol.
-  </summary>
-</histogram>
-
-<histogram name="DelayNavigationThrottle.Delay.Actual" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The actual delay added to main frame navigations by DelayNavigationThrottle.
-  </summary>
-</histogram>
-
-<histogram name="DelayNavigationThrottle.Delay.Delta" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The absolute delta between the specified and actual delays added to main
-    frame navigations by DelayNavigationThrottle.
-  </summary>
-</histogram>
-
-<histogram name="DelayNavigationThrottle.Delay.Specified" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The specified delay added to main frame navigations by
-    DelayNavigationThrottle.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.DismissalReason"
-    enum="DesktopIOSPromotionDismissalReason" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    The dimissal reason of the desktop to iOS promotion entry point.
-    DismissalReason will be prefixed by the entry point promotion name that the
-    user interacted with.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.ImpressionFromEntryPoint"
-    enum="DesktopIOSPromotionEntryPoint" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    The type of the desktop to iOS promotion that was shown to the user. This
-    will be logged every time the user sees the desktop to iOS promotion.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.IOSSigninReason"
-    enum="DesktopIOSPromotionEntryPoint" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    [IOS] For users who sign-in on Chrome for iOS, log the type of the desktop
-    iOS promotions that was shown to the user. Only recorded if the user has
-    seen at least one desktop iOS promotion in the last 7 days and is signing
-    into chrome on iOS. The last promotion entry point that sent an SMS (if any)
-    is logged as DesktopIOSPromotion.SMSSent.IOSSigninReason; all other
-    promotions that the user has seen are logged as
-    DesktopIOSPromotion.NoSMS.IOSSigninReason.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.OAuthTokenCompletion"
-    enum="BooleanSuccess" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <summary>
-    Whether getting the OAuth token was successful for a desktop to iOS
-    promotion query.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.OAuthTokenResponseCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <summary>
-    HTTP Response code returned by the server when trying to fetch the OAuth
-    token for a desktop ios promotion query.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.QueryPhoneNumberSucceeded"
-    enum="BooleanSuccess" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    Whether the SMS service api called from the desktop to iOS promotion
-    returned a phone number or failed. This phone number is presented to the
-    user so they know that Chrome will send the SMS to this number.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.SendSMSSucceeded" enum="BooleanSuccess"
-    expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    Whether the SMS service api initiated SMS sending successfully from the
-    desktop to iOS promotion.
-  </summary>
-</histogram>
-
-<histogram name="DesktopIOSPromotion.SMSToSigninTime" units="hours"
-    expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    [IOS] The difference between the client time of triggering the SMS action on
-    a specific entry point promotion on desktop and client time of signing in
-    Chrome iOS app. This will only be logged if at least one promotion was shown
-    to the user on the last 7 days and if at least one SMS was sent. If multiple
-    SMSs were sent (at any time), it uses the time from the most recently sent
-    one. If the is negative due to bad clock on one of the clients it will be
-    logged as 0. SMSToSigninTime will be prefixed by the entry point promotion
-    name that was responsible for the SMS sending.
-  </summary>
-</histogram>
-
-<histogram base="true" name="DesktopIOSPromotion.VariationSigninReason"
-    units="units" expires_after="2018-11-05">
-  <obsolete>
-    Removed 11/2018 in issue 894963.
-  </obsolete>
-  <owner>mrefaat@chromium.org</owner>
-  <summary>
-    [IOS] For users who sign-in on Chrome for iOS, log which variation of the
-    desktop iOS promotions was shown to the user. The variation number is a
-    unique identifier that is set for each group on the DesktopIOSPromotion
-    study, and will be only recorded if the user has seen at least one desktop
-    iOS promotion in the last 7 days and is signing into Chrome on iOS. The last
-    variation that sent an SMS (if any) is logged as
-    DesktopIOSPromotion.SMSSent.VariationSigninReason. If no SMS was sent, then
-    the last variation the user has seen is logged as
-    DesktopIOSPromotion.NoSMS.VariationSigninReason.
-  </summary>
-</histogram>
-
-<histogram name="DevTools.CSSGridSettings" enum="DevtoolsGridSettingChanged"
-    expires_after="M87">
-  <obsolete>
-    Removed 08/2020 because the set of settings has changed. Superseded by
-    DevTools.CSSGridSettings2.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <owner>brgoddar@microsoft.com</owner>
-  <owner>leo.lee@microsoft.com</owner>
-  <summary>
-    DevTools settings for CSS grid recorded on launch of the DevTools.
-  </summary>
-</histogram>
-
-<histogram name="DevTools.GridSettingChanged" enum="DevtoolsGridSettingChanged"
-    expires_after="M87">
-  <obsolete>
-    Removed in July 2020, M86. This histogram was fired multiple times per
-    setting change and is unusable. Replaced with DevTools.CSSGridSettings.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <owner>brgoddar@microsoft.com</owner>
-  <owner>leo.lee@microsoft.com</owner>
-  <summary>
-    Recorded when a DevTools CSS Grid overlay display setting is changed.
-    Actually fires once for each overlay target active when the setting is
-    changed.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Recovery.ConflictingDlls" enum="DiagnosticsResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    TBD - Not run automatically yet, so this is just a placeholder for future
-    metrics collection. Any samples collected here represent users running
-    diagnostics manually.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Recovery.OperatingSystem" enum="DiagnosticsResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    TBD - Not run automatically yet, so this is just a placeholder for future
-    metrics collection. Any samples collected here represent users running
-    diagnostics manually.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Recovery.SQLiteIntegrityAppCache"
-    enum="DiagnosticsResult" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityAppCache recovery
-    step that runs on recovery startups. The recovery step attempts to guarantee
-    the SQLiteIntegrityAppCache test, which checks the integrity of the App
-    Cache database, would pass on the next startup.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Recovery.SQLiteIntegrityArchivedHistory"
-    enum="DiagnosticsResult" expires_after="2015-09-10">
-  <obsolete>
-    Removed as of Jun 2014: we no longer have an archived database.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityArchivedHistory
-    recovery step that runs on recovery startups. The recovery step attempts to
-    guarantee the SQLiteIntegrityArchivedHistory test, which checks the
-    integrity of the Archived History database, would pass on the next startup.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Recovery.SQLiteIntegrityThumbnails"
-    enum="DiagnosticsResult" expires_after="2016-06-05">
-  <obsolete>
-    Removed 05/2016 in Issue 617226; has not been valid for many years.
-  </obsolete>
-  <owner>shess@chromium.org</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityThumbnails
-    recovery step that runs on recovery startups. The recovery step attempts to
-    guarantee the SQLiteIntegrityThumbnails test, which checks the integrity of
-    the Thumbnails database, would pass on the next startup.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Test.ConflictingDlls" enum="DiagnosticsResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    TBD - Not run automatically yet, so this is just a placeholder for future
-    metrics collection. Any samples collected here represent users running
-    diagnostics manually.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Test.OperatingSystem" enum="DiagnosticsResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    TBD - Not run automatically yet, so this is just a placeholder for future
-    metrics collection. Any samples collected here represent users running
-    diagnostics manually.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Test.SQLiteIntegrityAppCache"
-    enum="DiagnosticsResult" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityAppCache test that
-    runs on recovery startups. The test checks the integrity of the App Cache
-    database.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Test.SQLiteIntegrityArchivedHistory"
-    enum="DiagnosticsResult" expires_after="2015-09-10">
-  <obsolete>
-    Removed as of Jun 2014: we no longer have an archived database.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityArchivedHistory
-    test that runs on recovery startups. The test checks the integrity of the
-    Archived History database.
-  </summary>
-</histogram>
-
-<histogram name="Diagnostics.Test.SQLiteIntegrityThumbnails"
-    enum="DiagnosticsResult" expires_after="2016-06-05">
-  <obsolete>
-    Removed 05/2016 in Issue 617226; has not been valid for many years.
-  </obsolete>
-  <owner>shess@chromium.org</owner>
-  <summary>
-    Shows the success and failure rates of the SQLiteIntegrityThumbnails test
-    that runs on recovery startups. The test checks the integrity of the
-    Thumbnails database.
-  </summary>
-</histogram>
-
-<histogram name="Dialog.Delegate.Creation" enum="BooleanCreated"
-    expires_after="2017-05-14">
-  <obsolete>
-    Removed, use Dialog.DialogDelegate.Create.
-  </obsolete>
-  <owner>pdyson@chromium.org</owner>
-  <summary>
-    Counts the number times dialog boxes are created using DialogDelegate.
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.BuildCache.File.Size" units="KB"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <summary>
-    Reports size of font cache file. This is reported every time we rebuild font
-    cache.
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.BuildCache.Ignored" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <owner>layout-dev@chromium.org</owner>
-  <summary>
-    Reports the total number of fonts that will be ignored while building static
-    font cache due to size limitation. During cache building phase if our logic
-    suggests that we need to put more than 70% of font file contents into cache
-    file then we don't cache that particular font file. These ignored font files
-    are directly picked up from system fonts folder during Direct Write cache
-    building process. Our end goal is to minimize costly open and close
-    operations on font files in system folder.
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.Ignored" units="units" expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <summary>
-    Reports the total number of fonts that will be ignored while loading a
-    custom font collection. With current criteria fonts that are not in
-    system-font location will be ignored.
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.Loaded" units="units" expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <summary>
-    Reports the total number of fonts to be loaded through a custom font
-    collection. This actually reports total font entries from registry excluding
-    font entries that point to non-system location.
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.LoadTime" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <summary>
-    Measures the total time spent in loading a custom font collection in
-    non-cache-file mode. We load system fonts as a custom font collection to
-    avoid any interaction with windows font cache service from sandboxed
-    renderer process. Please note that windows font cache services is different
-    from our cache file approach (later referred here as cache-file mode).
-  </summary>
-</histogram>
-
-<histogram name="DirectWrite.Fonts.LoadTime.Cached" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2016, as the code path containing this metric was deprecated in
-    favor of DWriteFontProxyImpl.
-  </obsolete>
-  <owner>drott@chromium.org</owner>
-  <summary>
-    Measures the total time spent in loading a custom font collection in
-    cache-file mode. We load system fonts as a custom font collection to avoid
-    any interaction with windows font cache service from sandboxed renderer
-    process. Please note that windows font cache services is different from our
-    cache file approach (later referred here as cache-file mode)
-  </summary>
-</histogram>
-
-<histogram name="DisabledExtension.ExtensionWipedStatus" enum="BooleanWiped"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Whether an extension has been wiped out.</summary>
-</histogram>
-
-<histogram name="DisabledExtension.SideloadWipeoutCount" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How many external extensions get wiped out as a result of the Sideload
-    Wipeout one-time initiative.
-  </summary>
-</histogram>
-
-<histogram name="DisabledExtension.SideloadWipeoutNeeded" enum="BooleanSuccess"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether any extension got wiped out as a result of the Sideload Wipeout
-    one-time initiative.
-  </summary>
-</histogram>
-
-<histogram name="DisabledExtension.UserSelection" enum="SideloadWipeoutBubble"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The user selection in the Sideload Wipeout bubble, grouped by the
-    UmaWipeoutHistogramOptions enum.
-  </summary>
-</histogram>
-
-<histogram name="Discarding.Urgent.NumAliveTabs" units="tabs"
-    expires_after="M77">
-  <obsolete>
-    Removed 08/2019. Use Discarding.ReloadsPer10Minutes to assess whether tabs
-    are discarded too often.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Number of tabs that are not pending load or discarded when an urgent discard
-    request is received.
-  </summary>
-</histogram>
-
-<histogram name="Discarding.Urgent.TimeSinceLastUrgent" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 08/2019. Use Discarding.ReloadsPer10Minutes to assess whether tabs
-    are discarded too often.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time between two consecutive urgent discard requests. Urgent discards are
-    undesirable; it is better to reduce memory usage before the system is in a
-    bad state.
-  </summary>
-</histogram>
-
-<histogram name="Discarding.Urgent.TimeSinceStartup" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 08/2019. Use Discarding.ReloadsPer10Minutes to assess whether tabs
-    are discarded too often.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time between Chrome startup and the first urgent discard request. Urgent
-    discards are undesirable; it is better to reduce memory usage before the
-    system is in a bad state.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.CertIo" enum="CertificateChainPosition"
-    expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Records information about DiskBasedCertCache operations with respect to
-    certificate chain positions. Zero indicates that a certificate is root, one
-    indicates that it is the first intermediate certificate, etc.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.CertIoCacheResult" enum="CacheResult"
-    expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Records the outcome of requests to retrieve certificates from the disk
-    cache.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.CertIoReadSuccessLeaf"
-    enum="BooleanSuccess" expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Whether or not the leaf certificate of a certificate chain was successfuly
-    read from the disk cache.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.CertIoWriteSuccessLeaf"
-    enum="BooleanSuccess" expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Whether or not the leaf certificate of a certificate chain was successfully
-    written to the disk cache.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.ChainReadTime" units="ms"
-    expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Measures the wall clock time spent reading a certificate chain. The starting
-    time is when the read command is issued, and the ending time is when all of
-    the certificates in the chain have been read into memory.
-  </summary>
-</histogram>
-
-<histogram name="DiskBasedCertCache.ChainWriteTime" units="ms"
-    expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. CertCacheTrial has been removed.
-    https://crbug.com/522312
-  </obsolete>
-  <owner>brandonsalmon@chromium.org</owner>
-  <summary>
-    Measures the wall clock time spent writing a certificate chain to disk. The
-    starting time is when the write command is issued, and the ending time is
-    when all the certificates in the chain have been written to disk.
-  </summary>
-</histogram>
-
-<histogram name="DiskCache.0.FilesAge" units="hours" expires_after="M77">
-  <obsolete>
-    Removed 2019-07-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The age of the cache's files (wall time).</summary>
-</histogram>
-
-<histogram name="DiskCache.0.MaxSize" units="MB" expires_after="M80">
-  <obsolete>
-    Removed. See MaxSize2.
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>The maximum size of the cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.0.Size" units="MB" expires_after="M80">
-  <obsolete>
-    Removed. See Size2
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>The current size of the cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.2.FilesAge" units="hours" expires_after="M80">
-  <obsolete>
-    Removed 2019-07-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The age of the cache's files (wall time). Media-specific cache.
-  </summary>
-</histogram>
-
-<histogram name="DiskCache.2.MaxSize" units="MB" expires_after="M80">
-  <obsolete>
-    Removed. See MaxSize2.
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>The maximum size of the cache. Media-specific cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.2.Size" units="MB" expires_after="M80">
-  <obsolete>
-    Removed. See Size2.
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>The current size of the cache. Media-specific cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.3.FilesAge" units="hours" expires_after="2018-08-30">
-  <obsolete>
-    Removed 2019-07-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The age of the cache's files (wall time). AppCache.</summary>
-</histogram>
-
-<histogram name="DiskCache.3.MaxSize" units="MB" expires_after="M80">
-  <obsolete>
-    Removed. See MaxSize2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The maximum size of the cache. AppCache.</summary>
-</histogram>
-
-<histogram name="DiskCache.4.FilesAge" units="hours" expires_after="2018-08-30">
-  <obsolete>
-    Removed 2019-07-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The age of the cache's files (wall time). ShaderCache.</summary>
-</histogram>
-
-<histogram name="DiskCache.Entries" units="entries" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of entries currently stored on the cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.HitRatio" units="?" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The current hit ratio. It is only measured after the cache is full, so
-    evictions are taking place, and data from the fill-up period is not
-    considered.
-  </summary>
-</histogram>
-
-<histogram name="DiskCache.LargeEntriesRatio" units="%" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Percentage of the cache used by entries of more than 512 KB. It is only
-    measured after the cache is full, so evictions are taking place.
-  </summary>
-</histogram>
-
-<histogram name="DiskCache.MaxSize" units="MB" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The maximum size of the cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.Size" units="MB" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The current size of the cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.SizeStats2" units="KB" expires_after="M77">
-  <obsolete>
-    Removed 2019-07-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The size distribution of data stored in the HTTP cache.</summary>
-</histogram>
-
-<histogram name="DiskCache.TotalIOTime" units="ms" expires_after="2013-04-11">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time it takes to perform a payload IO operation, for the regular
-    disk cache.
-  </summary>
-</histogram>
-
-<histogram name="DiskCache.TrimAge" units="hours" expires_after="M80">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time that an entry lives in the cache without being accessed until it is
-    finally purged.
-  </summary>
-</histogram>
-
-<histogram base="true" name="DisplayScheduler.ShouldNotDraw" enum="Boolean"
-    expires_after="2018-11-21">
-  <obsolete>
-    Removed after M72 since no longer needed.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="DisplaySchedulerNotDrawReason" -->
-
-  <owner>sadrul@chromium.org</owner>
-  <owner>sunnyps@chromium.org</owner>
-  <summary>
-    The reason for the DisplayScheduler to abort a draw operation.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptCancelled" units="units" expires_after="2018-07-03">
-  <obsolete>
-    Removed as of 6/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The attempt which completed after the job was already cancelled.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptDiscarded" units="units" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The attempt which completed after the job was already cancelled OR the
-    attempt that has finished after host resolution was already completed by an
-    earlier attempt.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptFailDuration" units="ms" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in OS resolutions for actual navigations. These
-    attempts which completed after the job was already canceled OR after the job
-    was already completed by an earlier attempt. Note that cached resolutions
-    may provide low (0ms?) resolution times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptFailure" units="units" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>The attempt that has not resolved the host successfully.</summary>
-</histogram>
-
-<histogram name="DNS.AttemptFirstFailure" units="units"
-    expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The attempt that resolved the host first and the resolution was not
-    successful.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptFirstSuccess" units="units"
-    expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The attempt that resolved the host first and the resolution was successful.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptSuccess" units="units" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>The attempt that has resolved the host successfully.</summary>
-</histogram>
-
-<histogram name="DNS.AttemptSuccessDuration" units="ms"
-    expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken in OS resolutions that succeeded and were requested
-    for actual navigations. These attempts which completed after the job was
-    already canceled OR after the job was already completed by an earlier
-    attempt. Note that cached resolutions may provide low (0ms?) resolution
-    times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.AttemptTimeSavedByRetry" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed as of 6/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    This histogram shows the time saved by having spawned an extra attempt, when
-    the first attempt didn't finish before retry attempt.
-  </summary>
-</histogram>
-
-<histogram name="DNS.CacheEvicted" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The time left to expiration of an entry when it is removed while compacting
-    the HostCache.
-  </summary>
-</histogram>
-
-<histogram name="DNS.CacheExpired" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The time since expiration of an entry when it is removed while compacting
-    the HostCache.
-  </summary>
-</histogram>
-
-<histogram name="DNS.CacheExpiredOnGet" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The time since expiration of an entry when it is removed on lookup.
-  </summary>
-</histogram>
-
-<histogram name="DNS.EmptyAddressListAndNoError"
-    enum="DNSEmptyAddressListAndNoError" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Error status when an empty address list was found in OnLookupComplete().
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.Erase" enum="DNS.HostCache.EraseReason"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>The reason for erasing a DNS entry from the host cache.</summary>
-</histogram>
-
-<histogram name="DNS.HostCache.EraseStale.ExpiredBy" units="ms"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When erasing a stale (expired or old-network) DNS entry from the host cache,
-    how long past the expiration time it is.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.EraseStale.NetworkChanges" units="changes"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When erasing a stale (expired or old-network) DNS entry from the host cache
-    how many network changes happened between setting and erasing it.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.EraseStale.StaleHits" units="hits"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When erasing a stale (expired or old-network) DNS entry from the host cache
-    how many hits it received while stale.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.EraseValid.ValidFor" units="ms"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When erasing a valid DNS entry from the host cache, for how much longer it
-    would have remained valid.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.Lookup" enum="DNS.HostCache.LookupOutcome"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>The outcome of looking up a DNS entry in the host cache.</summary>
-</histogram>
-
-<histogram name="DNS.HostCache.LookupStale.ExpiredBy" units="ms"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When looking up a stale DNS entry in the host cache, how long past the
-    expiration time it is.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.LookupStale.NetworkChanges" units="changes"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When looking up a stale DNS entry in the host cache, how many network
-    changes happened between setting it and looking it up.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.RestoreSize" units="entries" expires_after="M84">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Number of HostCache entries persisted to disk, measured at restore time.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.RestoreSuccess" enum="BooleanSuccess"
-    expires_after="M84">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Whether the persisted HostCache entries were restored successfully.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.Set" enum="DNS.HostCache.SetOutcome"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>The outcome of setting a DNS entry in the host cache.</summary>
-</histogram>
-
-<histogram name="DNS.HostCache.UpdateStale.AddressListDelta"
-    enum="DNS.AddressListDeltaType" expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When updating a stale (expired or old-network) DNS entry in the host cache,
-    and both results are successful, how the address list differs between the
-    old and new entries.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.UpdateStale.ExpiredBy" units="ms"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When updating a stale (expired or old-network) DNS entry in the host cache,
-    how long past the expiration time the old entry was.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.UpdateStale.NetworkChanges" units="changes"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When updating a stale (expired or old-nework) DNS entry in the host cache,
-    how many network changes happened between setting the old entry and setting
-    the new entry.
-  </summary>
-</histogram>
-
-<histogram name="DNS.HostCache.UpdateStale.StaleHits" units="hits"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    The number of hits received to an updated stale DNS entry in the host cache
-    while it was stale.
-  </summary>
-</histogram>
-
-<histogram name="DNS.IndependentFailedNavigation" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    When either a pre-resolution was not done recently enough to provide
-    benefit, or the corresponding pre-resolution is still pending, this
-    histogram shows the duration of time used to resolve a hostname as not
-    existing during a failed attempt to navigate to (GET) a URL. In newer
-    versions, if the hostname has never been found as a link during a page scan,
-    and it has a referring URL, then it is added to referrer list data structure
-    (hoping we'll do better next time).
-  </summary>
-</histogram>
-
-<histogram name="DNS.IndependentNavigation" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    When either a pre-resolution was not done recently enough to provide
-    benefit, or the corresponding pre-resolution is still pending, this
-    histogram shows the duration of the duration of time used to resolve a
-    hostname to navigate to (GET) a URL. In newer versions, if the hostname has
-    never been found as a link during a page scan, and it has a referring URL,
-    then it is added to referrer list data structure (hoping we'll do better
-    next time).
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool).
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime_HIGHEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool). Includes only Jobs which had priority HIGHEST when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime_IDLE" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool). Includes only Jobs which had priority IDLE when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime_LOW" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool). Includes only Jobs which had priority LOW when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime_LOWEST" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool). Includes only Jobs which had priority LOWEST when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTime_MEDIUM" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started (a getaddrinfo call was dispatched to the thread
-    pool). Includes only Jobs which had priority MEDIUM when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool).
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange_HIGHEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool). Includes
-    only Jobs which had priority HIGHEST when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange_IDLE" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool). Includes
-    only Jobs which had priority IDLE when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange_LOW" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool). Includes
-    only Jobs which had priority LOW when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange_LOWEST" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool). Includes
-    only Jobs which had priority LOWEST when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.JobQueueTimeAfterChange_MEDIUM" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.JobQueueTimeAfterChange.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started (a getaddrinfo call was dispatched to the thread pool). Includes
-    only Jobs which had priority MEDIUM when started.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchCacheEviction" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time used (most recently) to pre-resolve a hostname, when
-    the prefetched resolution was apparently evicted from the cache. The
-    included samples only list pre-resolution times when the later
-    navigations/fetches took in excess of 15ms.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchCacheEvictionL" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time used (most recently) to pre-resolve a hostname, when
-    the prefetched resolution was apparently evicted from the cache. The
-    included samples only list pre-resolution times when the later
-    navigations/fetches took in excess of 15ms.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchFoundName" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Replaced by DNS.PrefetchFoundNameL.</summary>
-</histogram>
-
-<histogram name="DNS.PrefetchFoundNameL" units="ms" expires_after="2013-05-16">
-  <obsolete>
-    Removed 2/2010, and replaced by DNS.PrefetchResolution
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time used by the DNS pre-resolving threads to resolve a host
-    name via the network. Any resolutions that are faster than 15ms are
-    considered to be local cache hits, not requiring network access, and are not
-    included in this histogram. This histogram is most useful for estimating the
-    typical cost of a name resolution, but it also estimates the total number of
-    network-based resolutions induced by this feature. Not all these resolutions
-    prove helpful (i.e., the user does not always actually visit the resolved
-    hostnames).
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchNegativeHit" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Replaced by DNS.PrefetchNegativeHitL.</summary>
-</histogram>
-
-<histogram name="DNS.PrefetchNegativeHitL" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time saved due to DNS pre-resolving in the &quot;name not
-    found&quot; case. Time &quot;savings&quot; shown in the histogram are
-    defined to be the difference between the DNS pre-resolution duration, and
-    the DNS resolution duration seen during a navigation. These cache hits only
-    list events where the DNS pre-resolve duration for a host was in excess of
-    15ms (i.e., the network was consulted), and the actual DNS resolution (when
-    a user attempted to navigate to a link with the same host name) took less
-    than 15ms (i.e., the network was not consulted), which means the gain was a
-    result of a &quot;cache hit&quot; in the OS cache. For some users with LANs,
-    all negative results (even when the DNS cache might otherwise help) take
-    about 2.5 seconds (due to timeouts for netbios broadcasts), and hence no
-    savings are possible (or shown) for such users in this category.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchPositiveHit" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Replaced by DNS.PrefetchPositiveHitL.</summary>
-</histogram>
-
-<histogram name="DNS.PrefetchPositiveHitL" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time saved due to DNS pre-resolving in the &quot;name was
-    found&quot; case, and induced by either a page scan for a link or an omnibox
-    entry by the user. Time &quot;savings&quot; shown in the histogram are
-    defined to be the difference between the DNS pre-resolution duration, and
-    the DNS resolution duration seen during a navigation. These cache hits only
-    list events where the DNS pre-resolve duration for a host was in excess of
-    15ms (i.e., the network was consulted), and the actual DNS resolution (when
-    a user attempted to navigate to a link with the same host name) took less
-    than 15ms (i.e., the network was not consulted), which means the gain was a
-    result of a &quot;cache hit&quot; in the OS cache.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchQueue" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time spent by a proposed resolution waiting in the queue to
-    be resolved. This number is in addition to any DNS resolution time that may
-    come later.
-  </summary>
-</histogram>
-
-<histogram name="DNS.PrefetchReferredPositiveHit" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The duration of time saved due to DNS pre-resolving in the &quot;name was
-    found&quot; case, and induced by predicting (using referrer lists) that a
-    resolution was needed. Time &quot;savings&quot; shown in the histogram are
-    defined to be the difference between the DNS pre-resolution duration, and
-    the DNS resolution duration seen during a navigation. These cache hits only
-    list events where the DNS pre-resolve duration for a host was in excess of
-    15ms (i.e., the network was consulted), and the actual DNS resolution (when
-    a user attempted to navigate to a link with the same host name) took less
-    than 15ms (i.e., the network was not consulted), which means the gain was a
-    result of a &quot;cache hit&quot; in the OS cache.
-  </summary>
-</histogram>
-
-<histogram name="DNS.QueueRecycledDeltaOver2" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    When, due to congestion avoidance, a queued pre-resolution is abandoned
-    (recycled) without actually being resolved, this histograms records the age
-    in the queue of that entry. Only times over 2 seconds are recorded in this
-    histogram.
-  </summary>
-</histogram>
-
-<histogram name="DNS.QueueRecycledUnder2" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    When, due to congestion avoidance, a queued pre-resolution is abandoned
-    (recycled) without actually being resolved, this histograms records the age
-    in the queue of that entry. Only times less than or equal to 2 seconds are
-    recorded in this histogram.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveCategory" enum="ResolutionCategory"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ResolveCategory.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Counts of successes and failures of OS resolutions in various categories.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveFail" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken in OS resolutions for actual navigations. Note that
-    cached OS resolutions may provide low (0ms?) resolution times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveFail_FAMILY_IPV4" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Same as DNS.ResolveFail, but limited to pure IPv4 lookups.</summary>
-</histogram>
-
-<histogram name="DNS.ResolveFail_FAMILY_IPV6" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Same as DNS.ResolveFail, but limited to pure IPv6 lookups.</summary>
-</histogram>
-
-<histogram name="DNS.ResolveFail_FAMILY_UNSPEC" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Same as DNS.ResolveFail, but limited to IPv4/IPv6 lookups.</summary>
-</histogram>
-
-<histogram name="DNS.ResolveSpeculativeFail" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskFail.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken in speculative OS resolutions. Note that cached OS
-    resolutions may provide low (0ms?) resolution times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveSpeculativeSuccess" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken in speculative OS resolution that succeeded. Note
-    that cached resolutions may provide low (0ms?) resolution times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveSuccess" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time taken in OS resolutions that succeeded and were requested
-    for actual navigations. Note that cached resolutions may provide low (0ms?)
-    resolution times.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveSuccess_FAMILY_IPV4" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as DNS.ResolveSuccess, but limited to pure IPv4 lookups.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveSuccess_FAMILY_IPV6" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as DNS.ResolveSuccess, but limited to pure IPv6 lookups.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveSuccess_FAMILY_UNSPEC" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.ProcTaskSuccess.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Same as DNS.ResolveSuccess, but limited to IPv4/IPv6 lookups.
-  </summary>
-</histogram>
-
-<histogram name="DNS.ResolveUnspecWaste" enum="ResolutionUnspecWasteCategory"
-    expires_after="2013-05-23">
-  <obsolete>
-    Removed as of 5/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Counts of hits and misses in the DNS cache and DNS jobs pool of wasted
-    HostResolverImpl::Jobs that could be avoided by always resolving using
-    AF_UNSPEC.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.NetworkEarly" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver returns, a stale cached
-    result was available, and the network responded before or exactly at the
-    stale delay, how much earlier it responded.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.NetworkLate" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver returns, a stale cached
-    result was available, and the network responded after the stale delay, how
-    much later it responded.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.RequestOutcome"
-    enum="DNS.StaleHostResolverRequestOutcome" expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver returns or is canceled,
-    the outcome of the request.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.RestoreSizeOnCacheMiss" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver has no stale cached result
-    available, the number of host cache entries that were restored from prefs.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.SizeOnCacheMiss" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver has no stale cached result
-    available, the number of entries in the host cache.
-  </summary>
-</histogram>
-
-<histogram name="DNS.StaleHostResolver.StaleAddressListDelta"
-    enum="DNS.AddressListDeltaType" expires_after="M85">
-  <obsolete>
-    Removed 2020-06
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    When a DNS request made through StaleHostResolver had a stale cached result
-    and both the stale and network results were successful, the difference
-    between the old and new address lists.
-  </summary>
-</histogram>
-
-<histogram name="DNS.TotalTime" units="ms" expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.TotalTime.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Excludes speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="DNS.TotalTime_speculative" units="ms"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017. Replaced by Net.DNS.TotalTime_speculative.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Speculative requests only.
-  </summary>
-</histogram>
-
-<histogram name="DNS.UnexpectedResolution" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    In some cases, such as when content arrives with embedded references to
-    other servers, the prefetch system can't (or doesn't) attempt to pre-resolve
-    the hostnames. As an example, a visit to www.cnn.com will fetch content with
-    references to about 12 additional hostnames, none of which are currently
-    anticipated. Such resolutions are termed &quot;Unexpected Resolutions,&quot;
-    and the durations associated with those DNS resolutions are shown below.
-    Future features may attempt to learn (from prior experience locally, or from
-    server provided hints), what secondary hostname resolutions should be done
-    when a primary resolution (or navigation) takes place. This histogram shows
-    what the potential savings are that &quot;remain on the table&quot; until we
-    employ some of these more advanced features.
-  </summary>
-</histogram>
-
-<histogram name="DNS.UnexpectedResolutionL" units="units"
-    expires_after="2017-09-28">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    In some cases, such as when content arrives with embedded references to
-    other servers, or when a page (such as one in SSL) preclude scanning and
-    prefetching, the prefetch system can't (or doesn't) attempt to pre-resolve
-    the hostnames. As an example, a visit to www.cnn.com will fetch content with
-    references to about 12 additional hostnames, none of which might be
-    anticipated. Similarly, clicking on a link in an SSL page won't be
-    anticipated (since scanning in not allowed by default). Such resolutions are
-    termed &quot;Unexpected Resolutions,&quot; and the durations associated with
-    those navigation induced DNS resolutions are shown below. If a referring URL
-    is available for the navigation, the relationship to the referring URL was
-    recorded, and future navigations to the referring hostname would have
-    induced a pre-resolution of hostname that caused an entry below. Such any
-    entry may facilitate future listing in the ReferredPositiveHit histogram.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.Elapsed" units="ms" expires_after="2013-08-01">
-  <obsolete>
-    Renamed 7/2013 to DnsProbe.ProbeDuration.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Time between starting and finishing DNS probe.</summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.NcnOffline.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time between starting and finishing DNS probe when NCN says we're offline.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.NcnOffline.Result"
-    enum="DnsProbe.ObsoleteProbeResult" expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Result of DNS probes sent by the probe service when NCN says we're offline.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.NcnOnline.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Time between starting and finishing DNS probe when NCN says we're online.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.NcnOnline.Result"
-    enum="DnsProbe.ObsoleteProbeResult" expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Result of DNS probes sent by the probe service when NCN says we're online.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.Result" enum="DnsProbe.ObsoleteProbeResult"
-    expires_after="2013-08-01">
-  <obsolete>
-    Renamed 7/2013 to DnsProbe.ProbeResult. (Also switched to the full
-    DnsProbe.ProbeStatus enum.)
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Result of DNS probes sent by the probe service.</summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultBadConfig.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Elapsed time of DNS probes that return PROBE_BAD_CONFIG.</summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultBadConfig.SystemIsLocalhost"
-    enum="DnsProbe.SystemIsLocalhost" expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Whether the only nameserver in the system DNS config was 127.0.0.1 when the
-    probe result was BAD_CONFIG.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultBadConfig.SystemJobResult"
-    enum="DnsProbe.JobResult" expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The result of the system probe job when the overall probe result was
-    BAD_CONFIG.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultBadConfig.SystemNameserverCount"
-    units="units" expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    The number of nameservers in the system DNS config when the probe result was
-    BAD_CONFIG.
-  </summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultNoInternet.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Elapsed time of DNS probes that return PROBE_NO_INTERNET.</summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultNxdomain.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Elapsed time of DNS probes that return PROBE_NXDOMAIN.</summary>
-</histogram>
-
-<histogram name="DnsProbe.Probe.ResultUnknown.Elapsed" units="ms"
-    expires_after="2013-08-01">
-  <obsolete>
-    Removed 7/2013.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>Elapsed time of DNS probes that return PROBE_UNKNOWN.</summary>
-</histogram>
-
-<histogram name="DnsProbe.ProbeDuration" units="ms" expires_after="2019-02-28">
-  <obsolete>
-    Replaced 2/2019 with DnsProbe.ProbeDuration2, which uses TimeTicks instead
-    of Time.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>Wall time between starting and finishing DNS probe.</summary>
-</histogram>
-
-<histogram name="DocumentActivity.Enabled" enum="RunningMode"
-    expires_after="2016-09-13">
-  <obsolete>
-    Removed 9/2016.
-  </obsolete>
-  <owner>mariakhomenko@chromium.org</owner>
-  <summary>
-    Recorded only for Android. Records on every metrics upload whether document
-    mode is enabled.
-  </summary>
-</histogram>
-
-<histogram name="DocumentScan.ConverterResult" enum="BooleanSuccess"
-    expires_after="M85">
-  <obsolete>
-    Removed May 2020.
-  </obsolete>
-  <owner>pstew@chromium.org</owner>
-  <summary>
-    Chrome OS document scan metric that tracks whether a document scan call to
-    the image conversion process succeeded.
-  </summary>
-</histogram>
-
-<histogram name="DocumentScan.ScanResult" enum="BooleanSuccess"
-    expires_after="M90">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>fletcherw@chromium.org</owner>
-  <owner>bmgordon@chromium.org</owner>
-  <summary>
-    Chrome OS document scan metric that tracks whether an attempt to scan
-    succeeded.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBExists" enum="BooleanExists"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    Tracks whether the &quot;Origin Bound Certs&quot; file exists in a profile.
-    Logged each time the network context params are created for a profile, which
-    should happen approximately once per session for a profile.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBLoadedCount" units="units"
-    expires_after="2018-01-22">
-  <obsolete>
-    Removed January 2018.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>Number of certs loaded from domain bound cert database.</summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBLoadStatus"
-    enum="DomainBoundCerts.DBLoadStatus" expires_after="M77">
-  <obsolete>
-    Feature was removed (crbug.com/875053).
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    The status of loading the Channel ID database from disk. This histogram
-    records why the database failed to load, or that it loaded successfully.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBLoadTime" units="ms"
-    expires_after="2018-01-22">
-  <obsolete>
-    Removed January 2018.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>Time spent loading domain bound cert database.</summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBSizeInKB" units="KB"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    The size, on disk, of the domain bound cert database as it is being loaded.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.DBVersion" units="units" expires_after="M80">
-  <obsolete>
-    Feature was removed (crbug.com/875053).
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    The version number of the Channel ID database (before any migrations are
-    run).
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.GenerateCertTime" units="ms"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>Time spent generating a domain bound cert.</summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.GetCertTime" units="ms"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Combined time for GetDomainBoundCert retrieval (both synchronous and
-    asynchronous).
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.GetCertTimeAsync" units="ms"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Time for asynchronous retrieval (from the GetDomainBoundCert call until
-    completion callback is called).
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.GetCertTimeSync" units="ms"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>Time for synchronous GetDomainBoundCert cert retrieval.</summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.GetDomainBoundCertResult"
-    enum="DomainBoundCerts.GetCertResult" expires_after="2018-01-22">
-  <obsolete>
-    Removed January 2018.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>Result of GetDomainBoundCert function.</summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.KillDatabaseResult" enum="BooleanSuccess"
-    expires_after="M80">
-  <obsolete>
-    Feature was removed (crbug.com/875053).
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Whether the domain-bound certs sqlite database was killed succesfully when
-    an unrecoverable error was detected.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.Support" enum="DomainBoundCerts.Support"
-    expires_after="2018-01-22">
-  <obsolete>
-    Removed January 2018.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Counts of SSL client sockets broken down by support for Domain Bound
-    Certificates TLS extension. Counts only connections with full handshakes,
-    resumed sessions are not counted.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.TaskMaxWaitTime" units="ms"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Longest time spent by requests waiting for load of domain bound cert
-    database.
-  </summary>
-</histogram>
-
-<histogram name="DomainBoundCerts.TaskWaitCount" units="units"
-    expires_after="2017-04-05">
-  <obsolete>
-    Removed 4/2017.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Number of requests that waited for load of domain bound cert database.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.BeaconInterval" units="ms"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The time between successive Domain Reliability beacons being queued in the
-    same context. (Can be arbitrarily long if no beacons are queued in a while.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.BeaconIntervalGlobal" units="ms"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The time between successive Domain Reliability beacons being queued across
-    all contexts. (Can be arbitrarily long if no beacons are queued in a while.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.BeaconReported" enum="BooleanReported"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Whether a beacon added to a Domain Reliability context was saved to be
-    uploaded to the collector.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.OnBeaconDidEvict" enum="BooleanDidEvict"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Whether adding a beacon to a Domain Reliability context caused it to evict
-    an older beacon to stay within memory limits.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.ReportedBeaconError" enum="NetErrorCodes"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The Chrome error code included in a beacon saved to be uploaded to the
-    collector.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.ReportedBeaconError_HasServerIP"
-    enum="NetErrorCodes" expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The Chrome error code included in a beacon with a non-empty server_ip field
-    saved to be uploaded to the collector.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.ReportedBeaconUploadDepth" units="levels"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The upload depth included in a beacon saved to be uploaded to the collector.
-    (Zero means the beacon was not about a report upload; n+1 means the beacon
-    was about a report with upload depth n.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.SetConfigRecreatedContext"
-    enum="BooleanCreated" expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    When Domain Reliability receives a valid NEL configuration header for an
-    origin with Domain Reliability active, whether or not it needed to recreate
-    the origin's context to apply a changed config.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadCollectorIndex" units="units"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The index of the collector that a Domain Reliability upload was sent to.
-    (Later collectors are only used when earlier collectors have failed.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadCollectorRetryDelay" units="ms"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    After an upload to a collector finishes (successfully or not), the delay
-    before the scheduler can send another upload to that collector. (If recent
-    uploads were successful, this will be 0; if not, it will be based on the
-    BackoffEntry and any Retry-After header received.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadDuration" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/807144
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The elapsed time between starting and finishing a Domain Reliability upload.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadFailover"
-    enum="DomainReliability.BooleanFailover" expires_after="2014-11-03">
-  <obsolete>
-    Removed 11/2014; see UploadCollectorIndex
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Whether a Domain Reliability upload was sent to a collector other than the
-    first one listed in the config. (This only happens when an upload to the
-    first collector fails.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadInterval" units="ms"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The time between successive Domain Reliability uploads being started in the
-    same context. (Can be arbitrarily long if no beacons are reported in a
-    while.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadIntervalGlobal" units="ms"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The time between successive Domain Reliability uploads being started across
-    all contexts. (Can be arbitrarily long if no beacons are reported in a
-    while.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadLatency" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/807144
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The time from the first beacon in a Domain Reliability upload being recorded
-    and that upload completing successfully. (Note that if some beacons are
-    never uploaded successfully, they will not feature in this histogram at
-    all.)
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadNetError" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/807144
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The network error code (or OK if none) returned by the URLFetcher when a
-    Domain Reliability report is uploaded.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadResponseCode" enum="HttpResponseCode"
-    expires_after="M80">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/807144
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The HTTP response code returned by the Domain Reliability collector when a
-    report is uploaded.
-  </summary>
-</histogram>
-
-<histogram name="DomainReliability.UploadSuccess" enum="BooleanSuccess"
-    expires_after="M80">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/807144
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>Whether a Domain Reliability upload succeeded.</summary>
-</histogram>
-
-<histogram name="DomDistiller.BarCloseButtonUsage" enum="BooleanPanelWasOpen"
-    expires_after="2017-06-13">
-  <obsolete>
-    UI rewrite to be an InfoBar makes this metric irrelevant as of 05/2017.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <summary>
-    Records if the close button was used before or after opening and viewing
-    Reader Mode content.
-  </summary>
-</histogram>
-
-<histogram name="DomDistiller.DistillationQuality" enum="BooleanSuccess"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2020 because the code to collect this metric has not been called
-    in months.
-  </obsolete>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    Whether the perceived quality of the distillation of a web page was good.
-  </summary>
-</histogram>
-
-<histogram name="DomDistiller.PageDistillable" enum="DistillableType"
-    expires_after="2016-02-09">
-  <obsolete>
-    PageDistillableAfterLoading and PageDistillableAfterParsing provide more
-    details since 02/2016.
-  </obsolete>
-  <owner>cjhopman@chromium.org</owner>
-  <summary>
-    Records the &quot;Distillable Type&quot; (not distillable, mobile-friendly
-    distillable, non-mobile-friendly distillable, etc) for each analyzed page.
-  </summary>
-</histogram>
-
-<histogram name="DomDistiller.PageDistilledType" enum="DistillableType"
-    expires_after="2016-02-09">
-  <obsolete>
-    Not collected anymore.
-  </obsolete>
-  <owner>cjhopman@chromium.org</owner>
-  <summary>
-    Records the &quot;Distillable Type&quot; (not distillable, mobile-friendly
-    distillable, non-mobile-friendly distillable, etc) for each distilled page.
-  </summary>
-</histogram>
-
-<histogram name="DomDistiller.Time.SwipeToPaint" units="ms"
-    expires_after="2017-06-13">
-  <obsolete>
-    UI rewrite to be an InfoBar makes this metric irrelevant as of 05/2017.
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    Records the time from a swipe-up gesture on ReaderModePanel to the first
-    paint of the empty template.
-  </summary>
-</histogram>
-
-<histogram name="DomDistiller.Time.ViewingReaderModePanel" units="ms"
-    expires_after="2017-06-13">
-  <obsolete>
-    UI rewrite to be an InfoBar makes this metric irrelevant as of 05/2017.
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <summary>
-    Records the amount of time between the Reader Mode panel opening and it
-    closing or returning to the peeking state.
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.clear" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.clear() or sessionStorage.clear().
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.getItem" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.getItem() or sessionStorage.getItem().
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.key" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.key() or sessionStorage.key().
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.length" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.length() or sessionStorage.length().
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.removeItem" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.removeItem() or
-    sessionStorage.removeItem().
-  </summary>
-</histogram>
-
-<histogram name="DOMStorage.setItem" units="ms" expires_after="2015-02-20">
-  <obsolete>
-    Removed 2012.
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Duration to execute localStorage.setItem() or sessionStorage.setItem().
-  </summary>
-</histogram>
-
-<histogram name="Doodle.ConfigDownloadOutcome"
-    enum="DoodleConfigDownloadOutcome" expires_after="2017-08-24">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>Outcome of downloading the Doodle config.</summary>
-</histogram>
-
-<histogram name="Doodle.ConfigDownloadTime" units="ms"
-    expires_after="2017-08-24">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The time it took to download the Doodle config. Recorded only if the
-    download succeeded and the received data was parsed without errors.
-  </summary>
-</histogram>
-
-<histogram name="Download.AcceptRangesBytes.KBytes" units="KB"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>The length of downloads for serves that accept byte ranges.</summary>
-</histogram>
-
-<histogram name="Download.AcceptRangesMissingOrInvalid.KBytes" units="KB"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The length of downloads for serves that do not specify whether the accept
-    ranges, or have invalid ranges specified.
-  </summary>
-</histogram>
-
-<histogram name="Download.AcceptRangesNone.KBytes" units="KB"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The length of downloads for serves that do not accept ranges.
-  </summary>
-</histogram>
-
-<histogram name="Download.ActualBandwidth" units="Bytes/second"
-    expires_after="2017-01-05">
-  <obsolete>
-    Removed January 2017.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>The actual bandwidth (per read) of a download.</summary>
-</histogram>
-
-<histogram name="Download.AttachmentServices.Result"
-    enum="AttachmentServicesResult" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Result of invoking (or attempting to invoke) Windows Attachment Services API
-    via IAttachmentExecute::Save().
-  </summary>
-</histogram>
-
-<histogram name="Download.BandwidthDiskBytesPerSecond" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Disk bandwidth (defined as total bytes divided by the amount of time blocked
-    on write or close on the file descriptor) seen for a single download.
-  </summary>
-</histogram>
-
-<histogram name="Download.BandwidthUsed" units="%" expires_after="2017-01-05">
-  <obsolete>
-    Removed January 2017.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The percentage of the potential bandwidth actually used (per read) of a
-    download. An entry of 100% implies that Chrome was the limiting factor in
-    download speed.
-  </summary>
-</histogram>
-
-<histogram name="Download.BandwidthWithoutParallelStreamsBytesPerSecond"
-    units="bytes/second" expires_after="2017-04-20">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    For parallel downloading, average disk bandwidth seen when only 1 stream is
-    actively downloading the content. Other streams may have already finished,
-    or have not been created yet. If a download was ever paused, this is not
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="Download.BandwidthWithParallelStreamsBytesPerSecond"
-    units="bytes/second" expires_after="2017-04-20">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    For parallel downloading, average disk bandwidth seen when parallel streams
-    are downloading the content. If a download was ever paused, this is not
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="Download.CancelledDownloadRemovedFromHistory"
-    units="downloads" expires_after="M80">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the number of cancelled download that are cleaned up from the
-    history, after loading all the downloads from the history DB on startup.
-  </summary>
-</histogram>
-
-<histogram name="Download.ClearAllSize" units="units"
-    expires_after="2017-01-05">
-  <obsolete>
-    Removed 1/2017.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The number of downloads in history at the time it is cleared.
-  </summary>
-</histogram>
-
-<histogram name="Download.ConnectionInfo" enum="ConnectionInfo"
-    expires_after="M81">
-  <obsolete>
-    Deprecated 04/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Network connection information about the download, recorded after the
-    network response is received.
-  </summary>
-</histogram>
-
-<histogram name="Download.ContentDisposition" enum="DownloadContentDisposition"
-    expires_after="M81">
-  <obsolete>
-    Deprecated 02/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Content-Disposition header features. The presence of a Content-Disposition
-    header, use of 'filename' and 'filename*' parameters, and string encoding
-    schemes are counted for each unthrottled download. The total number
-    downloads is Download.Counts[5] (Initiated and Unthrottled).
-  </summary>
-</histogram>
-
-<histogram name="Download.ContentLength.Parallelizable" units="KB"
-    expires_after="M81">
-  <obsolete>
-    Deprecated 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    File size calculated from the content-length header of successfully
-    completed Parallelizable downloads.
-  </summary>
-</histogram>
-
-<histogram name="Download.ContentType" enum="DownloadContentType"
-    expires_after="2017-03-23">
-  <obsolete>
-    Removed 03/2017, and replaced by Download.Start.ContentType.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>Content types that are downloaded.</summary>
-</histogram>
-
-<histogram name="Download.DangerousDownloadValidated"
-    enum="DownloadItem.DangerType" expires_after="M81">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    User chose to save a download which was marked dangerous. Grouped by the
-    type of danger.
-  </summary>
-</histogram>
-
-<histogram name="Download.DangerousFile.DangerousDownloadValidated"
-    enum="DownloadItem.DangerousFileType" expires_after="M81">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    User chose to save a download which was marked DANGEROUS_FILE. Grouped by
-    the type of file.
-  </summary>
-</histogram>
-
-<histogram name="Download.DangerousFile.Discard"
-    enum="DownloadItem.DangerousFileType" expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    A download which was marked DANGEROUS_FILE was discarded without the user
-    directly choosing, because the browser was closed. Grouped by the file
-    extension.
-  </summary>
-</histogram>
-
-<histogram name="Download.DangerousFile.Reason" enum="DangerousFile.Reason"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77 since the data was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates why a download is marked as DANGEROUS_FILE. Grouped by reason,
-    such as Safe Browsing (SB) service is not available, and SB returns UNKOWN
-    or SAFE verdict. The sum of all reasons should roughly equal to the
-    DANGEROUS_FILE bucket count in Download.DownloadWarningShown.
-  </summary>
-</histogram>
-
-<histogram name="Download.DangerousFile.UserDiscard"
-    enum="DownloadItem.DangerousFileType" expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    User chose to discard a download which was marked DANGEROUS_FILE. Grouped by
-    the file extension.
-  </summary>
-</histogram>
-
-<histogram name="Download.Database.CreateDownloadDuration" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Time taken to create a single download in the history DB.</summary>
-</histogram>
-
-<histogram name="Download.Database.QueryDownloadDuration" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Time taken to query all downloads from history DB.</summary>
-</histogram>
-
-<histogram name="Download.Database.UpdateDownloadDuration" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Time taken to update a single download in the history DB.</summary>
-</histogram>
-
-<histogram name="Download.DatabaseDownloadExistsForDownloadSlice"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Whether a download can be found for a download slice in the DB. This
-    histogram is recorded for each download slice row every time the database is
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="Download.DatabaseRecordDropped"
-    enum="DownloadDatabaseRecordDroppedType" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Reason for dropping a record read in from the DB.</summary>
-</histogram>
-
-<histogram name="Download.DatabaseRemoveDownloadsCount" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Number of downloads removed from the history at once.</summary>
-</histogram>
-
-<histogram name="Download.DatabaseRemoveDownloadsTime" units="microseconds"
-    expires_after="2017-02-14">
-  <obsolete>
-    Removed 2/2017
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    How long it took to delete a batch of downloads from history.
-  </summary>
-</histogram>
-
-<histogram name="Download.DatabaseRemoveDownloadsTimePerRecord"
-    units="nanoseconds/record" expires_after="2017-02-14">
-  <obsolete>
-    Removed 2/2017
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    How long it took to delete some downloads from history, per download.
-  </summary>
-</histogram>
-
-<histogram name="Download.Discard" enum="DownloadItem.DangerType"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    A download which was marked dangerous was discarded without the user
-    directly choosing, because the browser was closed. Grouped by the type of
-    danger.
-  </summary>
-</histogram>
-
-<histogram name="Download.DiskBandwidthUsedPercentage" units="%"
-    expires_after="2017-01-05">
-  <obsolete>
-    Removed 1/2017.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The percentage of the available disk bandwidth that was used by the
-    download. 100% indicates that the disk bandwidth was the limiting factor for
-    the download.
-  </summary>
-</histogram>
-
-<histogram name="Download.DownloadWarningShown" enum="DownloadItem.DangerType"
-    expires_after="M77">
-  <obsolete>
-    Replaced 03/2020 by Download.ShowedDownloadWarning due to this one expiring.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    A download warning was shown in the shelf. Note that some downloads may not
-    be shown on the shelf, e.g., if chrome://downloads is already open when the
-    download completes, or if an extension is using the downloads API. Grouped
-    by the type of danger.
-  </summary>
-</histogram>
-
-<histogram name="Download.EstimatedTimeSavedWithParallelDownload" units="ms"
-    expires_after="2020-10-18">
-  <obsolete>
-    Removed in 09/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Estimated time saved on a download when parallel downloading is enabled. To
-    estimate this, the time spent on a download is classified into two
-    categories. The fist category has only one stream active, while other
-    streams are either finished, not started, or failed. And the second category
-    has multiple streams active. By calculating the average bandwidth during the
-    first category, a rough estimation on the time it will save is obtained by
-    assuming all the bytes downloaded during the second category are downloaded
-    by only one stream. If a download is ever paused, this is not recorded.
-  </summary>
-</histogram>
-
-<histogram name="Download.EstimatedTimeWastedWithParallelDownload" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Similar to Download.EstimatedTimeSavedWithParallelDownload, but this
-    estimates the time wasted on a download when parallel downloading is
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="Download.FeedbackDialogEnabled" enum="BooleanEnabled"
-    expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Whether the user enables dangerous download feedback reporting after viewing
-    the opt-in dialog.
-  </summary>
-</histogram>
-
-<histogram name="Download.FilePickerResult" enum="DownloadFilePickerResult"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    How the user interacts with the file chooser when doing a &quot;Save
-    As&quot; for non-full-page saves.
-  </summary>
-</histogram>
-
-<histogram name="Download.FileThreadBlockedTime" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The amount of time in milliseconds the file thread blocks for each set of
-    buffers drained from the incoming pipe (ms).
-  </summary>
-</histogram>
-
-<histogram name="Download.FileThreadReceiveBuffers" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The number of buffers in a call to DownloadManager::UpdateDownload.
-  </summary>
-</histogram>
-
-<histogram name="Download.FirstOpenTime" units="ms" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The time between a download completing and the file being opened for the
-    first time.
-  </summary>
-</histogram>
-
-<histogram name="Download.FrameGesture" enum="DownloadFrameGesture"
-    expires_after="2018-11-02">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    The type of frame in which a download occurs and whether the download
-    involves a transient user gesture. It is only recorded for downloads
-    originated from navigations or from HTML anchor download attributes.
-  </summary>
-</histogram>
-
-<histogram name="Download.HistorySize" units="units" expires_after="M85">
-  <obsolete>
-    Removed in 04/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The number of items in the History database, at the time a new download is
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="Download.HistorySize2" units="units"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removed in 04/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The number of items in the History database, at the time a new download is
-    recorded. Higher maximum, more buckets than Download.HistorySize.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedAtEndError" enum="NetErrorCodes"
-    expires_after="M85">
-  <obsolete>
-    Checked on 06/2020 and no longer logged.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Positive net error code that caused a download to be interrupted at the
-    *end* of a download (when the number of bytes is known). This is only
-    triggered when the total content size is known before any bytes are
-    transferred, such as when a Content-Length header is supplied.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedAtEndReason" enum="InterruptReason"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The reason that a download was interrupted at the *end* of a download (when
-    the number of bytes is known). This is only triggered when the total content
-    size is known before any bytes are transferred, such as when a
-    Content-Length header is supplied.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedDownloadsRemovedFromHistory"
-    units="downloads" expires_after="M80">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the number of interrupted download that are cleaned up from the
-    history, after loading all the downloads from the history DB on startup.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedError" enum="NetErrorCodes"
-    expires_after="M85">
-  <obsolete>
-    Checked on 06/2020 and no longer logged.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Positive net error code that caused a download to be interrupted.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedOverrunBytes" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The total number of bytes minus the received number of bytes at the time
-    that a download is interrupted. This is only triggered when the total
-    content size is known before any bytes are transferred, such as when a
-    Content-Length header is supplied.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedReceivedSizeK" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The number of kilobytes received for a download at the time it is
-    interrupted.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedTotalSizeK" units="KB" expires_after="M81">
-  <obsolete>
-    Deprecated 02/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The reported total size in kilobytes for a download at the time it is
-    interrupted. This is essentially the size reported by the Content-Length
-    header. If no size is specified up-front, it is not recorded in the
-    histogram. For example, a download transferred with chunked encoding will
-    not be recorded.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedUnderrunBytes" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The excessive number of bytes which have been received at the time that a
-    download is interrupted. This is only triggered when the total content size
-    is known before any bytes are transferred, such as when a Content-Length
-    header is supplied.
-  </summary>
-</histogram>
-
-<histogram name="Download.InterruptedUnknownSize"
-    enum="DownloadInterruptedUnknownSizeType" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    True if the size of an interrupted download is unknown, false if it is
-    known.
-  </summary>
-</histogram>
-
-<histogram name="Download.IOSDownloadInstallDrivePromoShown" enum="Boolean"
-    expires_after="2020-07-13">
-  <obsolete>
-    Removed in 12/2019 replaced by IOSDownloadFileUIGoogleDrive's histogram.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    Logged when the download was successfully completed. Bool value indicates
-    whether or not Install Google Drive promo was shown to the user.
-  </summary>
-</histogram>
-
-<histogram name="Download.MainFrame.HasGesture" enum="Boolean"
-    expires_after="2019-01-10">
-  <obsolete>
-    Removed as of 01/2019.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    Whether the main frame download involves a transient user gesture. It is
-    only recorded for downloads originated from navigations or from HTML anchor
-    download attributes.
-  </summary>
-</histogram>
-
-<histogram name="Download.MainFrame.SandboxGesture"
-    enum="MainFrameDownloadSandboxGesture" expires_after="2019-03-19">
-  <obsolete>
-    Removed as of 03/2019.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    For a download that occurs in top frame, record whether the frame is
-    sandboxed and whether the download involves a transient user gesture. It is
-    only recorded for downloads originated from navigations or from HTML anchor
-    download attributes.
-  </summary>
-</histogram>
-
-<histogram name="Download.MaliciousDownloadClassified"
-    enum="DownloadItem.DangerType" expires_after="2020-02-16">
-  <obsolete>
-    Removed as of 08/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    A download has been marked as malicious. Grouped by the type of danger. Each
-    download can only be recorded once; it will be labeled with the first type
-    of danger spotted.
-  </summary>
-</histogram>
-
-<histogram name="Download.MapErrorNetworkFailed" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed in 04/2019 after network service is enabled by default. Use
-    Download.MapErrorNetworkFailed.NetworkService instead.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Network error that produced a DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED
-    result in DownloadResourceHandler::OnResponseCompleted().
-  </summary>
-</histogram>
-
-<histogram name="Download.MapErrorNetworkFailed.NetworkService"
-    enum="NetErrorCodes" expires_after="2020-10-04">
-  <obsolete>
-    Removed as of 08/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Network error that produced a DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED
-    result in DownloadResourceHandler::OnResponseCompleted(). Recorded when
-    running with the network service enabled.
-  </summary>
-</histogram>
-
-<histogram name="Download.MapWinShErrorAccessDenied"
-    enum="SpecialShFileOperationCodes" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Windows error that produced a DOWNLOAD_INTERRUPT_REASON_ACCESS_DENIED result
-    in MapShFileOperationCodes().
-  </summary>
-</histogram>
-
-<histogram name="Download.MapWinShErrorFileFailed"
-    enum="SpecialShFileOperationCodes" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Windows error that produced a DOWNLOAD_INTERRUPT_REASON_FILE_FAILED result
-    in MapShFileOperationCodes().
-  </summary>
-</histogram>
-
-<histogram name="Download.MapWinShErrorTransientError"
-    enum="SpecialShFileOperationCodes" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Windows error that produced a DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR
-    result in MapShFileOperationCodes().
-  </summary>
-</histogram>
-
-<histogram name="Download.MediaParser.CompletionTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the duration to successfully complete the media file parsing.
-  </summary>
-</histogram>
-
-<histogram name="Download.OnChanged" units="units" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Percentage of DownloadItem::Observer::OnDownloadUpdated events that
-    signified a change in the extension API representation of the download.
-  </summary>
-</histogram>
-
-<histogram name="Download.OpenTime" units="ms" expires_after="M81">
-  <obsolete>
-    Deprecated 02/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The time between a download completing and the file being opened.
-  </summary>
-</histogram>
-
-<histogram name="Download.OriginStateOnFullResumption"
-    enum="DownloadOriginStateOnResumption" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Changes observed when a response is received for a full download resumption
-    request.
-  </summary>
-</histogram>
-
-<histogram name="Download.OriginStateOnPartialResumption"
-    enum="DownloadOriginStateOnResumption" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Changes observed when a response is received for a partial (byte-range)
-    download resumption request.
-  </summary>
-</histogram>
-
-<histogram name="Download.PageTransition" enum="CorePageTransition"
-    expires_after="M85">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The core page transition type for navigation initiated downloads. Not
-    recorded for programmatic downloads. This metric is recorded when the
-    response headers were received and processed for a download. The number of
-    samples here should correspond to Download.Counts[8] (Started) -
-    (programmatic downloads that don't have a page transition type).
-  </summary>
-</histogram>
-
-<histogram name="Download.ParallelDownload.BandwidthRatioPercentage" units="%"
-    expires_after="2018-08-31">
-  <obsolete>
-    Removed August 2018.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the ratio of parallel streams bandwidth to single stream bandwidth
-    in parallel download.
-  </summary>
-</histogram>
-
-<histogram name="Download.ParallelDownload.RemainingTimeWhenBuildingRequests"
-    units="seconds" expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Records the remaining download time when building parallel requests.
-  </summary>
-</histogram>
-
-<histogram name="Download.ParallelDownload.TotalTimeRatioPercentage" units="%"
-    expires_after="2018-08-31">
-  <obsolete>
-    Removed August 2018.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the ratio of the actual total time of the download to the total time
-    without parallel streams. The total time without parallel streams is
-    calculated as the size of the file divided by the single stream bandwidth.
-  </summary>
-</histogram>
-
-<histogram name="Download.PotentialBandwidth" units="Bytes/second"
-    expires_after="2017-01-05">
-  <obsolete>
-    Removed January 2017.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The maximum bandwidth (per read) that Chrome could have provided for the
-    download. If the actual bandwidth equals the potential bandwidth, that means
-    that Chrome was the limiting factor for download bandwidth.
-  </summary>
-</histogram>
-
-<histogram name="Download.ResourceHandlerBlockedPercentage" units="%"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The percentage of the lifetime of the DownloadResourceHandler for which it
-    was blocked by downstream flow control. 0% indicates that the network
-    bandwidth was the limiting factor for the download.
-  </summary>
-</histogram>
-
-<histogram name="Download.ResumptionAfterContentLengthMismatch.Reason"
-    enum="InterruptReason" expires_after="2020-02-16">
-  <obsolete>
-    Removed in 08/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records the interrupt reason after download is resumed after a content
-    length mismatch error.
-  </summary>
-</histogram>
-
-<histogram name="Download.ResumptionComplete.HasStrongValidators"
-    enum="BooleanHasStrongValidators" expires_after="2020-06-07">
-  <obsolete>
-    Removed in 04/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records whether strong validators are present when download completes.
-  </summary>
-</histogram>
-
-<histogram name="Download.ResumptionRestart.Counts"
-    enum="DownloadResumptionRestartCountType" expires_after="2020-10-25">
-  <obsolete>
-    Removed in 09/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records counts related to download restarting from the beginning during
-    resumption.
-  </summary>
-</histogram>
-
-<histogram name="Download.ResumptionStart.HasStrongValidators"
-    enum="BooleanHasStrongValidators" expires_after="2020-06-07">
-  <obsolete>
-    Removed in 04/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records whether strong validators are present when download is resumed.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Clients.InflatedFullBrowser"
-    enum="BooleanRequested" expires_after="2020-06-01">
-  <obsolete>
-    Deprecated 05/2020.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="Download.Service.Client" -->
-
-  <owner>dtrainor@chromium.org</owner>
-  <owner>mheikal@chromium.org</owner>
-  <owner>hanxi@chromium.org</owner>
-  <summary>
-    The number of times full browser mode is requested to be loaded by a
-    DeferredClientWrapper. This is recorded when a DeferredClientWrapper needs
-    to inflate the underlying client while the browser is running in reduced
-    mode. DeferredClientWrapper inflates the underlying client for any
-    non-trivial method call on DeferredClientWrapper.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Entry.ResumptionCount" units="attempts"
-    expires_after="M81">
-  <obsolete>
-    Deprecated 02/2020.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Records how many resumptions have taken place at the time of resumption for
-    a download in the Download Service. This differs from
-    Download.Service.Entry.RetryCount, which records restarts.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Files.Cleanup.Attempts" units="attempts"
-    expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>shaktisahu@chromium.org</owner>
-  <summary>
-    The number of times download service tried to delete the download file
-    before successfully deleting it.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Files.DiskUsed" units="%" expires_after="M85">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    The percentage of disk space used by download service files. Recorded during
-    initialization of the file monitor.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Files.PathRenamed" enum="BooleanRenamed"
-    expires_after="M82">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-<!-- expires-never: Download service stability metric. -->
-
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records if the final file path has been renamed by low level download
-    library after the download is successfully completed.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Download.Service.Finish.FileSize" units="KB"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed as of 08/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="Download.Service.CompletionType" -->
-
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    The file size of completed download, including failed downloads.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Finish.ReportedHash"
-    enum="BooleanIncludesHash" expires_after="2019-10-01">
-  <obsolete>
-    Removed in 09/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Records if a completed download service entry was sent to a client with a
-    hash or not.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Recovery" enum="Download.Service.EntryStates"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    The state that the entry transitions to when recovery operation happens.
-  </summary>
-</histogram>
-
-<histogram name="Download.Service.Request.BatteryRequirement"
-    enum="Download.Service.BatteryRequirements" expires_after="M77">
-  <obsolete>
-    Removed in 06/2019 in Issue 975678.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>The battery requirement of the download request.</summary>
-</histogram>
-
-<histogram name="Download.Service.Request.NetworkRequirement"
-    enum="Download.Service.NetworkRequirements" expires_after="M77">
-  <obsolete>
-    Removed in 06/2019 in Issue 975678.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>The network requirement of the download request.</summary>
-</histogram>
-
-<histogram name="Download.Service.Request.Priority"
-    enum="Download.Service.Priority" expires_after="M77">
-  <obsolete>
-    Removed in 06/2019 in Issue 975678.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>The priority of the download request.</summary>
-</histogram>
-
-<histogram base="true" name="Download.Service.Request.StartResponse"
-    enum="Download.Service.ShouldDownload" expires_after="M85">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="Download.Service.Client" -->
-
-  <owner>xingliu@chromium.org</owner>
-  <summary>The start response of download attempts.</summary>
-</histogram>
-
-<histogram base="true" name="Download.Service.Request.StartResult"
-    enum="Download.Service.StartResult" expires_after="M81">
-  <obsolete>
-    Download client api no longer expects a repsponse from the client when a
-    download is started.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="Download.Service.Client" -->
-
-  <owner>xingliu@chromium.org</owner>
-  <summary>The start result of download attempts.</summary>
-</histogram>
-
-<histogram name="Download.ShelfInProgressSizeOnAutoClose" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The number of download items in progress on the shelf when it closes
-    automatically.
-  </summary>
-</histogram>
-
-<histogram name="Download.ShelfInProgressSizeOnUserClose" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The number of download items in progress on the shelf when the user closes
-    it.
-  </summary>
-</histogram>
-
-<histogram name="Download.ShelfSizeOnAutoClose" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The number of download items on the shelf when it closes automatically.
-  </summary>
-</histogram>
-
-<histogram name="Download.ShelfSizeOnUserClose" units="units"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    The number of download items on the shelf when the user closes it.
-  </summary>
-</histogram>
-
-<histogram name="Download.Sources" enum="DownloadSource"
-    expires_after="2018-01-17">
-  <obsolete>
-    Removed 1/2018, integrated into Download.Counts.DOWNLOAD_TRIGGERED_COUNT
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    The initiation source (if initiated within the content layer of chrome) for
-    a download.
-  </summary>
-</histogram>
-
-<histogram name="Download.Start.ContentType.InsecureChain"
-    enum="DownloadContentType" expires_after="2020-09-06">
-  <obsolete>
-    Removed in 04/2020. Superseded by mixed download metrics under
-    Download.InsecureBlocking.
-  </obsolete>
-  <owner>cthomp@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The content type of a download, for downloads where the final resolved URL
-    or any redirect before the final URL are insecure. To normalize these
-    numbers, divide the counts by the counts of Download.Start.ContentType (to
-    measure the proportion for each content type downloaded insecurely) or by
-    the sum of Download.Start.ContentType (to measure the proportion of a
-    particular insecure download content type over all downloads).
-  </summary>
-</histogram>
-
-<histogram name="Download.Start.ContentType.SecureChain"
-    enum="DownloadContentType" expires_after="2020-05-03">
-  <obsolete>
-    Removed in 04/2020. Superseded by mixed download metrics under
-    Download.InsecureBlocking.
-  </obsolete>
-  <owner>cthomp@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The content type of a download, for downloads where the final resolved URL
-    and all redirects before the final URL are secure. To normalize these
-    numbers, divide the counts by the counts of Download.Start.ContentType (to
-    measure the proportion for each content type downloaded securely) or by the
-    sum of Download.Start.ContentType (to measure the proportion of a particular
-    secure download content type over all downloads).
-  </summary>
-</histogram>
-
-<histogram name="Download.Subframe.SandboxOriginAdGesture"
-    enum="SubframeDownloadSandboxOriginAdGesture" expires_after="2019-03-19">
-  <obsolete>
-    Removed as of 03/2019.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    For a download that occurs in subframe, record whether the frame is
-    sandboxed, whether the origin is same to the top frame, whether it's an ad
-    subframe, and whether the download involves a transient user gesture. It is
-    only recorded for downloads originated from navigations or from HTML anchor
-    download attributes.
-  </summary>
-</histogram>
-
-<histogram name="Download.TargetConnectionSecurity"
-    enum="DownloadConnectionSecurity" expires_after="2020-02-16">
-  <obsolete>
-    Removed in M77 since the data was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The connection security state of a download, indicating whether its final
-    resolved url and the redirects before final url are secure.
-  </summary>
-</histogram>
-
-<histogram name="Download.Time" units="ms" expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>Time between the start of a download and its completion.</summary>
-</histogram>
-
-<histogram name="Download.TimeToRenameFailureAfterInitialFailure" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Time elapsed until a retried download file rename operation failed for the
-    last time after the initial rename failed.
-  </summary>
-</histogram>
-
-<histogram name="Download.TimeToRenameSuccessAfterInitialFailure" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Time elapsed until a retried download file rename operation succeeded after
-    the initial rename failed.
-  </summary>
-</histogram>
-
-<histogram name="Download.UserDiscard" enum="DownloadItem.DangerType"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    User chose to discard a download which was marked dangerous. Grouped by the
-    type of danger.
-  </summary>
-</histogram>
-
-<histogram name="Download.WriteLoopCount" units="units"
-    expires_after="2017-01-05">
-  <obsolete>
-    Removed 1/2017
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    The number of iterations for the write loop in BaseFile::AppendDataTofile().
-  </summary>
-</histogram>
-
-<histogram name="Download.WriteSize" units="Bytes" expires_after="2017-01-05">
-  <obsolete>
-    Removed 1/2017
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>The write size for calls to BaseFile::AppendDataTofile().</summary>
-</histogram>
-
-<histogram name="DownloadableStrings.InstallTime" units="ms"
-    expires_after="2018-02-06">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>digit@chromium.org</owner>
-  <summary>
-    The time to succesfully download and install the DownloadableStrings
-    component on Android.
-  </summary>
-</histogram>
-
-<histogram name="DownloadableStrings.SimCountryCode"
-    enum="DownloadableStrings.MobileCountryCode" expires_after="2018-02-06">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>digit@chromium.org</owner>
-  <summary>
-    The mobile country code (MCC) of the device's SIM card, if available (in the
-    [200..999] range), or 0 for &quot;undetermined&quot;. This is collected on
-    Chrome startup. For devices with several SIM cards, this only reports the
-    code of the SIM card in use during startup.
-  </summary>
-</histogram>
-
-<histogram name="DownloadableStrings.Status"
-    enum="DownloadableStrings.InstallStatus" expires_after="2018-02-06">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>digit@chromium.org</owner>
-  <summary>
-    The status code returned after trying to install and update the
-    DownloadableStrings component.
-  </summary>
-</histogram>
-
-<histogram name="DownloadableStrings.Timeout" units="ms"
-    expires_after="2018-02-06">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>digit@chromium.org</owner>
-  <summary>
-    The timeout reported by the component updater when trying to install the
-    DownloadableStrings component fails with a specific error.
-  </summary>
-</histogram>
-
-<histogram name="Drive.BatchUploadResponseCode" enum="HttpResponseCode"
-    expires_after="M77">
-  <obsolete>
-    Obsolete 07/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>hirono@chromium.org</owner>
-  <summary>Respose code of batch upload request.</summary>
-</histogram>
-
-<histogram name="Drive.CacheDBOpenStatus" enum="DriveCacheDBOpenStatus"
-    expires_after="2013-12-03">
-  <obsolete>
-    Removed 8/2013.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>Status of drive cache metadata database open.</summary>
-</histogram>
-
-<histogram name="Drive.DeltaFeedLoadTime" units="ms" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Time spent to load the delta change list information from the server.
-  </summary>
-</histogram>
-
-<histogram name="Drive.DirectoryFeedLoadTime" units="ms" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Time spent to load the list of files in a single directory from Google Drive
-    server.
-  </summary>
-</histogram>
-
-<histogram name="Drive.DownloadFromDriveFileSize" units="KB"
-    expires_after="2019-02-15">
-  <obsolete>
-    This was a temporary histogram for bug http://crbug.com/229650 that has been
-    closed.
-  </obsolete>
-  <owner>mtomasz@chromium.org</owner>
-  <summary>
-    Sizes of files being downloaded from Drive. Temporary histogram for
-    gathering data for http://crbug.com/229650.
-  </summary>
-</histogram>
-
-<histogram name="Drive.EntireFeedLoadTime" units="microseconds"
-    expires_after="2013-12-03">
-  <obsolete>
-    Removed 12/2013 due to the UMA stat bucket layout change. We'll use
-    Drive.FullFeedLoadTime instead.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Time spent to load the entire file system information from the server
-  </summary>
-</histogram>
-
-<histogram name="Drive.EntryKind" enum="DriveEntryKind"
-    expires_after="2013-12-03">
-  <obsolete>
-    Removed 10/2012.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Provides breakdown of specific formats for hosted documents. Recorded when
-    feed is loaded from the server.
-  </summary>
-</histogram>
-
-<histogram name="Drive.FileFormat" enum="DriveFileFormat"
-    expires_after="2013-12-03">
-  <obsolete>
-    Removed 10/2012.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Provides breakdown of specific file formats for regular files. Recorded when
-    feed is loaded from the server.
-  </summary>
-</histogram>
-
-<histogram name="Drive.FilesListRequestRunner.ApiErrorCode"
-    enum="DriveApiErrorCode" expires_after="2019-02-15">
-  <obsolete>
-    Obsolete 02/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>mtomasz@chromium.org</owner>
-  <summary>
-    Error codes returned by the Drive API for files list requests executed via
-    the FilesListRequestRunner class.
-  </summary>
-</histogram>
-
-<histogram name="Drive.FilesListRequestRunner.MaxResults" units="units"
-    expires_after="2019-02-15">
-  <obsolete>
-    Obsolete 02/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>mtomasz@chromium.org</owner>
-  <summary>
-    Maximum number of results for each files list request using the Drive API.
-  </summary>
-</histogram>
-
-<histogram name="Drive.FullFeedLoadTime" units="ms" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Time spent to load the entire file system information from the server
-  </summary>
-</histogram>
-
-<histogram name="Drive.InitialFeedLoadTime" units="microseconds"
-    expires_after="2013-12-03">
-  <obsolete>
-    Deperecated 12/2013 since it did not record meaningful information.
-    Drive.DirectoryFeedLoadTime should be checked for measuring the time until
-    the user sees the first response of file lists.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Time spent to load the initial part of the file system information from the
-    server
-  </summary>
-</histogram>
-
-<histogram name="Drive.MetadataDBInitResult" enum="DriveMetadataDBInitStatus"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>Result of drive resource metadata database initialization.</summary>
-</histogram>
-
-<histogram name="Drive.MetadataDBOpenExistingResult"
-    enum="DriveMetadataDBInitStatus" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Result of attempt to open existing drive resource metadata database.
-  </summary>
-</histogram>
-
-<histogram name="Drive.MetadataDBValidityCheckFailureReason"
-    enum="DriveMetadataDBValidityCheckFailureReason" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Reason of drive resource metadata database validity check failure. Recorded
-    when the validity check fails during Drive metadata initialization triggered
-    by profile initialization.
-  </summary>
-</histogram>
-
-<histogram name="Drive.MetadataDBVersionBeforeUpgradeCheck" units="units"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Version number of drive resource metadata DB found on the disk before
-    checking whether it should be upgraded. Recorded during Drive metadata
-    initialization triggered by profile initialization.
-  </summary>
-</histogram>
-
-<histogram name="Drive.MigrateDirtyFilesCount" units="units"
-    expires_after="2019-10-01">
-  <obsolete>
-    Obsolete 08/2019. Most migrations are complete, we no longer need this.
-  </obsolete>
-  <owner>dats@chromium.org</owner>
-  <owner>sammc@chromium.org</owner>
-  <summary>
-    Records the number of dirty (unsynced) files migrated from legacy Drive to
-    DriveFs.
-  </summary>
-</histogram>
-
-<histogram name="Drive.NumberOfCacheFilesRecoveredAfterDBCorruption"
-    units="units" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Number of files recovered from Drive cache directory. Recorded when file
-    recovery takes place after metadata DB corruption is found during metadata
-    DB initialization.
-  </summary>
-</histogram>
-
-<histogram name="Drive.NumberOfHostedDocuments" units="units"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Number of hosted documents (spreadsheets etc.) on Drive. Logged when Drive
-    is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="Drive.NumberOfRegularFiles" units="units" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Number of regualr files on Drive. Logged when Drive is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="Drive.NumberOfTotalFiles" units="units" expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Number of total files (regualr files + hosted documents) on Drive. Logged
-    when Drive is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="Drive.SearchMetadataTime" units="microseconds"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Time spent to perform an incremental search for auto completion of files on
-    Drive. This time is collected for every partial query the user types for
-    auto completion. For instance, if the user types &quot;faq&quot;,
-    incremental searches are performed for &quot;f&quot;, &quot;fa&quot;, and
-    &quot;faq&quot; respectively.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Drive.TotalFileCountInBatchUpload" units="units"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>Total file count contained in a drive batch upload request.</summary>
-</histogram>
-
-<histogram name="Drive.TotalFileSizeInBatchUpload" units="KB"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>Total file size contained in a drive batch upload request.</summary>
-</histogram>
-
-<histogram name="Drive.TransferBlockedOnJobs" units="jobs"
-    expires_after="2019-02-15">
-  <obsolete>
-    This was a temporary histogram for bug http://crbug.com/229650 that has been
-    closed.
-  </obsolete>
-  <owner>mtomasz@chromium.org</owner>
-  <summary>
-    Number of jobs which have to be completed before a newly added download or
-    download from or to Drive is requested. Temporary histogram for gathering
-    data for http://crbug.com/229650.
-  </summary>
-</histogram>
-
-<histogram name="Drive.UploadProtocol" enum="DriveUploadProtocol"
-    expires_after="M75">
-  <obsolete>
-    Obsolete 04/2019 as DriveFS implementation obsoletes this metric.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Upload protocol for each file. e.g. Batch upload including 5 files triggers
-    the metric 5 times.
-  </summary>
-</histogram>
-
-<histogram name="Drive.UploadToDriveFileSize" units="KB"
-    expires_after="2019-02-15">
-  <obsolete>
-    This was a temporary histogram for bug http://crbug.com/229650 that has been
-    closed.
-  </obsolete>
-  <owner>mtomasz@chromium.org</owner>
-  <summary>
-    Sizes of files being uploaded to Drive. Temporary histogram for gathering
-    data for http://crbug.com/229650.
-  </summary>
-</histogram>
-
-<histogram name="DrmUtil.CreateDisplaySnapshot.EdidBlobIsEmpty" enum="Boolean"
-    expires_after="2021-02-07">
-  <obsolete>
-    Converted to DCHECK in 08/2020. If EDID property is unset, blob is always
-    NULL.
-  </obsolete>
-  <owner>andrescj@chromium.org</owner>
-  <owner>mcasas@chromium.org</owner>
-  <owner>chromeos-gfx@google.com</owner>
-  <summary>
-    True when an EDID blob is detected and is empty. This UMA is recorded
-    whenever we attempt to parse the EDID from a display.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.AuthenticationSuccess" enum="BooleanSuccess"
-    expires_after="2018-04-06">
-  <obsolete>
-    Removed as of 03/2018.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    When Easy Unlock attempts to authenticate the secure connection between a
-    Chromebook (or other Chrome device) and an Android phone, whether the
-    authentication succeeded.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.AuthProximity.TimeSinceLastZeroRssi" units="ms"
-    expires_after="2018-11-14">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>tengs@chromium.org</owner>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Measures the time delta in milliseconds since the last zero RSSI value was
-    read to when the user successfully unlocks or signs in using Smart Lock.
-
-    A zero RSSI value is special because both Bluetooth devices in a connection
-    attempt to maintain by adjusting their transmit power levels. This time
-    delta can be used as a possible heuristic to determine that the phone is
-    close to the local device.
-
-    If no RSSI was read, then an overflow value will be recorded.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.AuthProximity.TransmitPowerDelta" units="dBm"
-    expires_after="2018-11-14">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>tengs@chromium.org</owner>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Measures the difference between the current transmit power and the maximum
-    transmit power of the local device when the user successfully unlocks or
-    signs in using Smart Lock.
-
-    Devices connected using classic Bluetooth adjust their transmit power
-    dynamically to optimize power and signal strength. The difference between
-    the current transmit power and maximum transmit power can be used as a
-    heurstic to determine if the phone is close to the local device.
-
-    According to the Bluetooth specs, there are three classes of devices, with a
-    maximum transmit power of 20, 4, and 0 dBm respectively.
-
-    If no transmit power was read, then a sentinel value of 127 will be
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.BluetoothAvailability"
-    enum="EasyUnlockBluetoothType" expires_after="2017-02-18">
-  <obsolete>
-    Removed as of 02/2017.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Reports the type of Bluetooth adapter present in the device.
-
-    Statistics about what Bluetooth capabilities are available will determine
-    how the EasyUnlock feature gets developed and deployed across platforms.
-
-    This value is logged only once during the lifetime of the Chrome process,
-    shortly after it starts up. If a Bluetooth USB adapter is inserted after
-    that point, the change will not be registered until Chrome restarts.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.ClickedButton" enum="EasyUnlockButton"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>Button clicked in EasyUnlock app during setup process.</summary>
-</histogram>
-
-<histogram name="EasyUnlock.NotificationEvent"
-    enum="EasyUnlockNotificationEvent" expires_after="2015-02-24">
-  <obsolete>
-    Removed 02/2015. Replaced by EasyUnlock.Setup.PromoNotificationEvent.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Tracks events related to notifications used by EasyUnlock feature. For
-    example a specific EasyUnlock notification being shown or clicked.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Devices.Count.Eligible" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The number of eligible devices that the CryptAuth server returns during the
-    Smart Lock setup flow.
-
-    Note that a single user might report multiple values, for example if they
-    try to complete the setup flow with a device in airplane mode, and then try
-    again taking the device out of airplane mode.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Devices.Count.Ineligible" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The number of ineligible devices that the CryptAuth server returns during
-    the Smart Lock setup flow.
-
-    Note that a single user might report multiple values, for example if they
-    try to complete the setup flow with a device in airplane mode, and then try
-    again taking the device out of airplane mode.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Devices.HasSecureScreenLock"
-    enum="EasyUnlockHasSecureScreenLock" expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Whether the user's phone has a secure screen lock installed. Recorded during
-    Smart Lock setup, when the user's phone first connects to the Chromebook.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Devices.HasTrustAgentEnabled"
-    enum="EasyUnlockHasTrustAgentEnabled" expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Whether the user's phone has a trust agent -- e.g. Smart Lock for Android --
-    enabled. Recorded during Smart Lock (for Chrome) setup, when the user's
-    phone first connects to the Chromebook.
-
-    Note that this histogram tracks whether the setting under Settings ~&gt;
-    Security ~&gt; Trust agents ~&gt; Smart Lock (Google) (or any other trust
-    agent) is enabled. The Smart Lock trust agent is enabled by default for
-    users who have ascure lock screen. This metric does _not_ measure whether
-    users have any Smart Lock trustlets enabled.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Devices.IneligibilityReason"
-    enum="EasyUnlockDeviceIneligibilityReason" expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Records the most actionable reason why none of a user's devices were
-    eligible as unlock keys for Smart Lock. This is recorded during the Smart
-    Lock setup flow, only if the CryptAuth server returns no eligible devices
-    for the user.
-
-    To be precise, this metric tracks the _least_ actionable _reason_ why the
-    _most_ actionable _device_ is not eligible as an unlock key. For example,
-    suppose that the user has 10 ineligible devices returned. This metric tries
-    to identify the most likely candidate device for use as a Smart Lock key,
-    and then records the most confounding reason why that device is still not
-    eligible to be used as an unlock key.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Progress.SansPromo"
-    enum="EasyUnlockSetupProgress" expires_after="M80">
-  <obsolete>
-    Removed as of 03/2018.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <owner>jhawkins@chromium.org</owner>
-  <summary>
-    Records events at each step of the Setup process, when the Setup flow is
-    initiated without the promotion notification.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.Progress.ViaPromo"
-    enum="EasyUnlockSetupProgress" expires_after="M80">
-  <obsolete>
-    Removed as of 03/2018.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <owner>jhawkins@chromium.org</owner>
-  <summary>
-    Records events at each step of the Setup process, when the Setup flow is
-    initiated via the promotion notification.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.Setup.PromoNotificationEvent"
-    enum="EasyUnlockPromoNotificationEvent" expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Measures user interactions with the Smart Lock promo notification.
-
-    Due to technical limitations of the implementation, it is hard to track
-    precisely which users opened the setup app as a result of interacting with
-    the promo notification. This metric measures setup app interactions from all
-    users who click on the promo notification, and subsequently launch the setup
-    app.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.SetupStateOnClose" enum="EasyUnlockSetupState"
-    expires_after="2018-04-06">
-  <obsolete>
-    Removed as of 03/2018.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    The state of EasyUnlock setup when the app window was closed by user.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.SignIn.LoginEvent" enum="EasyUnlockAuthEvent"
-    expires_after="2015-02-11">
-  <obsolete>
-    Removed 02/2015; replaced by EasyUnlock.AuthEvent.SignIn.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Measures the use of Easy sign-in: records whether an Easy sign-in login
-    succeeded or failed; or if a password fallback was used, the reason why.
-    Recorded upon a login attempt for users who have the Easy sign-in feature
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.TrialRun.Events" enum="EasyUnlockTrialRunEvents"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Records when the Easy Unlock trial run is launched, and when the user
-    attempts to click on the lock icon during the trial run.
-
-    If a user clicks on the lock icon more than once, then the &quot;clicked
-    lock icon&quot; event counter will be incremented more than once as well.
-    Hence, the &quot;user count&quot; data shows how many users ever clicked on
-    the lock icon during the trial run. From the raw (non-&quot;user
-    count&quot;) data, we can also see whether users click on the icon multiple
-    times.
-  </summary>
-</histogram>
-
-<histogram name="EasyUnlock.UnlockEvent" enum="EasyUnlockUnlockEvent"
-    expires_after="2015-02-11">
-  <obsolete>
-    Removed 02/2015; replaced by EasyUnlock.AuthEvent.Unlock.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>Screen unlock events detected while EasyUnlock was enabled.</summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ExistingProcessAllocation" units="ms"
-    expires_after="2016-04-07">
-  <obsolete>
-    Removed 03/2016; replaced by
-    EmbeddedWorkerInstance.Start.SendStartWorker_ExistingProcess and
-    EmbeddedWorkerInstance.Start.TimeToURLJob_ExistingProcess.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time taken to allocate a process to start the EmbeddedWorkerInstance.
-    Recorded when an existing process was used.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.NewProcessAllocation" units="ms"
-    expires_after="2016-04-07">
-  <obsolete>
-    Removed 03/2016; replaced by
-    EmbeddedWorkerInstance.Start.SendStartWorker_NewProcess and
-    EmbeddedWorkerInstance.Start.TimeToURLJob_NewProcess.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time taken to allocate a process to start the EmbeddedWorkerInstance.
-    Recorded when a new process was created.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ProcessAllocation" units="ms"
-    expires_after="2015-05-26">
-  <obsolete>
-    Removed as of 05/2015. Replaced by
-    EmbeddedWorkerInstance.NewProcessAllocation and
-    EmbeddedWorkerInstance.ExistingProcessAllocation.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken to allocate a process to start the EmbeddedWorkerInstance.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ProcessCreated" enum="BooleanCreated"
-    expires_after="2020-06-23">
-  <obsolete>
-    Removed as of June 2020. If you find it's useful and add the metric again,
-    please consider using an enum of StartSituation instead of a boolean.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    Whether a new renderer process was created for the EmbeddedWorkerInstance or
-    existing one was used. Only recorded for installed workers.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ScriptEvaluate" units="ms"
-    expires_after="2016-04-07">
-  <obsolete>
-    Removed as of 03/2016. Replaced by
-    EmbeddedWorkerInstance.Start.TimeToEvaluateScript.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken to evaluate the script to start the EmbeddedWorkerInstance.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ScriptLoadWithNetworkAccess" units="ms"
-    expires_after="2016-04-07">
-  <obsolete>
-    Removed as of 03/2016. Replaced by
-    EmbeddedWorkerInstance.Start.TimeToLoad_Network.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken to load the script file for the EmbeddedWorkerInstance with
-    network access.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.ScriptLoadWithoutNetworkAccess"
-    units="ms" expires_after="2016-04-07">
-  <obsolete>
-    Removed as of 03/2016. Replaced by
-    EmbeddedWorkerInstance.Start.TimeToLoad_HttpCache and
-    EmbeddedWorkerInstance.Start.TimeToLoad_InstalledScript.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken to load the script file for the EmbeddedWorkerInstance
-    without network access.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency" units="ms"
-    expires_after="2018-06-29">
-  <obsolete>
-    Removed June 2018 (M69). Replaced with
-    ServiceWorker.StartTiming.SentStartWorkerToReceivedStartWorker.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time between the browser sending a &quot;start a service worker&quot;
-    message to the renderer, and the renderer receiving it. This may include
-    renderer startup time. Only recorded if the high-resolution system clock was
-    used and deemed consistent across proceses, and the time was non-negative
-    (see EmbeddedWorkerInstance.Start.StartMessageLatency.Type). Only recorded
-    for installed workers. Recorded upon successful startup.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency.Type"
-    enum="CrossProcessTimeDelta" expires_after="2018-06-29">
-  <obsolete>
-    Removed June 2018 (M69). Replaced with
-    ServiceWorker.StartTiming.ClockConsistency.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    See EmbeddedWorkerInstance.Start.StartMessageLatency. Describes the outcome
-    of taking the measurement and whether StartMessageLatency was recorded.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToEvaluateScript" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018 (M69). Replaced with
-    ServiceWorker.StartTiming.ScriptEvaluationStartToScriptEvaluationEnd.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken for initial evaluation of the service worker script.
-    Specifically, the time between ACK from the renderer that the thread started
-    and ACK that the script evaluation finished. Only recorded for installed
-    workers.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToLoad.HttpCache" units="ms"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed June 2018 (M69). This depended on the URLRequestJob code path, which
-    won't be taken with S13nServiceWorker/NetworkService. If we want this again,
-    it can be logged from ServiceWorkerScriptLoader or in Blink directly using
-    Resource Timing.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken to load a new (not installed) service worker, when it came
-    from the HTTP cache.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToLoad.InstalledScript"
-    units="ms" expires_after="2018-06-25">
-  <obsolete>
-    Removed June 2018 (M69). This path is no longer taken since service worker
-    installed script manager is used for installed scripts.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>The time taken to load an installed service worker.</summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToLoad.Network" units="ms"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed June 2018 (M69), see note in
-    EmbeddedWorkerInstance.Start.TimeToLoad.HttpCache.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken to load a new (not installed) service worker, when it came
-    from the network.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToSendStartWorker" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018 (M69). Replaced with
-    ServiceWorker.StartTiming.StartToSentStartWorker.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken between deciding to start a worker and sending the start
-    worker IPC. Only recorded for installed workers.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToStartThread" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018 (M69). Replaced with
-    ServiceWorker.StartTiming.ReceivedStartWorkerToScriptEvaluationStart.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken to start the service worker thread. Specifically, the time
-    between ACK from the renderer that load finished and ACK that the thread
-    started. Does not include script evaluation time. Only recorded for
-    installed workers.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.TimeToURLJob" units="ms"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed June 2018 (M69). This path is no longer taken since service worker
-    installed script manager is used for installed scripts.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The round-trip time between asking the renderer process to start a worker
-    and receiving the corresponding resource request. Only recorded for
-    installed workers.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.WaitedForRendererSetup"
-    enum="BooleanWaited" expires_after="2018-06-27">
-  <obsolete>
-    Removed June 2018 (M69).
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Indicates if Blink was not initialized by the time the browser sent a
-    &quot;start a service worker&quot; message to the renderer. If this is true,
-    receiving the message had to wait until after Blink initialization finished.
-    Blink initialization is considered the time RenderThreadImpl::Init sets up
-    the Mojo interface for receiving the &quot;start a service worker&quot;
-    message. Only recorded for installed workers. Recorded upon successful
-    startup.
-  </summary>
-</histogram>
-
-<histogram name="EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time"
-    units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed June 2018 (M69).
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Recorded when EmbeddedWorkerInstance.Start.WaitedForRendererSetup is true.
-    The time between when the &quot;start a service worker&quot; was sent by the
-    browser, and Blink initialization finishing. The start time is recorded by
-    the browser process, and the end time by the renderer process, so process
-    clock skew could possibly affect the result.
-  </summary>
-</histogram>
-
-<histogram name="EnhancedBookmarks.AllBookmarksCount" units="units"
-    expires_after="2016-05-04">
-  <obsolete>
-    Removed 4/2016 after we no longer show &quot;all bookamrks&quot; in bookmark
-    manager.
-  </obsolete>
-  <owner>ianwen@chromium.org</owner>
-  <summary>Number of bookmarks the user has. Android only.</summary>
-</histogram>
-
-<histogram name="EnhancedBookmarks.SyncExperimentState"
-    enum="BookmarksExperimentState" expires_after="2015-03-17">
-  <obsolete>
-    Removed 3/2015 along with the enhanced bookmarks sync experiment.
-  </obsolete>
-  <owner>noyau@chromium.org</owner>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Captures the state the enhanced bookmark experiment is in. Recorded on
-    startup. To be removed once the enhanced bookmark experiment is finished.
-    see crbug/323423.
-  </summary>
-</histogram>
-
-<histogram name="EnhancedBookmarks.ViewMode" enum="EnhancedBookmarkViewMode"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 9/2015 after list view became the only view mode.
-  </obsolete>
-  <owner>ianwen@chromium.org</owner>
-  <summary>
-    Record which Enhanced Bookmark UI mode users are in. This will be recorded
-    everytime the user opens the bookmark manager UI.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.AppRestrictionLoadTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Code removed in M46.
-  </obsolete>
-  <owner>aberent@chromium.org</owner>
-  <summary>
-    Android Only - Time to load the App Restrictions from the O.S..
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.AppRestrictionsCacheLoad" enum="BooleanSuccess"
-    expires_after="M85">
-  <obsolete>
-    Code removed in M46.
-  </obsolete>
-  <owner>aberent@chromium.org</owner>
-  <summary>
-    Android Only - Whether Chrome was able to read and decode the
-    AppRestrictions policy cache on startup.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.CloudReportingStaleProfileCount" units="profiles"
-    expires_after="2020-06-09">
-  <obsolete>
-    Removed 06/2020 because enough data had been gathered.
-  </obsolete>
-  <owner>zmin@chromium.org</owner>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    The number of profiles that miss at least one report and may not be able to
-    catch the next round due to browser shutdown. The metric is recorded during
-    browser shutdown process.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DevicePolicyInvalidations"
-    enum="EnterprisePolicyInvalidations" expires_after="2021-03-01">
-  <obsolete>
-    Removed 03/2020 in order to separate device and device local account.
-    Superseded by Enterprise.DevicePolicyInvalidations2 and
-    Enterprise.DeviceLocalAccountPolicyInvalidations2.
-  </obsolete>
-  <owner>asumaneev@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    Events for counting both device and device local account policies
-    invalidations received with and without payloads. Invalidations indicate
-    that a policy has been updated and should be refreshed. Payloads provide
-    context about the policy update, but may be absent if dropped by the
-    invalidation service.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DevicePolicyRefresh" enum="EnterprisePolicyRefresh"
-    expires_after="2020-02-23">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.DevicePolicyRefresh2.
-  </obsolete>
-  <owner>bartfab@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing device policy when
-    invalidations are received from a service. For each refresh, indicates
-    whether the policy changed, and whether the policy was invalidated at the
-    time of the refresh.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DevicePolicyRefresh2"
-    enum="EnterprisePolicyRefresh" expires_after="2021-03-01">
-  <obsolete>
-    Removed 03/2020 in order to separate device and device local account.
-    Superseded by Enterprise.DevicePolicyRefresh3 and
-    Enterprise.DeviceLocalAccountPolicyRefresh3.
-  </obsolete>
-  <owner>asumaneev@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    Events measuring effectiveness of refreshing both device and device local
-    account policies when invalidations are received from a service. For each
-    refresh, indicates whether the policy changed, and whether the policy was
-    invalidated at the time of the refresh.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DMToken" enum="EnterpriseDMTokenType"
-    expires_after="2019-03-15">
-  <obsolete>
-    Removed 03/2019, since no code reports it anymore.
-  </obsolete>
-  <owner>mnissler@chromium.org</owner>
-  <summary>
-    Events related to fetching, saving and loading DM server tokens. These are
-    used to retrieve cloud policies.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DomainWhitelistRegexFailure"
-    enum="EnterpriseDomainRegex" expires_after="2019-03-28">
-  <obsolete>
-    Removed 03/2019, since the issues has been long fixed.
-  </obsolete>
-  <owner>atwilson@chromium.org</owner>
-  <summary>
-    Temporary metric tracking which regex caused an icu::RegexMatcher
-    initialization failure, to help figure out the cause of
-    http://crbug.com/365351 which we can't repro locally.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DomainWhitelistRegexFailureStatus"
-    units="icu error" expires_after="2019-03-28">
-  <obsolete>
-    Removed 03/2019, since the issues has been long fixed.
-  </obsolete>
-  <owner>atwilson@chromium.org</owner>
-  <summary>
-    Temporary metric tracking the type of an icu::RegexMatcher initialization
-    failure, to help figure out the cause of http://crbug.com/365351 which we
-    can't repro locally.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.DomainWhitelistRegexSuccess" enum="BooleanSuccess"
-    expires_after="2019-03-28">
-  <obsolete>
-    Removed 03/2019, since the issues has been long fixed.
-  </obsolete>
-  <owner>atwilson@chromium.org</owner>
-  <summary>
-    Temporary metric tracking the success of icu::RegexMatcher IcuMatcher
-    initialization, to help figure out the cause of http://crbug.com/365351.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.FCMInvalidationService.DevicePolicyInvalidations"
-    enum="EnterprisePolicyInvalidations" expires_after="2021-03-01">
-  <obsolete>
-    Removed 03/2020 in order to separate device and device local account.
-    Superseded by Enterprise.FCMInvalidationService.DevicePolicyInvalidations2
-    and
-    Enterprise.FCMInvalidationService.DeviceLocalAccountPolicyInvalidations2.
-  </obsolete>
-  <owner>asumaneev@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    Events for counting both device and device local account policies
-    invalidations received with and without payloads. Invalidations indicate
-    that a policy has been updated and should be refreshed. Payloads provide
-    context about the policy update, but may be absent if dropped by the
-    invalidation service. Subset of
-    &quot;Enterprise.DevicePolicyInvalidations&quot;. Gets recorded only when
-    FCMInvalidationService is used as InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.FCMInvalidationService.DevicePolicyRefresh"
-    enum="EnterprisePolicyRefresh" expires_after="2020-03-01">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.FCMInvalidationService.DevicePolicyRefresh2.
-  </obsolete>
-  <owner>askaraitzhan@google.com</owner>
-  <owner>isandrk@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing device policy when
-    invalidations are received from a service. For each refresh, indicates
-    whether the policy changed, and whether the policy was invalidated at the
-    time of the refresh. Subset of &quot;Enterprise.DevicePolicyRefresh&quot;.
-    Gets recorded only when FCMInvalidationService is used as
-    InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.FCMInvalidationService.DevicePolicyRefresh2"
-    enum="EnterprisePolicyRefresh" expires_after="2021-03-01">
-  <obsolete>
-    Removed 03/2020 in order to separate device and device local account.
-    Superseded by Enterprise.FCMInvalidationService.DevicePolicyRefresh3 and
-    Enterprise.FCMInvalidationService.DeviceLocalAccountPolicyRefresh3.
-  </obsolete>
-  <owner>asumaneev@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    Events measuring effectiveness of refreshing both device and device local
-    account policies when invalidations are received from a service. For each
-    refresh, indicates whether the policy changed, and whether the policy was
-    invalidated at the time of the refresh. Subset of
-    &quot;Enterprise.DevicePolicyRefresh2&quot;. Gets recorded only when
-    FCMInvalidationService is used as InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.FCMInvalidationService.PolicyRefresh"
-    enum="EnterprisePolicyRefresh" expires_after="2020-03-08">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.FCMInvalidationService.PolicyRefresh2.
-  </obsolete>
-  <owner>askaraitzhan@google.com</owner>
-  <owner>isandrk@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing user policy when invalidations
-    are received from a service. For each refresh, indicates whether the policy
-    changed, and whether the policy was invalidated at the time of the refresh.
-    Subset of &quot;Enterprise.PolicyRefresh&quot;. Gets recorded only when
-    FCMInvalidationService is used as InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.InvalidDevicePolicyFiles" units="files"
-    expires_after="2020-07-02">
-  <obsolete>
-    Removed 10/2019, since no code reports it anymore. Superseded by
-    Enterprise.InvalidDevicePolicyFilesStatus.
-  </obsolete>
-  <owner>emaxx@chromium.org</owner>
-  <owner>igorcov@chromium.org</owner>
-  <summary>
-    Chrome OS only. Number of policy files that turned out to be invalid when
-    reading the device policy data. In success scenario the latest policy file
-    read is successful and has valid data submitting zero for this statistic.
-  </summary>
-</histogram>
-
-<histogram
-    name="Enterprise.MachineLevelUserCloudPolicyEnrollment.InstallLevel_Win"
-    enum="BooleanIsSystemLevelInstall" expires_after="2020-03-08">
-  <obsolete>
-    Remove in M82. Because we decide not to handle user level enrollment
-    separately.
-  </obsolete>
-  <owner>zmin@chromium.org</owner>
-  <summary>
-    Records whether the Chrome install is system level or user level when trying
-    to enroll into the machine level user cloud policy on Windows. This is
-    intended to count the number of enrollments for each install type.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.Policy" enum="EnterprisePolicyType"
-    expires_after="2019-03-15">
-  <obsolete>
-    Removed 03/2019, since no code reports it anymore.
-  </obsolete>
-  <owner>mnissler@chromium.org</owner>
-  <summary>
-    Events related to fetching, saving and loading user policies, and also
-    device policies on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.PolicyRefresh" enum="EnterprisePolicyRefresh"
-    expires_after="2020-03-01">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.PolicyRefresh2.
-  </obsolete>
-  <owner>mnissler@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing user policy when invalidations
-    are received from a service. For each refresh, indicates whether the policy
-    changed, and whether the policy was invalidated at the time of the refresh.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.ResourceCacheTiming" units="ms"
-    expires_after="2020-03-01">
-  <obsolete>
-    Removed 01/2020 since the histogram indicators were stable.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <summary>The time to perform operations on the ResourceCache object.</summary>
-</histogram>
-
-<histogram name="Enterprise.SchemaMismatchedValueIgnored" enum="BooleanSuccess"
-    expires_after="2020-08-02">
-  <obsolete>
-    Removed 01/2020 because SCHEMA_ALLOW_INVALID strategy was removed.
-  </obsolete>
-  <owner>poromov@chromium.org</owner>
-  <owner>hendrich@chromium.org</owner>
-  <summary>
-    Signals whether mismatched value was ignored while validating while using
-    SCHEMA_ALLOW_INVALID strategy. The strategy is used only for
-    ManagedBookmarks policy and is considered for deprecation. Recorded when
-    policy is validated using SCHEMA_ALLOW_INVALID strategy.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.SystemLogPIILeak" enum="SystemLogPIIType"
-    expires_after="2016-01-26">
-  <obsolete>
-    Removed and removed from code as of 01/2016.
-  </obsolete>
-  <owner>pbond@chromium.org</owner>
-  <summary>
-    Events for counting sensitive data occurrences in system logs to upload.
-    (Email addresses, IP addresses, SSIDs, URLs). The lines with this data will
-    be removed before upload.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.TiclInvalidationService.DevicePolicyRefresh"
-    enum="EnterprisePolicyRefresh" expires_after="2020-03-01">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.TiclInvalidationService.DevicePolicyRefresh2.
-  </obsolete>
-  <owner>askaraitzhan@google.com</owner>
-  <owner>isandrk@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing device policy when
-    invalidations are received from a service. For each refresh, indicates
-    whether the policy changed, and whether the policy was invalidated at the
-    time of the refresh. Subset of &quot;Enterprise.DevicePolicyRefresh&quot;.
-    Gets recorded only when TiclInvalidationService is used as
-    InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="Enterprise.TiclInvalidationService.PolicyRefresh"
-    enum="EnterprisePolicyRefresh" expires_after="2020-03-01">
-  <obsolete>
-    Removed 10/2019 because was recorded incorrectly. Superseded by
-    Enterprise.TiclInvalidationService.PolicyRefresh2.
-  </obsolete>
-  <owner>askaraitzhan@google.com</owner>
-  <owner>isandrk@chromium.org</owner>
-  <summary>
-    Events measuring effectiveness of refreshing user policy when invalidations
-    are received from a service. For each refresh, indicates whether the policy
-    changed, and whether the policy was invalidated at the time of the refresh.
-    Subset of &quot;Enterprise.PolicyRefresh&quot;. Recorded only when
-    TiclInvalidationService was used as InvalidationService.
-  </summary>
-</histogram>
-
-<histogram name="EnterpriseCheck.DeprecatedDomainBindSucceeded"
-    enum="BooleanSuccess" expires_after="2016-07-19">
-  <obsolete>
-    Removed 07/2016 in Issue 621270.
-  </obsolete>
-  <owner>mnissler@chromium.org</owner>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    Whether we were able to contact the AD Domain Controller. This check is
-    performed once at start-up on Windows.
-  </summary>
-</histogram>
-
-<histogram name="EnterpriseCheck.DeprecatedDomainCheckFailed"
-    enum="EnterpriseCheckError" expires_after="2016-07-19">
-  <obsolete>
-    Removed 07/2016 in Issue 621270.
-  </obsolete>
-  <owner>mnissler@chromium.org</owner>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    Enum of possible things that can fail while checking for enterprise env.
-    This check is performed once at start-up on Windows.
-  </summary>
-</histogram>
-
-<histogram name="EnterpriseCheck.IsFullyManaged" enum="IsFullyManagedBoolean"
-    expires_after="2020-12-01">
-  <obsolete>
-    Removed M85, obsoleted by IsFullyManaged2 because recording frequency
-    changed from once per session to once per app start. Note that the summary
-    of this histogram incorrectly stated otherwise.
-  </obsolete>
-  <owner>twellington@google.com</owner>
-  <owner>tedchcoc@chromium.org</owner>
-  <summary>
-    On Android (OS version M+): Whether the device has a &quot;device
-    owner&quot; app installed. This check is performed once at start-up.
-  </summary>
-</histogram>
-
-<histogram name="EnterpriseCheck.IsManaged" enum="BooleanEnabled"
-    expires_after="2020-12-01">
-  <obsolete>
-    Removed M85, obsoleted by IsManaged2 because recording frequency changed on
-    Android from once per session to once per app start.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    On Windows: Whether the machine is managed via MDM. On macOS: Whether Chrome
-    found a file of managed policies to follow. On Android (up to M84: OS
-    version M+, M85+: OS version Lollipop+): Whether the device has a profile
-    owner app. This check is performed once at start-up. Note that this data is
-    bogus before M81 on the Mac.
-  </summary>
-</histogram>
-
-<histogram name="Event.ActionAfterDoubleTapNoDelay" enum="ActionAfterDoubleTap"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    On non-mobile sites, gesture taps are delayed to prevent double taps from
-    sending a click event. This stat tracks the user's first action within 5
-    seconds after a double tap gesture when the gesture tap delay is disabled.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.ActionAfterDoubleTapWithDelay"
-    enum="ActionAfterDoubleTap" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    On non-mobile sites, gesture taps are delayed to prevent double taps from
-    sending a click event. This stat tracks the user's first action within 5
-    seconds after a double tap gesture when gesture tap events are delayed.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.AsyncTargeting.TimeInQueue" units="ms"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed as of 01/2020. The feature has been launched.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <summary>
-    Tracks how long an event has to wait in the queue while a previous event is
-    being targeted asynchronously.
-
-    Team: event-targeting@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.CoalescedCount.Mouse" units="units" expires_after="M81">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>Number of Mouse events coalesced.</summary>
-</histogram>
-
-<histogram name="Event.CoalescedCount.Touch" units="units" expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>Number of Touch events coalesced.</summary>
-</histogram>
-
-<histogram name="Event.CoalescedLatency.Mouse" units="ms"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the first and last events in a coalesced mouse events group.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.CoalescedLatency.Touch" units="ms"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the first and last events in a coalesced touch events group.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.CompositorThreadEventQueue.CoalescedCount"
-    units="events" expires_after="2019-01-03">
-  <obsolete>
-    Removed 01/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Number of continuous gesture events (GestureScrollUpdate,
-    GesturePinchUpdate) coalesced inside the compositor thread event queue per
-    event. This field is recorded just before the event is processed on the
-    compositor thread.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.CompositorThreadEventQueue.Continuous.HeadQueueingTime"
-    units="microseconds" expires_after="2019-01-03">
-  <obsolete>
-    Removed 01/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Time between the first event in a coalesced continuous gesture events group
-    (GestureScrollUpdate, GesturePinchUpdate) and when it was processed on the
-    compositor thread.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.CompositorThreadEventQueue.Continuous.TailQueueingTime"
-    units="microseconds" expires_after="2019-01-03">
-  <obsolete>
-    Removed 01/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Time between the last event in a coalesced continuous gesture events group
-    (GestureScrollUpdate, GesturePinchUpdate) and when it was processed on the
-    compositor thread.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.CompositorThreadEventQueue.NonContinuous.QueueingTime"
-    units="microseconds" expires_after="2019-01-03">
-  <obsolete>
-    Removed 01/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Time between when a non-continuous gesture event (GestureScrollStart/End,
-    GesturePinchStart/End) was placed into the queue and when it was processed
-    on the compositor thread.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.DownEventCount.PerDestination"
-    enum="DownEventDestination" expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018 in favor of
-    Event.DownEventCount.PerInputFormFactorDestinationCombination.
-  </obsolete>
-  <owner>xiaoyinh@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The number of down events received per destination. Every down event that is
-    targeted to each destination will be counted, including those that don't
-    have an effect. For example: Tapping on a disabled button inside the browser
-    frame will be treated as down events on browser window.
-  </summary>
-</histogram>
-
-<histogram name="Event.DownEventCount.PerFormFactor" enum="DownEventFormFactor"
-    expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018 in favor of
-    Event.DownEventCount.PerInputFormFactorDestinationCombination.
-  </obsolete>
-  <owner>xiaoyinh@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    Counts the number of down events generated by clamshell/touchview.
-  </summary>
-</histogram>
-
-<histogram name="Event.DownEventCount.PerInput" enum="DownEventSource"
-    expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018 in favor of
-    Event.DownEventCount.PerInputFormFactorDestinationCombination.
-  </obsolete>
-  <owner>xiaoyinh@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    Counts the number of down events generated by Mouse/Touch/Stylus.
-  </summary>
-</histogram>
-
-<histogram name="Event.DownEventCount.PerInputFormFactorDestinationCombination"
-    enum="DownEventInputFormFactorDestinationCombination" expires_after="M76">
-  <obsolete>
-    Removed 02/2019 in favor of
-    Event.DownEventCount.PerInputFormFactorDestinationCombination2.
-  </obsolete>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The number of down events received per input, form factor, and destination
-    combination.
-
-    Input is down events generated by mouse/touch/stylus. Form factor is down
-    events generated by clamshell/touchviewLandscape/touchviewPortrait.
-    Destination: Every down event that is targeted to each destination will be
-    counted including those that don't have an effect. For example: Tapping on a
-    disabled button inside the browser frame will be treated as down events on
-    browser window.
-  </summary>
-</histogram>
-
-<histogram name="Event.DragDrop.AcceptDragUpdate" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    Removed 06/2020 as being expired.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    Reports whether chrome accepts or rejects a drag and drop operation.
-
-    During a drag and drop operation, there are many 'drag update' events that
-    happen for each mouse-move event. For each such drag-update event, chrome
-    reports whether it is able to accept the drop event or not.
-  </summary>
-</histogram>
-
-<histogram name="Event.DragDrop.Cancel" enum="DragDropEventSource"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2020 as being expired.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Counts the number of times the user cancelled a drag and drop operation.
-  </summary>
-</histogram>
-
-<histogram name="Event.DragDrop.Drop" enum="DragDropEventSource"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2020 as being expired.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Counts the number of times the user completed a drag and drop operation.
-  </summary>
-</histogram>
-
-<histogram name="Event.DragDrop.ExternalOriginDrop" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed 06/2020 as being expired.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Counts the number of times a drag and drop operation originating outside of
-    a Chrome window successfuly drops.
-  </summary>
-</histogram>
-
-<histogram name="Event.DragDrop.Start" enum="DragDropEventSource"
-    expires_after="2020-02-23">
-  <obsolete>
-    Removed 06/2020 as being expired.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Counts the number of times the user started a drag and drop operation.
-  </summary>
-</histogram>
-
-<histogram name="Event.Frequency.Renderer.FlingAnimate" units="hertz"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Emitted after a renderer process main-thread fling curve animation
-    terminates, for any reason, reporting the average animation frequency
-    (animations/second) of the fling instance over its lifetime. This is
-    computed as the number of fling animation ticks divided by the fling
-    animation duration.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Frequency.RendererImpl.FlingAnimate" units="hertz"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Emitted after a renderer process impl-thread fling curve animation
-    terminates, for any reason, reporting the average animation frequency
-    (animations/second) of the fling instance over its lifetime. This is
-    computed as the number of fling animation ticks divided by the fling
-    animation duration.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.InputEventPrediction.Accuracy.Mouse" units="pixels"
-    expires_after="M81">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-            name="InputEventPredictionAccuracy" -->
-
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records the euclidean distance from a mouse event's position to the
-    predicted position at the event time when prediction is available.
-    Prediction is available after the predictor selected by feature flag gets a
-    few continuous mouse events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.InputEventPrediction.Accuracy.Scroll" units="pixels"
-    expires_after="2020-06-21">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-            name="InputEventPredictionAccuracy" -->
-
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records the euclidean distance from a ScrollUpdate event's absolute scroll
-    position (count by accumulated delta) to the predicted scrolling position at
-    the event time when prediction is available. Prediction is available after
-    the predictor selected by feature flag gets a few continuous
-    GestureScrollUpdate events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.InputEventPrediction.Accuracy.Scroll.OverPredict"
-    units="pixels" expires_after="2020-05-10">
-  <obsolete>
-    Removed 10/2019. Replaced by
-    Event.InputEventPrediction.Scroll.OverPrediction.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-            name="InputEventPredictionAccuracy" -->
-
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records y direction distance from a ScrollUpdate event's absolute scroll
-    position (count by accumulated delta) to the predicted scrolling position at
-    the event time when prediction is available and also the predicted result is
-    'OverPredict'. Over predict means the absolute value of predicted scroll
-    delta is larger than the real delta in the same time period.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.InputEventPrediction.Accuracy.Scroll.UnderPredict"
-    units="pixels" expires_after="2020-05-10">
-  <obsolete>
-    Removed 10/2019. Replaced by
-    Event.InputEventPrediction.Scroll.UnderPrediction.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-            name="InputEventPredictionAccuracy" -->
-
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records y direction distance from a ScrollUpdate event's absolute scroll
-    position (count by accumulated delta) to the predicted scrolling position at
-    the event time when prediction is available and also the predicted result is
-    'UnderPredict'. Under predict means the absolute value of predicted scroll
-    delta is smaller than the real delta in the same time period.
-    GestureScrollUpdate events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.InputEventPrediction.Accuracy.Touch" units="pixels"
-    expires_after="M82">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-            name="InputEventPredictionAccuracy" -->
-
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records the euclidean distance from a touch event's position to the
-    predicted position at the event time when prediction is available.
-    Prediction is available after the predictor selected by feature flag gets a
-    few continuous touches with same ids.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.KeyPressDefaultAllowed" units="ms"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a keyboard event and acking
-    it, for events which were not preventDefaulted. Only recorded for key
-    presses.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.KeyPressDefaultPrevented"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a keyboard event and acking
-    it, for events which were preventDefaulted. Only recorded for key presses.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchEndDefaultAllowed" units="ms"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchend event and acking
-    it, for events which were not preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchEndDefaultPrevented"
-    units="ms" expires_after="2020-01-26">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchend event and acking
-    it, for events which were preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchMoveDefaultAllowed" units="ms"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchmove event and acking
-    it, for events which were not preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchMoveDefaultPrevented"
-    units="ms" expires_after="2020-11-08">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchmove event and acking
-    it, for events which were preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchStartDefaultAllowed"
-    units="ms" expires_after="2020-11-08">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchstart event and
-    acking it, for events which were not preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.BlockingTime.TouchStartDefaultPrevented"
-    units="ms" expires_after="2020-10-18">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between the renderer main thread receiving a touchstart event and
-    acking it, for events which were preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of all input events and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_DROP_TARGET_EVENT"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_BEGIN" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_DOUBLE_TAP"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_END" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_LONG_PRESS"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_LONG_TAP"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_MULTIFINGER_SWIPE"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_PINCH_BEGIN"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_PINCH_END"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_PINCH_UPDATE"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_SCROLL_BEGIN"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_SCROLL_END"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_SCROLL_UPDATE"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_TAP" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_TAP_CANCEL"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_TAP_DOWN"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_GESTURE_TWO_FINGER_TAP"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_KEY_PRESSED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_KEY_RELEASED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_CAPTURE_CHANGED"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_DRAGGED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_ENTERED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_EXITED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_MOVED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSE_RELEASED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_MOUSEWHEEL" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_SCROLL" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_SCROLL_FLING_CANCEL"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_SCROLL_FLING_START"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TOUCH_CANCELLED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TOUCH_MOVED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TOUCH_PRESSED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TOUCH_RELEASED" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TOUCH_STATIONARY"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TRANSLATED_KEY_PRESS"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_TRANSLATED_KEY_RELEASE"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.ET_UNKNOWN" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of input event and browser processing.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.KeyPressAcked" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between key events sent from RWH to renderer and acked by renderer.
-    Only monitors key presses.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.KeyPressUI" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between key events received by Chrome and sent from RWH to renderer.
-    Only monitors key presses.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.TouchAcked" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between touch events sent from RWH to renderer and acked by renderer.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.TouchUI" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between touch events received by Chrome and sent from RWH to renderer.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.WheelAcked" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Time between wheel events sent from RWH to renderer and acked by renderer.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Browser.WheelUI" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    Time between wheel events received by Chrome and sent from RWH to renderer.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.OS_NO_VALIDATION.NEGATIVE" units="ms"
-    expires_after="2020-06-28">
-  <obsolete>
-    This histogram never has negative values, so it was removed 06/2020.
-  </obsolete>
-  <owner>sullivan@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    For Mac, a version of Event.Latency.OS that has the negative values it would
-    contain if ValidateEventTimeClock() were not called on the timestamps.
-
-    This metric is intended to debug http://crbug.com/1039833, where very high
-    numbers are seen for PageLoad.InputDelay3. The units of this metric are the
-    same as PageLoad.InputDelay3 for consistency while debugging.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.KeyPressDefaultAllowed" units="ms"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    Time between sending a keyboard event to the renderer main thread and when
-    the renderer begins to process that event, for events which were not
-    preventDefaulted. Only recorded for key presses.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.KeyPressDefaultPrevented"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a keyboard event to the renderer main thread and when
-    the renderer begins to process that event, for events which were
-    preventDefaulted. Only recorded for key presses.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchEndDefaultAllowed" units="ms"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchend event to the renderer main thread and when
-    the renderer begins to process that event, for events which were not
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchEndDefaultPrevented"
-    units="ms" expires_after="2020-02-02">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchend event to the renderer main thread and when
-    the renderer begins to process that event, for events which were
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchMoveDefaultAllowed" units="ms"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchmove event to the renderer main thread and when
-    the renderer begins to process that event, for events which were not
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchMoveDefaultPrevented"
-    units="ms" expires_after="2020-05-31">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchmove event to the renderer main thread and when
-    the renderer begins to process that event, for events which were
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchStartDefaultAllowed"
-    units="ms" expires_after="2020-11-08">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchstart event to the renderer main thread and when
-    the renderer begins to process that event, for events which were not
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.QueueingTime.TouchStartDefaultPrevented"
-    units="ms" expires_after="2020-05-31">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending a touchstart event to the renderer main thread and when
-    the renderer begins to process that event, for events which were
-    preventDefaulted.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Renderer" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initiation of all input events and renderer processing. This is
-    soon to be replaced by Event.Latency.Renderer2.*
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Renderer2" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between input event creation and the renderer receiving and starting to
-    process the event. For touch events on Windows, we measure from when the
-    event reaches Chrome, whereas on other platforms we use the timestamp from
-    the kernel. On Windows, this metric is only reported when |IsHighResolution|
-    is true, which will introduce some sampling bias.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.RendererImpl" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between input event creation and the renderer impl thread receiving and
-    starting to process the event. For touch events on Windows, we measure from
-    when the event reaches Chrome, whereas on other platforms we use the
-    timestamp from the kernel. On Windows, this metric is only reported when
-    |IsHighResolution| is true, which will introduce some sampling bias.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.RendererImpl.GestureScroll" units="microseconds"
-    expires_after="2013-12-12">
-  <obsolete>
-    Removed 12/2013 and replaced by Event.Latency.RendererImpl.GestureScroll2
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between initial creation of touch event and when the resulting
-    ScrollGesture reaches Impl thread. Maximum is 200ms.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.RendererImpl.GestureScroll2"
-    units="microseconds" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between touch event creation and when the resulting GestureScroll
-    reaches the Impl thread. Maximum is 1000ms. On Windows, we measure from when
-    the touch event reaches Chrome, whereas on other platforms we use the
-    timestamp from the kernel. On Windows, this metric is only reported when
-    |IsHighResolution| is true, which will introduce some sampling bias. This
-    supersedes the Event.Latency.RendererImpl.GestureScroll metric.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.TimeToScrollUpdateSwapBegin"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin2 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel/touch event and start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made. If no
-    swap was induced by the event, no recording is made.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Touch.EventTimeToRAFTime"
-    units="microseconds" expires_after="2020-05-10">
-  <obsolete>
-    Removed 04/2020 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <owner>axantoine@google.com</owner>
-  <summary>
-    Time between the initiation of the last ScrollBegin event received and its
-    handling in a frame by the scroll predictor (i.e. rAF time).
-
-    Team: input-dev@chromium.org.
-
-    Warning: Only recorded in a touch context.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Touch.RAFTimeToFrameSwapEnd"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed 10/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <owner>axantoine@google.com</owner>
-  <summary>
-    Time between the handling of the last ScrollBegin event received in the
-    frame (i.e. rAF time) and the end of the swap of that frame on the gpu.
-
-    Team: input-dev@chromium.org.
-
-    Warning: Only recorded in a touch context.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2019-01-17">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made. This is
-    going to be replaced by *.TimeToScrollUpdateSwapBegin3 version since a
-    rebucketing change made this metric lose its usefulness in Chirp
-    infrastructure.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin3"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2019-01-17">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made. This is
-    going to be replaced by *.TimeToScrollUpdateSwapBegin3 version since a
-    rebucketing change made this metric lose its usefulness in Chirp
-    infrastructure.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin3"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Latency.ScrollInertial.Touch.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>sahel@chromium.org</owner>
-  <summary>
-    Time between initial creation of a ScrollUpdate gesture event generated from
-    a touchscreen fling and the start of the frame swap on the GPU service
-    caused by the generated ScrollUpdate gesture event. If no swap was induced
-    by the event, no recording is made. This is going to be replaced by
-    *.TimeToScrollUpdateSwapBegin3 version since a rebucketing change made this
-    metric lose its usefulness in Chirp infrastructure.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Latency.ScrollInertial.Touch.TimeToScrollUpdateSwapBegin3"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>sahel@chromium.org</owner>
-  <summary>
-    Time between initial creation of a ScrollUpdate gesture event generated from
-    a touchscreen fling and the start of the frame swap on the GPU service
-    caused by the generated ScrollUpdate gesture event. If no swap was induced
-    by the event, no recording is made.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.BrowserNotifiedToBeforeGpuSwap"
-    units="microseconds" expires_after="2016-10-07">
-  <obsolete>
-    To be replaced by
-    Event.Latency.ScrollUpdate.Touch.BrowserNotifiedToBeforeGpuSwap2,
-    Event.Latency.ScrollUpdate.Wheel.BrowserNotifiedToBeforeGpuSwap2 in M56.
-    https://crbug.com/649754
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between the browser receives the notification of a ScrollUpdate gesture
-    event induced renderer swap and GPU starts to swap.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.GpuSwap" units="microseconds"
-    expires_after="2016-10-07">
-  <obsolete>
-    To be replaced by Event.Latency.ScrollUpdate.Touch.GpuSwap2,
-    Event.Latency.ScrollUpdate.wheel.GpuSwap2 in M56. https://crbug.com/649754
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between gpu starts to swap a ScrollUpdate gesture event induced frame
-    and the swap finishes.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.HandledToRendererSwap"
-    units="microseconds" expires_after="2016-10-07">
-  <obsolete>
-    To be replaced by Event.Latency.ScrollUpdate.Touch.HandledToRendererSwap2,
-    Event.Latency.ScrollUpdate.Wheel.HandledToRendererSwap2 in M56.
-    https://crbug.com/649754
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between the ScrollUpdate gesture event is handled on main/impl thread
-    (specified by suffix) and before renderer starts to swap.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.RendererSwapToBrowserNotified"
-    units="microseconds" expires_after="2016-10-07">
-  <obsolete>
-    To be replaced by
-    Event.Latency.ScrollUpdate.Touch.RendererSwapToBrowserNotified2,
-    Event.Latency.ScrollUpdate.Wheel.RendererSwapToBrowserNotified2 in M56.
-    https://crbug.com/649754
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between the renderer starts to swap a frame induced by ScrollUpdate
-    gesture event and browser receives the swap notification.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.TimeToScrollUpdateSwapBegin"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin2 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel/touch event and start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event.
-    If no swap was induced by the event, no recording is made. The first GSU of
-    every scrolling sequence is excluded from this metric.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Touch.EventTimeToRAFTime"
-    units="microseconds" expires_after="2020-05-10">
-  <obsolete>
-    Removed 10/2019 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <owner>axantoine@google.com</owner>
-  <summary>
-    Time between the initiation of the last ScrollUpdate event received and its
-    handling in a frame by the scroll predictor (i.e. rAF time).
-
-    Team: input-dev@chromium.org.
-
-    Warning: Only recorded in a touch context.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Touch.RAFTimeToFrameSwapEnd"
-    units="microseconds" expires_after="2020-05-24">
-  <obsolete>
-    Removed 04/2020 due to lack of usage.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <owner>axantoine@google.com</owner>
-  <summary>
-    Time between the handling of the last ScrollUpdate event received in the
-    frame (i.e. rAF time) and the end of the swap of that frame on the gpu.
-
-    Team: input-dev@chromium.org.
-
-    Warning: Only recorded in a touch context.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Latency.ScrollUpdate.Touch.TimeToFirstScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Replaced by Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-
-    To be replaced by
-    Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2 in M57.
-    https://crbug.com/669618
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2019-01-17">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made. The first GSU of every
-    scrolling sequence is excluded from this metric. This is going to be
-    replaced by *.TimeToScrollUpdateSwapBegin3 version since a rebucketing
-    change made this metric lose its usefulness in Chirp infrastructure.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin3"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made. The first GSU of every
-    scrolling sequence is excluded from this metric.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.TouchToHandled"
-    units="microseconds" expires_after="2016-10-07">
-  <obsolete>
-    To be replaced by Event.Latency.ScrollUpdate.Touch.TimeToHandled2 in M56.
-    https://crbug.com/649754
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the generated
-    ScrollUpdate gesture event is handled on main/impl thread (specified by
-    suffix). If no swap was induced by the ScrollUpdate gesture event, no
-    recording is made.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Latency.ScrollUpdate.Wheel.TimeToFirstScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Replaced by Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-
-    To be replaced by
-    Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2 in M57.
-    https://crbug.com/669618
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Wheel.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2019-01-17">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made. The first GSU of every
-    scrolling sequence is excluded from this metric. This is going to be
-    replaced by *.TimeToScrollUpdateSwapBegin3 version since a rebucketing
-    change made this metric lose its usefulness in Chirp infrastructure.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.ScrollUpdate.Wheel.TimeToScrollUpdateSwapBegin3"
-    units="microseconds" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by *.TimeToScrollUpdateSwapBegin4 https://crbug.com/849735 in M68.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made. The first GSU of every
-    scrolling sequence is excluded from this metric.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Touch.TimeToFirstScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2016-10-14">
-  <obsolete>
-    Replaced by
-    Event.Latency.ScrollUpdate.Touch.TimeToFirstScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Touch.TimeToScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2016-10-14">
-  <obsolete>
-    Replaced by Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.TouchToFirstScrollUpdateSwap"
-    units="microseconds" expires_after="2015-04-24">
-  <obsolete>
-    Replaced by Event.Latency.TouchToFirstScrollUpdateSwapBegin.
-    crbug.com/478845
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the frame swap caused by
-    by the generated ScrollUpdate gesture event if that ScrollUpdate is the
-    first such in a given scroll gesture event sequence. If no swap was induced
-    by the event, no recording is made.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.TouchToFirstScrollUpdateSwapBegin"
-    units="microseconds" expires_after="2017-10-19">
-  <obsolete>
-    Replaced by Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-
-    To be replaced by
-    Event.Latency.ScrollUpdate.Touch.TimeToFirstScrollUpdateSwapBegin2 in M56.
-    https://crbug.com/649754
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.TouchToScrollUpdateSwap" units="microseconds"
-    expires_after="2015-04-24">
-  <obsolete>
-    Replaced by Event.Latency.TouchToScrollUpdateSwapBegin. crbug.com/478845
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and the frame swap caused by
-    by the generated ScrollUpdate gesture event. If no swap was induced by the
-    event, no recording is made.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.TouchToScrollUpdateSwapBegin"
-    units="microseconds" expires_after="2017-10-19">
-  <obsolete>
-    Replaced by Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a touch event and start of the frame swap
-    on the GPU service caused by the generated ScrollUpdate gesture event. If no
-    swap was induced by the event, no recording is made.
-
-    To be replaced by
-    Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2 in M56.
-    https://crbug.com/649754
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.Wheel.TimeToFirstScrollUpdateSwapBegin2"
-    units="microseconds" expires_after="2016-10-14">
-  <obsolete>
-    Replaced by
-    Event.Latency.ScrollUpdate.Wheel.TimeToFirstScrollUpdateSwapBegin2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between initial creation of a wheel event and the start of the frame
-    swap on the GPU service caused by the generated ScrollUpdate gesture event
-    if that ScrollUpdate is the first such event in a given scroll gesture event
-    sequence. If no swap was induced by the event, no recording is made.
-  </summary>
-</histogram>
-
-<histogram name="Event.Latency.X11EventSource.UpdateServerTime"
-    units="microseconds" expires_after="2016-09-02">
-  <obsolete>
-    Removed 08/2016, and replaced by Linux.X11.ServerRTT.
-  </obsolete>
-  <owner>thomasanderson@chromium.org</owner>
-  <summary>Time to request a timestamp from the X server.</summary>
-</histogram>
-
-<histogram name="Event.MainThreadEventQueue.CoalescedCount" units="events"
-    expires_after="2018-03-07">
-  <obsolete>
-    Removed 03/2018 due to lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Number of continuous events (touchmove, mousemove, mousewheel) coalesced
-    inside the main thread event queue per event. This field is recorded just
-    before the event is processed on the main thread.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.MainThreadEventQueue.Continuous.FreshnessTime"
-    units="microseconds" expires_after="2018-01-03">
-  <obsolete>
-    Removed 01/2018 due to lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a continuous event (touchmove, mousemove, mousewheel) was
-    placed into the queue (or coalesced with another event) and when it was
-    processed on the main thread.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.MainThreadEventQueue.Continuous.QueueingTime"
-    units="microseconds" expires_after="2018-01-03">
-  <obsolete>
-    Removed 01/2018 due to lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a continuous event (touchmove, mousemove, mousewheel) was
-    placed into the queue and when it was processed on the main thread.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.MainThreadEventQueue.FlushQueueNoBeginMainFrame"
-    enum="BooleanHit" expires_after="M77">
-  <obsolete>
-    Expired 2019-07.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Whether the Begin Main Frame was not received and the queue generated a
-    flush queue after a given timeout.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.MainThreadEventQueue.NonContinuous.QueueingTime"
-    units="microseconds" expires_after="2018-01-03">
-  <obsolete>
-    Removed 01/2018 due to lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a non-continuous event (not touchmove, mousemove,
-    mousewheel) was placed into the queue and when it was processed on the main
-    thread.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.PassiveForcedEventDispatchCancelled"
-    enum="PassiveForcedListenerResultType" expires_after="M77">
-  <obsolete>
-    Expired 2019-07.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Counts the number of event listener invocations that were forced to be
-    passive due to interventions and whether the invocation of the listener
-    called prevent default or not.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.PassiveListeners.ForcedNonBlockingLatency"
-    units="microseconds" expires_after="2016-08-19">
-  <obsolete>
-    Removed 08/2016 in Issue 595327, and replaced by
-    Event.PassiveListeners.ForcedNonBlockingLatencyDueToFling.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a forced non-blocking event was generated and the event
-    processed. This histogram tracks the benefit of forcing non-blocking events
-    listeners.
-  </summary>
-</histogram>
-
-<histogram name="Event.PassiveListeners.ForcedNonBlockingLatencyDueToFling"
-    units="microseconds" expires_after="M77">
-  <obsolete>
-    Expired 2019-07.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a touchstart or first touchmove event per scroll was
-    generated and the event processed, for events which were forced non-blocking
-    since they occurred during fling. This histogram tracks the benefit of
-    forcing events non-blocking during fling.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.PassiveListeners.ForcedNonBlockingLatencyDueToUnresponsiveMainThread"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed 04/2018 due to cancellation of experiment.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touchstart or first touchmove event per scroll was
-    generated and the event processed, for events which were forced non-blocking
-    since they occurred while the main thread was unresponsive. This histogram
-    tracks the benefit of forcing events non-blocking when the main thread is
-    unresponsive.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.PassiveListeners.Latency" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    Removed as of M80 due to the lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Time between when a cancelable event was generated and the event processed
-    yet no action was executed for the event. This histogram tracks the
-    potential benefit of using passive events listeners.
-
-    Team: input-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative"
-    units="microseconds" expires_after="2020-03-29">
-  <obsolete>
-    Removed 10/2019 due to the completion of the experiment.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <owner>sarsha@microsoft.com</owner>
-  <summary>
-    On Windows, reports negative time delta between pointer input timestamps
-    based on TimeNow and the timestamp reported via
-    PointerInfo.PerformanceCount. This negative time delta is w.r.t to
-    PerformanceCount. See also
-    Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive"
-    units="microseconds" expires_after="M79">
-  <obsolete>
-    Removed 10/2019 due to the completion of the experiment.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <owner>sarsha@microsoft.com</owner>
-  <summary>
-    On Windows, reports positive time delta between pointer input timestamps
-    based on TimeNow and the timestamp reported via
-    PointerInfo.PerformanceCount. This positive time delta is w.r.t to
-    PerformanceCount. See also
-    Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative.
-  </summary>
-</histogram>
-
-<histogram name="Event.RenderView.DiscardInput" enum="BooleanHit"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Whether the input IPC messages were discarded before being fully processed
-    in RenderView's IPC message handler.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Scroll.ScrollerSize.OnLoad" units="pixels"
-    expires_after="2017-10-18">
-  <obsolete>
-    Removed 10/2017 due to the completion of the experiment.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <summary>
-    Record the area of a scroller upon page load. This is intended to help us
-    measure the distribution of scrollers with different sizes. Combined with
-    the other two metrics which measure the size of scrollers on scroll, we may
-    have a better idea of not compositing small scrollers.
-
-    Team: input-dev@chromium.org, animations-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Scroll.ScrollerSize.OnScroll" units="pixels"
-    expires_after="2017-10-23">
-  <obsolete>
-    Removed 10/2017 due to the completion of the experiment.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <summary>
-    Record the area of a scroller upon ScrollBegin. This is intended to help us
-    measure the frequencies of different sizes of scrollers getting scrolled.
-    For those small scrollers that users may rarely scroll, there is no need to
-    composite them even if we are able to do so.
-
-    Team: input-dev@chromium.org, animations-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Scroll.TouchGestureLatency" units="ms"
-    expires_after="M79">
-  <obsolete>
-    Removed as of 10/2019 due to no further need of data.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <owner>dlibby@microsoft.com</owner>
-  <summary>
-    Time (ms) between the pointer down event and when a subsequent pointer move
-    is recognized as a scroll.
-
-    Team: input-dev@chromium.org
-  </summary>
-</histogram>
-
-<histogram name="Event.TimestampHasValidTimebase" enum="EventTimestampValidity"
-    expires_after="2018-01-17">
-  <obsolete>
-    Removed as of 1/2018 in issue 650338 (http://crbug.com/650338). Using a
-    DCHECK instead.
-  </obsolete>
-  <owner>majidvp@chromium.org</owner>
-  <owner>caseq@chromium.org</owner>
-  <summary>
-    Whether the timestamps on input events produced by the windowing system
-    appear to be sharing the same time base as TimeTicks, modulo possible
-    roll-over.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative"
-    units="microseconds" expires_after="2020-03-29">
-  <obsolete>
-    Removed 10/2019 due to the completion of the experiment.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <owner>sarsha@microsoft.com</owner>
-  <summary>
-    On Windows, reports negative time delta between pointer input timestamps
-    based on TimeNow and the timestamp reported via
-    PointerInfo.PerformanceCount. This negative time delta is w.r.t to
-    PerformanceCount. See also
-    Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive.
-  </summary>
-</histogram>
-
-<histogram
-    name="Event.Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive"
-    units="microseconds" expires_after="2020-03-29">
-  <obsolete>
-    Removed 10/2019 due to the completion of the experiment.
-  </obsolete>
-  <owner>nzolghadr@chromium.org</owner>
-  <owner>sarsha@microsoft.com</owner>
-  <summary>
-    On Windows, reports positive time delta between pointer input timestamps
-    based on TimeNow and the timestamp reported via
-    PointerInfo.PerformanceCount. This positive time delta is w.r.t to
-    PerformanceCount. See also
-    Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TargetAndDispatchResult"
-    enum="TouchTargetAndDispatchResultType" expires_after="2016-05-19">
-  <obsolete>
-    Removed 05/2016, and replaced by Event.Touch.TargetAndDispatchResult2.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    An enumeration identifying 3 properties: 1) a classification of the event
-    target whether it is a root scroll listener (window, document, body) or not;
-    2) the result of the dispatch; 3) whether the document was scrollable or
-    not.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TargetAndDispatchResult2"
-    enum="TouchTargetAndDispatchResultType2" expires_after="M77">
-  <obsolete>
-    Expired 2019-07
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    An enumeration identifying 4 properties: 1) a classification of the current
-    target whether it is a root scroll listener (window, document, body) or not;
-    2) the result of the dispatch or whether it was previously canceled 3)
-    whether the document was scrollable or not 4) what phase the listener was
-    encountered at. This metric is logged during the dispatch of the touch
-    events. It will only be reported for main frame events that block scrolling,
-    have only one touch point and current targets that fired an event listener
-    at that phase.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchAdjustment.AdjustDistance" units="pixels"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 due to no longer needed.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records the euclidean distance in dips from a gesture event's original tap
-    center to its adjusted touch point. 0 if not adjusted. This only records
-    GestureTap events and GestureLongPress events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchAdjustment.AdjustedNode"
-    enum="TouchAdjustmentNodeRelation" expires_after="2018-05-11">
-  <obsolete>
-    Removed 03/2018 due to no longer needed.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records if doing touch adjustment on touchstart have same hit test node as
-    doing touch adjustment on GestureTap. If not, record if one is descendant of
-    the other. Others means neither of the nodes are descendant of the other.
-    This only records GestureTap events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchAdjustment.AdjustToSameNode" enum="Boolean"
-    expires_after="2018-02-22">
-  <obsolete>
-    Removed 02/2018 and replaced by Event.Touch.TouchAdjustment.AdjustedNode.
-  </obsolete>
-  <owner>eirage@chromium.org</owner>
-  <summary>
-    Records if doing touch adjustment on touchstart have same hit test node as
-    doing touch adjustment on GestureTap. True for same node, false for
-    different node. This only records GestureTap events.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsAfterPageLoad"
-    enum="TouchEventDispatchResultType" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart events and
-    the first touchmove events per scroll. Only recorded after the page is fully
-    loaded.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsBeforePageLoad"
-    enum="TouchEventDispatchResultType" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart events and
-    the first touchmove events per scroll. Only recorded before the page is
-    fully loaded.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsDuringFling"
-    enum="TouchEventDispatchResultType" expires_after="2016-08-19">
-  <obsolete>
-    Removed 08/2016 in Issue 595327, and replaced by
-    Event.Touch.TouchDispositionsDuringFling2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart events. Only
-    recorded while there is an active fling animation.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsDuringFling2"
-    enum="TouchEventDispatchResultType" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart and first
-    touchmove events per scroll. Only recorded while there is an active fling
-    animation.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsOutsideFling"
-    enum="TouchEventDispatchResultType" expires_after="2016-08-19">
-  <obsolete>
-    Removed 08/2016 in Issue 595327, and replaced by
-    Event.Touch.TouchDispositionsOutsideFling2.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart events. Only
-    recorded while there is no active fling animation.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchDispositionsOutsideFling2"
-    enum="TouchEventDispatchResultType" expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Records the disposition (handled or not handled) of touchstart and first
-    touchmove events per scroll events. Only recorded while there is no active
-    fling animation.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchLatencyAfterPageLoad" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touch event was generated and the event was processed.
-    Recorded only for touchstart events and the first touchmove events per
-    scroll that occur after the page is fully loaded.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchLatencyBeforePageLoad" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touch event was generated and the event was processed.
-    Recorded only for touchstart events and the first touchmove events per
-    scroll that occur before the page is fully loaded. This histogram tracks the
-    benefit of forcing passive event listeners before the page is fully loaded.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchLatencyOutsideFling" units="microseconds"
-    expires_after="2017-06-26">
-  <obsolete>
-    Removed 06/2017 due to lack of usage.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touch event was generated and the event was processed.
-    Recorded only for touchstart events and the first touchmove events per
-    scroll when there was no active fling animation.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchStartLatencyDuringFling" units="microseconds"
-    expires_after="2016-08-19">
-  <obsolete>
-    Removed 08/2016 in Issue 595327, and replaced by
-    Event.PassiveListeners.ForcedNonBlockingLatencyDueToFling.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touchstart event was generated and the event was
-    processed. Recorded only when there was an active fling animation. This
-    histogram tracks the benefit of forcing passive event listeners during
-    fling.
-  </summary>
-</histogram>
-
-<histogram name="Event.Touch.TouchStartLatencyOutsideFling"
-    units="microseconds" expires_after="2016-08-19">
-  <obsolete>
-    Removed 08/2016 in Issue 595327, and replaced by
-    Event.Touch.TouchLatencyOutsideFling.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between when a touchstart event was generated and the event was
-    processed. Recorded only when there was no active fling animation.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.AggregateTime" units="ms"
-    expires_after="2018-07-10">
-  <obsolete>
-    Removed as of 07/2018. Replaced with Event.VizHitTest.AggregateTimeUs.
-  </obsolete>
-  <owner>riajiang@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestAggregator to aggregate hit-test data
-    received from all clients.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.AggregateTimeUs" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020. The feature has been launched.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestAggregator to aggregate hit-test data
-    received from all clients, in microseconds.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.HitTestRegions" units="regions"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed as of 01/2020. The feature has been launched.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Total number of hit-test regions Viz received from all clients.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.TargetTime" units="ms"
-    expires_after="2018-07-10">
-  <obsolete>
-    Removed as of 07/2018. Replaced with Event.VizHitTest.TargetTimeUs.
-  </obsolete>
-  <owner>riajiang@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestQuery to find a target on a given
-    location.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.TargetTimeUs" units="microseconds"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed as of 01/2020. The feature has been launched.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestQuery to find a target on a given
-    location, in microseconds.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.TransformTime" units="ms"
-    expires_after="2018-07-10">
-  <obsolete>
-    Removed as of 07/2018. Replaced with Event.VizHitTest.TransformTimeUs.
-  </obsolete>
-  <owner>riajiang@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestQuery to transform a location to a given
-    target's coordinate space.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTest.TransformTimeUs" units="microseconds"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed as of 01/2020. The feature has been launched.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <owner>event-targeting@chromium.org</owner>
-  <summary>
-    Tracks how long it takes for HitTestQuery to transform a location to a given
-    target's coordinate space, in microseconds.
-  </summary>
-</histogram>
-
-<histogram name="Event.VizHitTestSurfaceLayer.ResultsMatch"
-    enum="VizHitTestResultsMatchEnums" expires_after="M81">
-  <obsolete>
-    Removed as of 11/2019. The verification path is removed.
-  </obsolete>
-  <owner>yigu@chromium.org</owner>
-  <summary>
-    This tracks how often the cc layer based hit testing fast path result
-    matches or doesn't match the asynchronous blink hit test result.
-
-    Team: event-targeting@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="ExploreSites.SiteTilesClickIndex" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed with M77 and replaced by ExploreSites.SiteTilesClickIndex2.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    The total index of the selected tile on the ExploreSites page. This measures
-    how far down from the top it is, counting all the other tiles in cards above
-    it. This assumes 8 tiles per category, and might skip some valid indices if
-    fewer tiles are displayed in a category.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.AdInjected" units="Extension Count"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that inject at least one new ad.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.AdLikelyInjected" units="Extension Count"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that performed an action that
-    heuristically looks like injecting an ad, but could not be confirmed.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.AdLikelyReplaced" units="Extension Count"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that performed an action that
-    heuristically looks like replacing an ad, but could not be confirmed.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.AdRemoved" units="Extension Count"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that remove at least one ad.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.AdReplaced" units="Extension Count"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that replace at least one ad.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.ContentScript" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that inject a content script.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedDiv" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create divs to add to the
-    page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedEmbed" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create 'embed' elements to
-    add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedIframe" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create iframes to add to
-    the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedInput" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create inputs to add to the
-    page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedLink" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create links to add to the
-    page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedObject" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create 'object' elements to
-    add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.CreatedScript" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that create script tags to add
-    to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.DocumentWrite" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that use document.write.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.ContentScript" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that inject a
-    content script.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedDiv" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create divs
-    to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedEmbed" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create
-    'embed' elements to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedInput" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create
-    inputs to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedLink" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create links
-    to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedObject" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create
-    'object' elements to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.CreatedScript" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that create
-    script tags to add to the page.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.DocumentWrite" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that use
-    document.write.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.InnerHtml" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that set
-    innerHTML.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.InvokedDomMethod" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that invoke DOM
-    methods.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.ModifiedDom" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that set the
-    value of DOM properties via assignments.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.Google.ReadDom" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each www.google.com pageload, the number of extensions that read from
-    the DOM.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.InnerHtml" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that set innerHTML.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.InvokedDomMethod" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that invoke DOM methods.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.ModifiedDom" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that set the value of DOM
-    properties via assignments.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionActivity.ReadDom" units="units"
-    expires_after="2015-08-17">
-  <obsolete>
-    Removed with M46.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    For each pageload, the number of extensions that read from the DOM.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionBubble.WipeoutUserSelection"
-    enum="ExtensionBubbleAction" expires_after="M80">
-  <obsolete>
-    Stopped recording in 2019-07. Data was no longer required.
-  </obsolete>
-  <owner>finnur@chromium.org</owner>
-  <summary>
-    The action taken by the user when seeing the bubble, logged right after the
-    action is taken.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstalledLoader.ForceDisabled"
-    enum="BooleanForceDisabled" expires_after="2017-08-23">
-  <obsolete>
-    Replaced with ExtensionInstalledLoader.ForceDisabled2.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Counts whether we force-disabled an installed extension at startup because a
-    policy provider indicated it must remain disabled.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstalledLoader.ForceDisabled2"
-    enum="BooleanForceDisabled" expires_after="2019-02-16">
-  <obsolete>
-    Expired 2018-08-30
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Counts whether we force-disabled an installed extension at startup because
-    it failed ManagementPolicy::MustRemainDisabled check. This checks both
-    UserMayLoad and MustRemainDisabled methods on a policy provider.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.FetchSuccess" units="units"
-    expires_after="M83">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <summary>N/A. Never properly tracked.</summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.GetResponseSuccess" units="units"
-    expires_after="M83">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <summary>N/A. Never properly tracked.</summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.InvalidCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    This is a count of the number of ids that we asked to be signed which the
-    server response indicated were not in the webstore.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.ParseFieldsSuccess" units="units"
-    expires_after="M83">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <summary>N/A. Never properly tracked.</summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.ParseJsonSuccess" units="units"
-    expires_after="M83">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <summary>N/A. Never properly tracked.</summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.RequestCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    A count of the number of server requests since Chrome started running,
-    recorded each time we do a request. NOTE: when interpreting these values,
-    keep in mind that a user who did 5 server requests during one run of Chrome
-    will log this histogram 5 times with values 1, 2, 3, 4, and 5.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.ResultWasValid" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Whether the server result received by the extensions install signer was
-    valid or invalid.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.SecondsSinceLastRequest"
-    units="seconds" expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    This records the number of seconds since the last time we've done a request
-    to the server (only during this run of the browser).
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallSigner.UptimeAtTimeOfRequest" units="seconds"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Records how many seconds the browser has been running at the time a request
-    to the server is made to get a new install signature.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallVerifier.ActualStatus"
-    enum="ExtensionInstallVerifierStatus" expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Logged during InstallVerifier::Init, to indicate the actual enforcement
-    status used (usually determined by the ExtensionInstallVerifier field trial
-    experiment, but possibly modified by command line flags).
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallVerifier.ExperimentStatus"
-    enum="ExtensionInstallVerifierStatus" expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Logged during InstallVerifier::Init to indicate the enforcement status as
-    determined by the ExtensionInstallVerifier field trial experiment.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionInstallVerifier.MustRemainDisabled"
-    enum="ExtensionInstallVerifierMustRemainDisabled"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The outcome for each call to InstallVerifier::MustRemainDisabled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ActiveScriptController.PreventableAdInjectors"
-    units="Extension Count" expires_after="M85">
-  <obsolete>
-    Code removed 2015-10.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The number of extensions per page that injected an ad and could have been
-    stopped if the user had declined script injection. This is related to the
-    ActivityLog metrics, ExtensionActivity.Ad*. Recorded upon page close or
-    navigation. Only recorded if there was at least one ad injection detected.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ActiveScriptController.ShownActiveScriptsOnPage"
-    units="Number of Actions" expires_after="2015-02-10">
-  <obsolete>
-    Removed 2/2014.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The number of extensions which would display an Active Script Running
-    indiciation to the user. Recorded at page close.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ActiveScriptController.UnpreventableAdInjectors"
-    units="Extension Count" expires_after="M85">
-  <obsolete>
-    Code removed 2015-10.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The number of extensions per page that injected an ad and that could not
-    have been stopped through script injection permission. This is related to
-    the ActivityLog metrics, ExtensionActivity.Ad*. Recorded upon page close or
-    navigation. Only recorded if there was at least one ad injection detected.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.AdInjection.AdType" enum="InjectedAdType"
-    expires_after="M85">
-  <obsolete>
-    Code removed 2015-08.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>The type of ad that was injected.</summary>
-</histogram>
-
-<histogram name="Extensions.AdInjection.InstallLocation"
-    enum="ExtensionLocation" expires_after="M85">
-  <obsolete>
-    Code removed long ago.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The install location of an ad-injecting extension. Recorded upon page close
-    for any extension that injected ads on that page.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ApiUrlNavigationDevtools" enum="Boolean"
-    expires_after="2020-09-13">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>tjudkins@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Reports whether a URL navigated to by an extension through the extensions
-    API has the devtools scheme. Reported once per call to tabs.update(),
-    tabs.create() or browser.openTab(). Also reported from windows.create() and
-    will be reported once for each url passed to that function.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.APIUse_RelativeURL" enum="UrlResolutionResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Captures the results of URL resolution when relative urls are used in the
-    tabs/windows api.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.AppLaunchContainer" enum="AppLaunchContainer"
-    expires_after="2014-12-03">
-  <obsolete>
-    Removed as of 12/2014, replaced by Apps.HostedAppLaunchContainer.
-  </obsolete>
-  <owner>benwells@chromium.org</owner>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    The number of times apps are launched grouped by
-    extensions::LaunchContainer.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BackgroundContentsServiceStartupTime" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Expired
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Time taken to load BackgroundContents for apps at startup when the extension
-    system notifies that it is ready.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BackgroundPageLoadTime" units="ms"
-    expires_after="2015-02-06">
-  <obsolete>
-    Replaced by Extensions.BackgroundPageLoadTime2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>The time for an extension's background page to load.</summary>
-</histogram>
-
-<histogram name="Extensions.BluetoothSocket.Connect.Service"
-    enum="BluetoothSocketServiceHash" expires_after="M72">
-  <obsolete>
-    Removed in M73 after collecting the data necessary.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the UUID of the service to which a Chrome App opens a socket
-    connection. The recorded value is a 31-bit hash of the UUID. These results
-    will help us better understand the uses of the API and make changes
-    according to developers' behavior.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BluetoothSocket.ListenL2CAP.Service"
-    enum="BluetoothSocketServiceHash" expires_after="M72">
-  <obsolete>
-    Removed in M73 after collecting the data necessary.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the UUID of a service created by a Chrome App listening for L2CAP
-    connections. The recorded value is a 31-bit hash of the UUID. These results
-    will help us better understand the uses of the API and make changes
-    according to developers' behavior.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BluetoothSocket.ListenRFCOMM.Service"
-    enum="BluetoothSocketServiceHash" expires_after="M72">
-  <obsolete>
-    Removed in M73 after collecting the data necessary.
-  </obsolete>
-  <owner>ortuno@chromium.org</owner>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the UUID of a service created by a Chrome App listening for RFCOMM
-    connections. The recorded value is a 31-bit hash of the UUID. These results
-    will help us better understand the uses of the API and make changes
-    according to developers' behavior.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.GetAppForCurrentURLDuration" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/05 as PWA link capturing has been removed.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    Time it takes to retrieve the app for the current URL during a navigation.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.GetAppForWindowDuration" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/05 as PWA link capturing has been removed.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    Time it takes to retrieve the app associated with the window during a
-    navigation.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.GetTargetAppDuration" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/05 as PWA link capturing has been removed.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    Time it takes to retrieve the app for the target url during a navigation.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate"
-    enum="HttpStatusCodeClass" expires_after="2020-01-01">
-  <obsolete>
-    Removed 2018/11 in favor of WebApp.Icon.HttpStatusCodeClassOnCreate.
-  </obsolete>
-  <owner>alancutter@chromium.org</owner>
-  <owner>mgiuca@chromium.org</owner>
-  <summary>
-    The HTTP status code class returned for each icon loaded during a
-    BookmarkApp's creation.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnSync"
-    enum="HttpStatusCodeClass" expires_after="2020-01-01">
-  <obsolete>
-    Removed 2019/05 in favor of WebApp.Icon.HttpStatusCodeClassOnSync.
-  </obsolete>
-  <owner>alancutter@chromium.org</owner>
-  <owner>mgiuca@chromium.org</owner>
-  <summary>
-    The HTTP status code class returned for each icon loaded when syncing a
-    BookmarkApp.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.NavigationResult"
-    enum="BookmarkAppNavigationResult" expires_after="M77">
-  <obsolete>
-    Removed 2019/05 as PWA link capturing has been removed.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    Number of times navigations into and out of Bookmark Apps are processed,
-    grouped by their result.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BookmarkApp.TimeBetweenOpenAppAndLastNavigation"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/05 as PWA link capturing has been removed.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    The time between the last navigation in the context and us opening a new app
-    window in response to a new navigation. If it is very small, the context
-    probably redirected immediately, which is a bad user experience.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BrowsingInstanceViolation.ExtensionType"
-    enum="ExtensionType" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77. Some historical data may be found at
-    (Google-internal, sorry)
-    https://docs.google.com/document/d/11O-73Hs0avk1xkkULn5HoxtY0gvzz3Ff5I3GFvMI_cY
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    When an extension violates browsing instance boundaries, this metric records
-    the extension type.
-
-    This is a temporary metric - probably okay to remove it in M66, after we've
-    gathered sufficient UMA data in M65. See also https://crbug.com/786411.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.BrowsingInstanceViolation.IsBackgroundSourceOrTarget"
-    enum="ExtensionViewTypeIsBackground" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77. Some historical data may be found at
-    (Google-internal, sorry)
-    https://docs.google.com/document/d/11O-73Hs0avk1xkkULn5HoxtY0gvzz3Ff5I3GFvMI_cY
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    When an extension violates browsing instance boundaries, this metric records
-    whether either the source or the target frame was of the extension view type
-    of VIEW_TYPE_BACKGROUND_CONTENTS.
-
-    This is a temporary metric - probably okay to remove it in M66, after we've
-    gathered sufficient UMA data in M65. See also https://crbug.com/786411.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BrowsingInstanceViolation.SourceExtensionViewType"
-    enum="ExtensionViewType" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77. Some historical data may be found at
-    (Google-internal, sorry)
-    https://docs.google.com/document/d/11O-73Hs0avk1xkkULn5HoxtY0gvzz3Ff5I3GFvMI_cY
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    When an extension violates browsing instance boundaries, this metric records
-    the extension view type of the source frame.
-
-    This is a temporary metric - probably okay to remove it in M66, after we've
-    gathered sufficient UMA data in M65. See also https://crbug.com/786411.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.BrowsingInstanceViolation.TargetExtensionViewType"
-    enum="ExtensionViewType" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77. Some historical data may be found at
-    (Google-internal, sorry)
-    https://docs.google.com/document/d/11O-73Hs0avk1xkkULn5HoxtY0gvzz3Ff5I3GFvMI_cY
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    When an extension violates browsing instance boundaries, this metric records
-    the extension view type of the found frame.
-
-    This metric should help confirm or deny the theory that violating browsing
-    instance boundaries is only needed for looking up background contents /
-    pages (of VIEW_TYPE_BACKGROUND_CONTENTS type).
-
-    This is a temporary metric - probably okay to remove it in M66, after we've
-    gathered sufficient UMA data in M65. See also https://crbug.com/786411.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ChromeExtensionsClientInitTime" units="ms"
-    expires_after="2019-12-01">
-  <obsolete>
-    Replaced by Extensions.ChromeExtensionsClientInitTime2.
-  </obsolete>
-  <owner>dbertoni@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The amount of elapsed time taken to initialize the ChromeExtensionsClient.
-    Recorded once per client initialization, which happens once per instance of
-    Chrome.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CorruptPolicyExtensionDetected" enum="BooleanHit"
-    expires_after="2019-05-31">
-  <obsolete>
-    Removed 11/2018. Renamed to Extensions.CorruptPolicyExtensionDetected2.
-  </obsolete>
-  <owner>asargent@chromium.org</owner>
-  <summary>
-    Fires when we detect corruption in an enterprise policy forced install
-    extension and begin the process of reinstalling it. Compare to
-    CorruptPolicyExtensionResolved to judge success rate.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CorruptPolicyExtensionDetected2" enum="BooleanHit"
-    expires_after="M81">
-  <obsolete>
-    Removed 01/2020. Replaced by Extensions.CorruptPolicyExtensionDetected3.
-  </obsolete>
-  <owner>burunduk@chromium.org</owner>
-  <owner>lazyboy@chromium.org</owner>
-  <owner>poromov@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Fires when we detect corruption in an enterprise policy forced install
-    extension and begin the process of reinstalling it. Compare to
-    CorruptPolicyExtensionResolved to judge success rate.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CorruptPolicyExtensionWouldBeDisabled"
-    enum="BooleanHit" expires_after="2016-09-09">
-  <obsolete>
-    Removed 9/2016 by fix for Issue 447040.
-  </obsolete>
-  <owner>asargent@chromium.org</owner>
-  <summary>
-    Fires when we detect corruption in an enterprise policy forced install
-    extension. See http://crbug.com/447040 for more background on why we don't
-    yet disable these. A useful comparison can be made between this value and
-    the number of policy forced extensions loaded at startup, which is logged in
-    the EXTERNAL_POLICY_DOWNLOAD bucket of the Extensions.ExtensionLocation
-    histogram.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CrxFetchError" enum="NetErrorCodes"
-    expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>Net error results from URLFetcher.</summary>
-</histogram>
-
-<histogram name="Extensions.CrxFetchFailureRetryCountGoogleUrl" units="units"
-    expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Number of times chrome retried to download an extension with a url on a
-    google.com domain, before eventually giving up.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CrxFetchFailureRetryCountOtherUrl" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Number of times chrome retried to download an extension with a url on a non
-    google.com domain, before eventually giving up.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CrxFetchSuccessRetryCountGoogleUrl" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Number of times chrome retried to download an extension with a url on a
-    google.com domain, before eventually succeeding.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CrxFetchSuccessRetryCountOtherUrl" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Number of times chrome retried to download an extension with a url on a non
-    google.com domain, before eventually succeeding.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.CrxInstallDirPathLength" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Length of the path to the directory under which an extension is installed.
-    This directory is in the user's profile.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Database.Restore"
-    enum="LevelDBDatabaseCorruptionRestoreValue" expires_after="2016-01-07">
-  <obsolete>
-    Shipped only in M48. Superceded by Extensions.Database.Database.Restore and
-    Extensions.Database.Value.Restore.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The result of an attempt to recover from an attempt to open a database that
-    failed as a result of corruption.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension"
-    units="ms" expires_after="2020-12-30">
-  <obsolete>
-    Removed Jan 2020 to increase resolution to microseconds. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension2.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Time taken to evaluate the before-request action for a network request for a
-    single extension ruleset. Emitted for each network request that is visible
-    to the extension.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed Dec 2018. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be blocked or
-    redirected as per the Declarative Net Request API. This includes the time
-    taken to evaluate all the extension rulesets. Emitted for non-sensitive
-    network requests seen by the Extension System.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"
-    units="ms" expires_after="2020-12-30">
-  <obsolete>
-    Removed Jan 2020 to increase resolution to microseconds. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be blocked or
-    redirected as per the Declarative Net Request API. This includes the time
-    taken to evaluate all the extension rulesets. Emitted for non-sensitive
-    network requests seen by the Extension System when there is at least one
-    active extension ruleset.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DeclarativeNetRequest.IndexRulesTime" units="ms"
-    expires_after="2019-03-22">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to index the deserialized json rules provided by an extension
-    manifest for the Declarative Net Request API. This is emitted whenever an
-    extension's json ruleset is successfully indexed. This may happen when a
-    packed extension is installed, an unpacked extension is loaded, an
-    extension's ruleset is re-indexed due to corruption, etc.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DeclarativeNetRequest.ManifestRulesCount"
-    units="rules" expires_after="2020-12-30">
-  <obsolete>
-    Removed April 2020. Replaced with
-    Extensions.DeclarativeNetRequest.ManifestRulesCount2.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>lazyboy@chromium.org</owner>
-  <summary>
-    The number of indexed declarative rules provided by an extension manifest
-    for the Declarative Net Request API. This is emitted whenever a packaged
-    extension with a declarative ruleset is installed or updated.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.PageWhitelistingInitiatorCheck"
-    enum="PageWhitelistingInitiatorCheck" expires_after="2020-12-30">
-  <obsolete>
-    Removed Jan 2020. The addAllowedPages API was removed.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>lazyboy@chromium.org</owner>
-  <summary>
-    Describes the different cases pertaining to initiator checks used by the
-    Declarative Net Request Page Whitelisting API. Emitted whenever an extension
-    ruleset is evaluated for a main frame sub-resource request.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.ShouldBlockRequestTime.AllExtensions"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed May 2018. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be blocked as per
-    the Declarative Net Request API. This includes the time taken to evaluate
-    all the extension rulesets. Emitted whenever a non-sensitive network request
-    is seen by the Extension System.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.ShouldBlockRequestTime.SingleExtension"
-    units="ms" expires_after="2020-12-30">
-  <obsolete>
-    Removed December 2019. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be blocked for a
-    single extension ruleset. Emitted for each network request that is visible
-    to the extension.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.ShouldRedirecRequestTime.SingleExtension"
-    units="ms" expires_after="2020-12-30">
-  <obsolete>
-    Removed December 2019. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be redirected for a
-    single extension ruleset. Emitted for network requests visible to the
-    extension.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeNetRequest.ShouldRedirectRequestTime.AllExtensions"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed May 2018. Replaced with
-    Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Time taken to evaluate whether a network request should be redirected as per
-    the Declarative Net Request API. This includes the time taken to evaluate
-    all the extension rulesets. Emitted for non-sensitive network requests seen
-    by the Extension System.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DeclarativeWebRequest.ConditionAttributeType"
-    enum="WebRequestConditionAttributeType" expires_after="2020-10-30">
-  <obsolete>
-    Removed 09/2020.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    The type of each WebRequestConditionAttribute created as part of the
-    declarativeWebRequest API.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.DeclarativeWebRequest.WebViewRequestDeclarativeRules"
-    enum="BooleanDeclarativeRules" expires_after="M78">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Whether a network request from a guest webview has any declarative web
-    request rules that need to be evaluated. Emitted whenever a network request
-    from a guest webview is received at the network layer.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DepricatedExternalJsonCount" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of extensions referenced in the depricated external extensions source
-    at path chrome::DIR_DEPRICATED_EXTERNAL_EXTENSIONS.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DialogLoadTime" units="ms"
-    expires_after="2015-02-06">
-  <obsolete>
-    There is no such thing as an extension dialog.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time for a dialog-hosted extension to load.</summary>
-</histogram>
-
-<histogram name="Extensions.DidSuppressJavaScriptException"
-    enum="ChromeChannelForHistogram" expires_after="2018-08-30">
-  <obsolete>
-    Expired 2018-08
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Records the Chrome channel when JavaScript exceptions are not gracefully
-    dealt with, and suppressed by C++ instead. These are exceptions generated
-    (or simply not caught and gracefully recovered) in our own internal
-    JavaScript, not from JavaScript code written by developers (that which is
-    typically hosted in CRX files). This should be 0 for unstable channels like
-    canary and dev, because we try *not* to suppress errors and instead kill the
-    renderer and generate a crash report. However, at times we need to suppress
-    even those. Note that this histogram is intended to be tracked over time,
-    per channel, to observe crash rates. Comparisons between
-    stable/beta/dev/canary are unlikely to be meaningful.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DisabledUIUserResponse"
-    enum="ExtensionDisabledUIUserResponse" expires_after="2017-03-15">
-  <obsolete>
-    Removed 03/2017 because miscounting IGNORE histogram entry. This error is
-    fixed with DisabledUIUserResponse2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    User response to the dialog shown when an extension is disabled due to an
-    update requiring more permissions.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DisabledUIUserResponseRemoteInstall"
-    enum="ExtensionDisabledUIUserResponse" expires_after="2017-03-15">
-  <obsolete>
-    Removed 03/2017 because miscounting IGNORE histogram entry. This error is
-    fixed with DisabledUIUserResponseRemoteInstall2.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    User response to the dialog shown when an extension is disabled due to it
-    having been installed remotely.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.DocsOfflineIconState" enum="ExtensionIconState"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The state of the toolbar icon for the docs offline extension (visible in the
-    toolbar, overflowed in the menu, or the extension is disabled). Recorded
-    once per startup per (non-incognito) profile.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.EnhancedBookmarksManagerNumEventListeners"
-    units="units" expires_after="2016-04-15">
-  <obsolete>
-    Obsolete since the enhanced bookmarks manager is no longer using an event
-    page.
-  </obsolete>
-  <owner>wittman@chromium.org</owner>
-  <summary>
-    The number of event listeners the Enhanced Bookmarks Manager has, measured
-    at profile startup. A value of 0 implies that Chrome has a general bug with
-    event page management, since the bookmarks manager should always have at
-    least one event listener - but a bug with event page management that affects
-    the bookmarks manager is particularly dire.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.EventPageActiveTime" units="ms"
-    expires_after="2015-02-06">
-  <obsolete>
-    Replaced by Extensions.EventPageActiveTime2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>The time an extension's event page has spent loaded.</summary>
-</histogram>
-
-<histogram name="Extensions.EventPageLoadTime" units="ms"
-    expires_after="2015-02-06">
-  <obsolete>
-    Replaced by Extensions.EventPageLoadTime2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>The time for an extension's event page to load.</summary>
-</histogram>
-
-<histogram name="Extensions.Events.DispatchToComponentWithSuspendedEventPage"
-    enum="ExtensionEvents" expires_after="M81">
-  <obsolete>
-    Removed 21-Jan-2020.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Recorded every time an event is dispatched to a *component* extension with a
-    suspended event page. Otherwise identical to
-    Extensions.Events.DispatchWithSuspendedEventPage.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionCreationTime" units="microseconds"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-05.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The amount of time taken to create a single extension object. This includes
-    parsing all the different extension manifest keys and initializating the
-    associated manifest data.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionFrameMapCacheHit" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    True if the cache of the extension frame map was hit during access on the IO
-    thread.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionFrameMapLookupSuccessful" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    True if the lookup for a frame in the extension frame map succeeded after a
-    cache miss.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionHostMonitoring.MaxActiveLoading"
-    units="units" expires_after="2019-11-21">
-  <obsolete>
-    Removed 2019-11
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The maximum number of ExtensionHosts (primarily background/event pages) that
-    were actively loading at any one time, within the first minute of Chrome
-    startup. Emitted exactly one minute after startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionHostMonitoring.MaxInQueue" units="units"
-    expires_after="2019-11-21">
-  <obsolete>
-    Removed 2019-11
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The maximum number of ExtensionHosts (primarily background/event pages) in
-    the queue awaiting being loaded (via an ExtensionHostQueue), within the
-    first minute of Chrome startup. Emitted exactly one minute after startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionHostMonitoring.NumLoaded" units="units"
-    expires_after="2019-11-21">
-  <obsolete>
-    Removed 2019-11
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The total number of ExtensionHosts that completed loading in the first
-    minute of Chrome startup. Emitted exactly one minute after startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionHostMonitoring.NumQueued" units="units"
-    expires_after="2019-11-21">
-  <obsolete>
-    Removed 2019-11
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The total number of ExtensionHosts (primarily background/event pages) that
-    were added to a queue to start loading, within the first minute of Chrome
-    startup. These may or may not end up starting, let alone finishing,
-    depending on the queue behavior. Emitted exactly one minute after startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionManagement_RefreshTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during ExtensionManagement::Refresh.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionRendererStateCacheHit" enum="Boolean"
-    expires_after="2016-04-05">
-  <obsolete>
-    Removed 4/2016. ExtensionRendererState was replaced with ExtensionFrameMap.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    True if the cache for the ExtensionRendererState was hit during a lookup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterFirstUpdateCheckErrorsGoogleUrl"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M75">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the error codes of the extension updater update check errors. These
-    events are triggered only when the extension updater gets an error for the
-    first time (before any retry) in the update check phase for a google.com
-    domain.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterFirstUpdateCheckErrorsNonGoogleUrl"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M75">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the error codes of the extension updater update check errors. These
-    events are triggered only when the extension updater gets an error for the
-    first time (before any retry) in the update check phase for a non google.com
-    domain.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterRawUpdateCalls" units="extensions"
-    expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The number of extensions that are checked for update. This number is emitted
-    right before the extensions are split between the current extension updater
-    and the unified extension updater (if used).
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterUpdateCalls" units="extensions"
-    expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The number of extensions that are passed over to the extension updater for
-    update check. Triggered when the extension updater starts doing update
-    check.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterUpdateFoundCount"
-    units="extensions" expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The number of extensions that have updates in an update check session.
-    Triggered when the extension updater found an update for an extension.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExtensionUpdaterUpdateResults"
-    enum="ExtensionUpdaterUpdateResult" expires_after="M81">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the update results of extensions in an extension updater session,
-    grouped by ExtensionUpdaterUpdateResult.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ExternalWarningUninstallationResult" enum="Boolean"
-    expires_after="2019-01-29">
-  <obsolete>
-    Expired 2018-08.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Whether or not the uninstallation of an external extension succeeded.
-    Triggered when the external install warning is shown to the user and the
-    user selects to remove the extension.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.FileInstallation" units="ms" expires_after="M77">
-  <obsolete>
-    Expired after M77.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <summary>
-    Record the time taken to physically move the extention files from temporary
-    location to the final installation directory. It includes the time to flush
-    the file system if ExtensionUseSafeInstallation field trial is enabled. This
-    is recorded once per extension install/update.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.FontSettingsEventRouterCtorTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the FontSettingsEventRouter
-    construction.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledFailureManifestInvalidErrorDetail"
-    enum="ManifestInvalidError" expires_after="2020-09-01">
-  <obsolete>
-    Removed 07/2020, replaced by
-    Extensions.ForceInstalledFailureManifestInvalidErrorDetail2.
-  </obsolete>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>burunduk@chromium.org</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    The detailed reason why enterprise policy forced extensions had failed to
-    install because fetched update manifest was invalid. Recorded for each
-    forced extension that failed to install after 5 minutes with
-    Extensions.ForceInstalledFailureReason2 equal to MANIFEST_INVALID.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledFailureReason"
-    enum="ExtensionInstallationFailureReason" expires_after="M80">
-  <obsolete>
-    Removed 12/2019, replaced by Extensions.ForceInstalledFailureReason3.
-  </obsolete>
-  <owner>askaraitzhan@google.com</owner>
-  <owner>burunduk@chromium.org</owner>
-  <owner>poromov@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The reason why enterprise policy forced extensions were not installed.
-    Recorded for each forced extension that failed to install after 5 minutes.
-    Recorded together with &quot;Extensions.ForceInstalledTimedOutCount&quot;
-    histogram, but for every extension not installed at the moment.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledFailureReason2"
-    enum="ExtensionInstallationFailureReason" expires_after="2020-11-01">
-  <obsolete>
-    Removed 04/2020, replaced by Extensions.ForceInstalledFailureReason3.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="ExtensionSource" -->
-
-  <owner>burunduk@chromium.org</owner>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    The reason why enterprise policy forced extensions were not installed.
-    Recorded for each forced extension that failed to install after 5 minutes.
-    Recorded together with &quot;Extensions.ForceInstalledTimedOutCount&quot;
-    histogram, but for every extension not installed at the moment.
-
-    Replaced Extensions.ForceInstalledFailureReason because of splitting
-    CRX_FETCH_FAILED options into three dirrerent failures.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledFailureUpdateCheckStatus"
-    enum="UpdateCheckStatus" expires_after="2020-09-01">
-  <obsolete>
-    Removed 2020-08-28 because it is verified from the collected statistics that
-    we always receive &quot;no update&quot; status in case of
-    CRX_FETCH_URL_EMPTY.
-  </obsolete>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>burunduk@chromium.org</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    The update check status details for enterprise policy forced extensions when
-    update manifest is fetched from server. Recorded for each forced extension
-    that failed to install after 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledHttpErrorCode"
-    enum="HttpResponseCode" expires_after="2021-01-24">
-  <obsolete>
-    Removed 2020-08-28, replaced by Extensions.ForceInstalledHttpErrorCode2.
-  </obsolete>
-  <owner>burunduk@chromium.org</owner>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    HTTP error code for the last retry attempt when CRX fetch failed for
-    enterprise policy forced extensions. Recorded for each forced extension that
-    failed to install after 5 minutes with
-    Extensions.{OffStore,WebStore}_ForceInstalledFailureReason3 equal to
-    CRX_FETCH_FAILED and a HTTP response code was received. HTTP response code
-    is received only if there was no network error.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledManifestFetchFailedHttpErrorCode"
-    enum="HttpResponseCode" expires_after="2021-01-24">
-  <obsolete>
-    Removed 2020-08-28, replaced by
-    Extensions.ForceInstalledManifestFetchFailedHttpErrorCode2.
-  </obsolete>
-  <owner>burunduk@chromium.org</owner>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    HTTP error code for the last retry attempt when Manifest fetch failed for
-    enterprise policy forced extensions. Recorded for each forced extension that
-    failed to install after 5 minutes with
-    Extensions.{OffStore,WebStore}_ForceInstalledFailureReason3 equal to
-    MANIFEST_FETCH_FAILED and a HTTP response code was received. HTTP response
-    code is received only if there was no network error.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ForceInstalledStage"
-    enum="ExtensionInstallationStage" expires_after="2021-01-24">
-  <obsolete>
-    Removed 09/2020, replaced by Extensions.ForceInstalledStage2.
-  </obsolete>
-  <owner>burunduk@chromium.org</owner>
-  <owner>swapnilgupta@google.com</owner>
-  <owner>managed-devices@google.com</owner>
-  <summary>
-    The last known stage of extension installation process if failure reason was
-    not recorded (installation of an extension was neither yet finished nor
-    failed). Recorded for each forced extension that failed to install after 5
-    minutes. Recorded together with
-    &quot;Extensions.ForceInstalledTimedOutCount&quot; histogram, but for every
-    extension not installed at the moment.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.FunctionCalls" enum="ExtensionFunctions"
-    expires_after="M80">
-  <obsolete>
-    Replaced by Extensions.Functions.ComponentExtensionCalls,
-    Extensions.Functions.ExtensionCalls, and Extensions.Functions.WebUICalls
-    2019-05.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>Number of calls to extension functions.</summary>
-</histogram>
-
-<histogram name="Extensions.GetUserDataTempDir" enum="GetUserDataTempDirResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    What happens when the extensions system tries to get a temp dir to unpack
-    in?
-  </summary>
-</histogram>
-
-<histogram name="Extensions.HasPermissions_WebStoreInstallAbort3"
-    enum="Boolean" expires_after="M85">
-  <obsolete>
-    Code removed 2020-06.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Whether there were any permissions present in an extension when installation
-    from the web store was aborted (e.g. because the parent window of the
-    confirmation dialog went away), not including installation errors and user
-    cancels. To find places where this histogram may be emitted, look for calls
-    to ExtensionService::RecordPermissionMessagesHistogram with the argument
-    WebStoreInstallAbort.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.HostedAppUnlimitedStoragePersistentStorageUsage"
-    units="KB" expires_after="2018-08-30">
-  <obsolete>
-    Expired 2018-08
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The usage (in kilobytes) of persistent storage in a hosted app with the
-    unlimitedStorage permission. This is logged each time the storage is used*,
-    so this also serves as a cap of the number of calls that would fail if the
-    app did not have the unlimited storage permission. *Capped at once per 30
-    seconds so as to not impact performance.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.HostedAppUnlimitedStorageTemporaryStorageUsage"
-    units="%" expires_after="2018-08-30">
-  <obsolete>
-    Expired 2018-08
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The percentage of &quot;normal&quot; (that is, not unlimited) quota that a
-    hosted app with unlimited storage is currently using. This is logged each
-    time the storage is used*, so the number of times the app would use greater
-    than 100% of the default storage can serve as a cap for the number of calls
-    that would fail if the app did not have the unlimitedStorage permission.
-    *Capped at once per 30 seconds so as to not impact performance.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.HostedAppUnlimitedStorageUsage" units="KB"
-    expires_after="2018-08-30">
-  <obsolete>
-    Expired 2018-08-30
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The usage (in kilobytes) of a hosted app with the unlimitedStorage api
-    permission, recorded once per run per app the first time we load storage for
-    the hosted app. This is separate from the other metrics on hosted app
-    unlimited storage usage because it is logged once per extension per run.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.InitExtensionControlledPrefsTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during
-    ExtensionPrefs::InitExtensionControlledPrefs.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.InitPrefStoreTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during ExtensionPrefs::InitPrefStore.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.InjectScriptTime" units="ms"
-    expires_after="2017-03-20">
-  <obsolete>
-    Removed 03/2017 in favor of Extensions.InjectedScriptExecutionTime.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>Time taken to inject all scripts by extensions.</summary>
-</histogram>
-
-<histogram name="Extensions.InstallPrompt.Accepted" enum="BooleanAccepted"
-    expires_after="2019-05-13">
-  <obsolete>
-    Obsolete as of 2019-05 as it can be derived by comparing the aggregate
-    counts of Extensions.InstallPrompt.TimeToInstall and
-    Extensions.InstallPrompt.TimeToInstall.
-  </obsolete>
-  <owner>meacer@chromium.org</owner>
-  <summary>
-    Whether the user accepted or aborted an extension installation.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.InstallPrompt.Type"
-    enum="ExtensionInstallPromptType" expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07. The previous enum was garbled.
-  </obsolete>
-  <owner>meacer@chromium.org</owner>
-  <summary>
-    Type of the extension install prompt displayed when an extension
-    installation is triggered.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.LoadAllTime" units="ms" expires_after="2019-11-01">
-  <obsolete>
-    Removed as of 2019-11. Replaced by Extensions.LoadAllTime2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Time taken to load all non-component extensions at profile open. This
-    happens as part of the total initialization time of ExtensionService,
-    measured in Extensions.ExtensionServiceInitTime.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.LoadContentPack" units="units"
-    expires_after="2015-04-23">
-  <obsolete>
-    Removed as of 4/2015. Replaced by ManagedUsers.Whitelist.Count.
-  </obsolete>
-  <owner>asargent@chromium.org</owner>
-  <summary>
-    The number of content-pack extensions loaded at profile open.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Extensions.LongInjectionTaskTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The amount of time taken to inject content scripts. If multiple scripts are
-    injected within a single task, this records the time taken to execute all
-    the scripts.
-
-    This metric only logs tasks longer than 50 milliseconds. This threshold
-    aligns with the definition of &quot;long task&quot; in Long Tasks API
-    (https://w3c.github.io/longtasks/).
-
-    Note that this histogram itself doesn't tell you what percentage of content
-    scripts are greater than 50 ms. See Extensions.Inject{Start,End,Idle}_Time
-    and Extensions.InjectedScriptExecutionTime.* for the overall distribution.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Messaging.IncludeChannelIdBehavior"
-    enum="ExtensionMessagingIncludeChannelIdBehavior"
-    expires_after="2019-12-01">
-  <obsolete>
-    Removed January 2020.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    The behavior for including the TLS channel ID in the information sent with
-    extension messaging. Recorded once per opened channel.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.NetworkDelayRegistryLoad" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <summary>
-    Time that network requests were blocked due to relevant rule registries
-    loading.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.NetworkDelayStartup" units="ms"
-    expires_after="2016-09-15">
-  <obsolete>
-    Never used. Added to source 06/2012. Removed from source and added here
-    09/2016.
-  </obsolete>
-  <summary>
-    Delay of network requests due to waiting for extension declarativeWebRequest
-    rules to be loaded from disk at startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_AutoDisable" enum="ExtensionPermission"
-    expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_AutoDisable2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it is automatically disabled
-    due to a permission increase (e.g., after an extension upgrade).
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_AutoDisable2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_AutoDisable3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it is automatically disabled
-    due to a permission increase (e.g., after an extension upgrade).
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Install" enum="ExtensionPermission"
-    expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_Install2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was installed.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Install2" enum="ExtensionPermission2"
-    expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_Install3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was installed.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_InstallAbort"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_InstallAbort2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation was aborted, not
-    including installation errors and user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_InstallAbort2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_InstallAbort3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation was aborted, not
-    including installation errors and user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_InstallCancel"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_InstallCancel2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation was canceled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_InstallCancel2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_InstallCancel3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation was canceled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Load" enum="ExtensionPermission"
-    expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_Load2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>The permissions present in an extension when it was loaded.</summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Load2" enum="ExtensionPermission2"
-    expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_Load3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>The permissions present in an extension when it was loaded.</summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnable" enum="ExtensionPermission"
-    expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_ReEnable2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was re-enabled from a
-    confirmation prompt.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnable2" enum="ExtensionPermission2"
-    expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_ReEnable3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was re-enabled from a
-    confirmation prompt.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnableAbort"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_ReEnableAbort2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when the re-enable prompt was
-    aborted, not including installation errors and manual user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnableAbort2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_ReEnableAbort3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when the re-enable prompt was
-    aborted, not including installation errors and manual user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnableCancel"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_ReEnableCancel2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when the re-enable was canceled from
-    the confirmation prompt.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_ReEnableCancel2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_ReEnableCancel3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when the re-enable was canceled from
-    the confirmation prompt.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Uninstall" enum="ExtensionPermission"
-    expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_Uninstall2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was uninstalled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_Uninstall2" enum="ExtensionPermission2"
-    expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_Uninstall3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was uninstalled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstall"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by Extensions.Permissions_WebStoreInstall2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was installed through the
-    web store.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstall2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by Extensions.Permissions_WebStoreInstall3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when it was installed through the
-    web store.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstallAbort"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by
-    Extensions.Permissions_WebStoreInstallAbort2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation from the web store
-    was aborted, not including installation errors and user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstallAbort2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by
-    Extensions.Permissions_WebStoreInstallAbort3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation from the web store
-    was aborted, not including installation errors and user cancels.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstallCancel"
-    enum="ExtensionPermission" expires_after="2014-06-04">
-  <obsolete>
-    Removed as of 5/2014, replaced by
-    Extensions.Permissions_WebStoreInstallCancel2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation from the web store
-    was canceled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Permissions_WebStoreInstallCancel2"
-    enum="ExtensionPermission2" expires_after="2015-06-12">
-  <obsolete>
-    Removed as of 6/2015, replaced by
-    Extensions.Permissions_WebStoreInstallCancel3.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>rpaquay@chromium.org</owner>
-  <summary>
-    The permissions present in an extension when installation from the web store
-    was canceled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.PopupLoadTime" units="ms"
-    expires_after="2015-02-06">
-  <obsolete>
-    Replaced by Extensions.PopupLoadTime2.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>The time for an Extension's popup to load.</summary>
-</histogram>
-
-<histogram name="Extensions.ProcessManagerStartupHostsTime" units="ms"
-    expires_after="2019-12-02">
-  <obsolete>
-    Replaced by Extensions.ProcessManagerStartupHostsTime2 - 12/2019
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The time taken to start up persistent background pages for extensions in
-    ExtensionProcessManager when the extension system notifies that it is ready.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ResourceDirectoryTimestampQueryLatency" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07. Data no longer needed.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The initialization latency (in milliseconds) introduced to each extension
-    resource request by querying the directory timestamp.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackFailure" units="units"
-    expires_after="M84">
-  <obsolete>
-    Can be inferred from SandboxUnpackFailureReason.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Count the number of times a sandboxed extension unpack fails.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackFailureTime" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>Time taken to unpack an extension, when the unpack fails.</summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackInitialCrxPathLength" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>Length of the initial path to the CRX to be unpacked.</summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackLinkFreeCrxPathLength" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Length of the normalized (link/junction free) path to the temporary copy of
-    a CRX made during unpacking.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRate" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which a CRX file is unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRate1To2mB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files 1MB to 2MB are unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRate2To5mB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files 2MB to 5MB are unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRate50kBTo1mB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files 50kB to 1MB are unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRate5To10mB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files 5MB to 10 MB are unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRateOver10mB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files larger than 10MB are unpacked in Kilobytes per
-    second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackRateUnder50kB" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Rate at which CRX files under 50 KB are unpacked in Kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackSuccessCantGetCrxSize" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Count the number of times a sandboxed CRX unpack succeeds, but we can't get
-    the file size.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackSuccessCrxSize" units="units"
-    expires_after="M84">
-  <obsolete>
-    Code removed 2020-04.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>Size of the .crx file, in KB, when the unpack succeeds.</summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackSuccessTime" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Time taken to unpack an extension, when the unpack succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackTempCrxPathLength" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Length of the path of the temporary copy of a CRX made during unpacking.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SandboxUnpackUnpackedCrxPathLength" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Code removed 2020-04. No longer being monitored.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>Length of the path under which a CRX is unpacked.</summary>
-</histogram>
-
-<histogram name="Extensions.SettingsQuotaExceeded.BytesPerSetting"
-    units="units" expires_after="2016-09-13">
-  <obsolete>
-    Removed in September, 2016
-  </obsolete>
-  <summary>
-    Emitted when QuotaExceededError was called due to an extension using too
-    many bytes for a given setting. The number has no natural numerator
-    (normalizing factor) and thus is not particularly useful.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SettingsQuotaExceeded.KeyCount" units="units"
-    expires_after="2016-09-13">
-  <obsolete>
-    Removed in September, 2016
-  </obsolete>
-  <summary>
-    Emitted when QuotaExceededError was called due to an extension using too
-    many keys. The number has no natural numerator (normalizing factor) and thus
-    is not particularly useful.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.SettingsQuotaExceeded.TotalBytes" units="units"
-    expires_after="2016-09-13">
-  <obsolete>
-    Removed in September, 2016
-  </obsolete>
-  <summary>
-    Emitted when QuotaExceededError was called due to an extension using too
-    many bytes. The number has no natural numerator (normalizing factor) and
-    thus is not particularly useful.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ShouldAllowOpenURL.Failure"
-    enum="ShouldAllowOpenURLFailureReason" expires_after="M77">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    When the web-accessible resource check in
-    ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL fails, this
-    records the reason for the failure. This check is performed on navigations
-    that utilize the OpenURL path as well as on transfers.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ShouldAllowOpenURL.Failure.Scheme"
-    enum="ShouldAllowOpenURLFailureScheme" expires_after="M77">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    When the web-accessible resource check in
-    ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL fails, this
-    records the scheme of the SiteInstance that initiated the blocked load. This
-    check is performed on navigations that utilize the OpenURL path as well as
-    on transfers.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.StartupDelay" units="ms" expires_after="2017-05-15">
-  <obsolete>
-    This has not been recorded since at least mid-2013.
-  </obsolete>
-  <owner>asargent@chromium.org</owner>
-  <summary>The time one extension delays network requests at startup.</summary>
-</histogram>
-
-<histogram name="Extensions.StartupDelay_Total" units="ms"
-    expires_after="2017-05-15">
-  <obsolete>
-    This has not been recorded since at least mid-2013.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The total time extensions delay network requests at startup.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.StorageFrontendInitTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during StorageFrontend::Init.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ThrottledNetworkRequests" units="requests"
-    expires_after="2018-08-30">
-  <obsolete>
-    Expired 2018-08.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The total number of network requests that were delayed by extension user
-    script load. Recorded once each time network requests may have been delayed
-    by user script load (i.e., once at the end of each batch of script loads).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Extensions.TimeYieldedBetweenContentScriptRuns"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Time elapsed between two asynchronously-injected content script runs.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Toolbar.PinnedExtensionCount"
-    units="pinned extensions" expires_after="M84">
-  <obsolete>
-    Replaced by Extensions.Toolbar.PinnedExtensionCount2 in 2020/05.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The number of extensions that the user has pinned on the toolbar. Recorded
-    once per profile during initialization.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Toolbar.PinnedExtensionPercentage" units="%"
-    expires_after="2021-06-30">
-  <obsolete>
-    Replaced by Extensions.Toolbar.PinnedExtensionPercentage2 in 2020/05.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The percentage of extensions that the user has pinned to the toolbar (i.e.,
-    this will be 100 if the user has every extension pinned). Recorded once per
-    profile during initialization.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.Toolbar.PinnedExtensionPercentage2" units="%"
-    expires_after="2021-06-30">
-  <obsolete>
-    Replaced by Extensions.Toolbar.PinnedExtensionPercentage3 in 2020/05.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The percentage of extensions that the user has pinned to the toolbar (i.e.,
-    this will be 100 if the user has every extension pinned). Recorded once per
-    profile during initialization if the user has at least one extension with an
-    action in the toolbar.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.ToolstripLoadTime" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time taken to load a toolstrip.</summary>
-</histogram>
-
-<histogram name="Extensions.UnifiedExtensionUpdaterDownloadErrors"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M81">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the error codes of the unified extension updater download errors.
-    These events are triggered when the extension updater fails to download the
-    extension update package of an extension, which can happen only after the
-    updater has successfuly determined that there is an update for the
-    extension.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnifiedExtensionUpdaterUpdateCalls"
-    units="extensions" expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The number of extensions that are passed over to the unified extension
-    updater for update check. Triggered when the new extension updater starts
-    doing update check.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnifiedExtensionUpdaterUpdateCheckErrors"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M81">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the error codes of the unified extension updater update check
-    errors. These events are triggered only when the new extension updater gets
-    an error in the update check phase.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnifiedExtensionUpdaterUpdateResults"
-    enum="ExtensionUpdaterUpdateResult" expires_after="M81">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Records the update results of extensions in an unified extension updater
-    session, grouped by ExtensionUpdaterUpdateResult.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnifiedExtensionUpdaterUpdateServiceErrors"
-    enum="UpdateClientErrors" expires_after="M81">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The update service errors that the update service encouters during an update
-    check session using update client.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnpackFailureInstallCause"
-    enum="ExtensionInstallCause" expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Count failing CRX installs, grouped by the way an extension can be
-    installed.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnpackFailureInstallSource"
-    enum="ExtensionLocation" expires_after="2020-06-01">
-  <obsolete>
-    Code removed 2020-06.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The install source of an extension that failed to unpack correctly. Emitted
-    each time an extension fails to unpack from the CrxInstaller.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnpackSuccessInstallCause"
-    enum="ExtensionInstallCause" expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    Count successful CRX installs, grouped by the cause of the install.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UnpackSuccessInstallSource"
-    enum="ExtensionLocation" expires_after="2020-06-01">
-  <obsolete>
-    Code removed 2020-06.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The install source of an extension that succeeded in unpacking correctly.
-    Emitted each time an extension successfully unpacks from the CrxInstaller.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UpdateCheckGap" units="minutes"
-    expires_after="2019-01-18">
-  <obsolete>
-    Removed 2019-01.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>Time in minutes between update checks.</summary>
-</histogram>
-
-<histogram name="Extensions.UpdateFrequencyCommandLineFlagIsUsed"
-    enum="BooleanPresent" expires_after="2018-03-20">
-  <obsolete>
-    Removed 3/2018 in https://crbug.com/357781 with the removal of the
-    extensions-update-frequency command line flag.
-  </obsolete>
-  <owner>catmullings@chromium.org</owner>
-  <summary>
-    Logs whether or not the extensions-update-frequency command line flag is
-    used. Recorded at profile creation if extensions autoupdate is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UpdateManifestDuplicateEntryCount" units="entries"
-    expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    Counts the number of entries with the same extension ID found in the update
-    manifest of an update check request. When the update manifest does not
-    contain any update entry for an extension ID in the update check request,
-    the count will be 0.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UpdateManifestHasProdVersionMinCounts"
-    units="extensions" expires_after="M77">
-  <obsolete>
-    Expired.
-  </obsolete>
-  <owner>waffles@chromium.org</owner>
-  <summary>
-    The number of prodversionmin attributes appearing in an update manifest of
-    an update check request.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.UpdaterWriteCrx" enum="ExtensionFileWriteResult"
-    expires_after="2013-10-03">
-  <obsolete>
-    Removed 10/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    What happened when the extension updater tried to write a file?
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.InitiatorAccess" enum="InitiatorAccess"
-    expires_after="2018-12-31">
-  <obsolete>
-    Removed November 2018. Replaced with Extensions.WebRequest.InitiatorAccess2.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Describes the different cases pertaining to host permissions check for the
-    initiator URL of a network request. This is emitted whenever an extension is
-    found to have access to a request url, when checked by the WebRequest API.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.InitiatorAccess2"
-    enum="InitiatorAccess2" expires_after="2019-04-30">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>karandeepb@chromium.org</owner>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Describes the different cases pertaining to host permissions check for the
-    initiator URL of a network request. This is emitted whenever an extension is
-    found to have access to a request url for the WebRequest or Declarative Net
-    Request API.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.ModifiedResponseHeaders"
-    enum="WebRequestResponseHeaderType" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018 as this is no longer needed.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Tracks whether any interesting response header modifications were made for
-    each request seen by the Web Request API. Logged for every network request
-    as long as one or more enabled extensions is using a declarative or blocking
-    filter to process onHeadersReceived events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M69.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.SetCookieResponseHeaderChanged"
-    enum="BooleanChanged" expires_after="M73">
-  <obsolete>
-    Removed May 2019.
-  </obsolete>
-  <owner>cduvall@chromium.org</owner>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Whether the set-cookie response header was changed by an extension using the
-    Web Request API. Logged for every network request as long as one or more
-    enabled extensions is using a declarative or blocking filter to process
-    onHeadersReceived events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M73.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.SetCookieResponseHeaderRemoved"
-    enum="BooleanRemoved" expires_after="M73">
-  <obsolete>
-    Removed May 2019.
-  </obsolete>
-  <owner>cduvall@chromium.org</owner>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Whether the set-cookie response header was removed by an extension using the
-    Web Request API. Logged for every network request as long as one or more
-    enabled extensions is using a declarative or blocking filter to process
-    onHeadersReceived events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M73.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.SpecialHeadersRemoved"
-    enum="WebRequestSpecialHeaderRemoval" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018 as this is no longer needed.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Whether either or both of the special Accept-Language or User-Agent request
-    headers were removed by an extension using the Web Request API. Logged for
-    every network request as long as one or more enabled extensions is using a
-    declarative or blocking filter to process onBeforeSendHeaders events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M69.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.SpecialRequestHeadersChanged"
-    enum="WebRequestSpecialRequestHeaderModification" expires_after="M73">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>cduvall@chromium.org</owner>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Whether Accept-Language, Accept-Encoding, User-Agent, Cookie, Referer, or
-    mulitple of these request headers were changed by an extension using the Web
-    Request API. Logged for every network request as long as one or more enabled
-    extensions is using a declarative or blocking filter to process
-    onBeforeSendHeaders events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M73.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.SpecialRequestHeadersRemoved"
-    enum="WebRequestSpecialRequestHeaderModification" expires_after="M73">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>cduvall@chromium.org</owner>
-  <owner>karandeepb@chromium.org</owner>
-  <summary>
-    Whether Accept-Language, Accept-Encoding, User-Agent, Cookie, Referer, or
-    mulitple of these request headers were removed by an extension using the Web
-    Request API. Logged for every network request as long as one or more enabled
-    extensions is using a declarative or blocking filter to process
-    onBeforeSendHeaders events.
-
-    This histogram is temporary, for investigating https://crbug.com/827582. It
-    can probably be removed by M73.
-  </summary>
-</histogram>
-
-<histogram
-    name="Extensions.WebRequest.WS_CookiesAreModifiedOnBeforeSendHeaders"
-    units="boolean" expires_after="M80">
-  <obsolete>
-    Removed as of Jan 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Whether cookies on a websocket connection are modified in
-    OnBeforeSendHeaders.
-
-    This histogram is temporary, for investigating https://crbug.com/827582.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.WS_CookiesAreModifiedOnHeadersReceived"
-    units="boolean" expires_after="2019-01-09">
-  <obsolete>
-    Removed as of Jan 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Whether cookies on a websocket connection are modified in OnHeadersReceived.
-
-    This histogram is temporary, for investigating https://crbug.com/827582.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Extensions.WebRequest.WS_RequestHeaders"
-    units="units" expires_after="2019-01-09">
-  <obsolete>
-    Removed as of Jan 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Whether certain headers are modified in OnBeforeSendHeaders.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.WS_RequestHeadersModification"
-    enum="WebRequestWSRequestHeadersModification" expires_after="2019-01-09">
-  <obsolete>
-    Removed as of Jan 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Tracks request headers modifications on a websocket connection in
-    OnBeforeSendHeaders.
-
-    This histogram is temporary, for investigating https://crbug.com/827582.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequest.WS_ResponseHeadersAreModified"
-    units="boolean" expires_after="2019-01-09">
-  <obsolete>
-    Removed as of Jan 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Whether response headers on a websocket connection are modified in
-    OnHeadersReceived.
-
-    This histogram is temporary, for investigating https://crbug.com/827582.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebRequestEventFoundFrame" units="boolean"
-    expires_after="2017-12-11">
-  <obsolete>
-    Removed as of 11/2017. No longer relevant after refactoring.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    Whether or not the render frame lookup for a given webRequest event
-    succeeded.
-  </summary>
-</histogram>
-
-<histogram name="Extensions.WebstoreDownload.FileDownload" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Expired after M77.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <summary>
-    The time spent to download the crx file from the webstore to local disk.
-    This is recorded once per successful download.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionService.ZipUnpackerDisabledReason"
-    enum="ExtensionDisableReason" expires_after="2018-10-04">
-  <obsolete>
-    Removed as of 09/2018, with the removal of the &quot;Zip Unpacker&quot;
-    component extension.
-  </obsolete>
-  <owner>yamaguchi@google.com</owner>
-  <summary>
-    Records the reason why the ZIP unpacker extension was disabled when the
-    service attempted to re-enable the extension upon startup. Each entry
-    indicates that the extension was disabled unintentionally and a fix was
-    attempted.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionToolbarModel.BrowserActionsPermanentlyHidden"
-    units="units" expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07.
-  </obsolete>
-  <owner>finnur@chromium.org</owner>
-  <summary>
-    The number of Browser Action icons the user has elected to permanently hide
-    (as opposed to putting them in the overflow bucket). Measured once per
-    startup per (non-incognito) profile.
-  </summary>
-</histogram>
-
-<histogram name="ExtensionUrlRequest.OnReadCompleteError" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed at 07/2019 because refactored DataPipeProducer does not provide the
-    net::Error code any more, and it reaches the planned expiry milestone.
-  </obsolete>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The error code for failures of incremental reads of a file stream for a
-    chrome-extension:// URL. (See also ExtensionUrlRequest.OnReadCompleteResult
-    for the success case).
-  </summary>
-</histogram>
-
-<histogram name="ExtensionUrlRequest.OnReadCompleteResult" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed at 07/2019 because refactored DataPipeProducer does not provide the
-    reported value, and this metric was already broken, reporting always 0.
-  </obsolete>
-  <owner>lazyboy@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The result of an incremental read of a file stream for a chrome-extension://
-    URL, representing a byte count. Logged in success cases (see also
-    ExtensionUrlRequest.OnReadCompleteError).
-  </summary>
-</histogram>
-
-<histogram name="Favicons.CandidatesCount" units="units"
-    expires_after="2017-12-20">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records the number of favicon link tags on a page once the page has finished
-    loading. The count includes the automatically added favicon.ico entry.
-  </summary>
-</histogram>
-
-<histogram name="Favicons.CandidatesWithDefinedSizesCount" units="units"
-    expires_after="2017-12-20">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records the number of favicon link tags with a non empty sizes attribute
-    once the page has finished loading.
-  </summary>
-</histogram>
-
-<histogram name="Favicons.CandidatesWithTouchIconsCount" units="units"
-    expires_after="2017-12-20">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records the number of apple-touch-icon and apple-touch-icon-precomposed link
-    tags once the page has finished loading.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Favicons.DownloadAttempts" units="attempts"
-    expires_after="2017-12-20">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records the number of icons requested until the best-fitting candidate was
-    found or there were no candidates left to check. More than 15 attempts are
-    unlikely and will be stored in overflow bucket 16. Less than 1 attempt means
-    an error happened; these cases are in bucket 0.
-  </summary>
-</histogram>
-
-<histogram name="Favicons.DownloadOutcome" enum="FaviconDownloadStatus"
-    expires_after="2017-12-20">
-  <obsolete>
-    Removed as of 12/2017.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records whether a download succeeded, failed or was skipped because it has
-    failed previously.
-  </summary>
-</histogram>
-
-<histogram name="FCMInvalidations.FCMMessagesDeleted"
-    enum="BooleanDeletedOrNot" expires_after="M82">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Recorded whenever the GCM client announces that some FCM messages were
-    deleted. Note that this does not record the number of deleted messages.
-  </summary>
-</histogram>
-
-<histogram name="FCMInvalidations.TokenStateOnRegistrationRequest"
-    enum="TokenStateOnRegistrationRequest" expires_after="2020-06-14">
-  <obsolete>
-    Replaced in 2019-12 by FCMInvalidations.TokenStateOnRegistrationRequest2.
-    This first version did not record the &quot;Token was cleared&quot; bucket.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Records the outcome of instance ID token requests (i.e. whether the token
-    changed). Such requests are made when invalidations are first enabled (e.g.
-    on sign-in), and then periodically every 24 hours.
-  </summary>
-</histogram>
-
-<histogram name="Feed.Offline.GetStatusCount" units="count"
-    expires_after="2019-08-30">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Offline.GetStatusCount.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The number of urls that have offline status requested per call.
-  </summary>
-</histogram>
-
-<histogram name="Feed.Offline.GetStatusDuration" units="ms"
-    expires_after="2019-08-30">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Offline.GetStatusDuration.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The number of milliseconds to round trip offline status for a set of URLs
-    from Offline Pages component.
-  </summary>
-</histogram>
-
-<histogram name="Feed.Scheduler.RefreshTrigger" enum="RefreshTrigger"
-    expires_after="2019-07-11">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Scheduler.RefreshTrigger.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The scheduler watches for various triggers, which cause it to decide if a
-    refresh is currently warranted or not. This histogram is emitted when a
-    trigger causes a refresh.
-  </summary>
-</histogram>
-
-<histogram name="Feed.Scheduler.RequestBehavior" enum="RequestBehavior"
-    expires_after="2019-07-11">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Scheduler.RequestBehavior.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    When NTP is opened, the scheduler host tells the Feed library how to act, if
-    the existing content should be shown, immediately or with timeout, and if a
-    refresh request should be started.
-  </summary>
-</histogram>
-
-<histogram name="Feedback.HappinessTrackingSurvey.DesktopResponse"
-    enum="HappinessTrackingSurveyDesktopResponse" expires_after="M80">
-  <obsolete>
-    Depcreated as of 08/2019. Replaced by
-    Feedback.HappinessTrackingSurvey.BubbleUsage.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>cyflee@chromium.org</owner>
-  <summary>
-    Reports on the responses to showing Happiness Tracking Surveys (HaTS) to a
-    subset of users. Records each time HaTS is shown.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.CloudImport.UserAction"
-    enum="CloudImportUserAction" expires_after="2018-12-11">
-  <obsolete>
-    Was removed from the code at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS File Browser - Specific actions taken by user such initiating
-    cloud import, canceling import, selecting a directory, or opting-in to
-    Drive&gt;Photos sync.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.CrostiniShareDialog"
-    enum="FileManagerCrostiniShareDialogType" expires_after="2020-10-01">
-  <obsolete>
-    Removed 2020-09.
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>Dialog shown when using crostini app to open a file.</summary>
-</histogram>
-
-<histogram base="true" name="FileBrowser.CrostiniSharedPaths.Depth"
-    units="depth" expires_after="2020-10-18">
-  <obsolete>
-    Removed 2020-09.
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <owner>tbuckley@chromium.org</owner>
-  <summary>
-    The depth from volume root of the path being shared. This is equivalent to
-    how many '/' are in the path. E.g. 'Downloads' or 'My Drive' has depth 0.
-    'Downloads/foo/bar' has depth 2.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.HardUnpluggedAroundSuspend.TimeSinceResume"
-    units="ms" expires_after="M79">
-  <obsolete>
-    The bug which the UMA was investigating got fixed.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS File Browser: time from the SuspendDone event to the DiskRemoved
-    event. The UMA is added temporarily for crbug.com/433734.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.HardUnpluggedAroundSuspend.TimeUntilSuspend"
-    units="ms" expires_after="M79">
-  <obsolete>
-    The bug which the UMA was investigating got fixed.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS File Browser: time from the DiskRemoved event to the Suspend
-    event. The UMA is added temporarily for crbug.com/433734.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.MountCrostiniContainer" units="ms"
-    expires_after="2019-05-30">
-  <obsolete>
-    Removed 2020-09.
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS File Browser: time to start and mount the crostini container in
-    order to show Linux Files.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.OpeningFileType" enum="FileType"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 4/2013, and replaced by FileBrowser.ViewingFileType.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>File types that were tried to be opened through browser.</summary>
-</histogram>
-
-<histogram name="FileBrowser.PhotoImport.Action" enum="ExternalDeviceAction"
-    expires_after="2018-11-14">
-  <obsolete>
-    Code seems to have been removed at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS Photo Import flow: action chosen in the Action Choice dialog for
-    the external device.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.PhotoImport.ImportCount" units="units"
-    expires_after="2018-11-14">
-  <obsolete>
-    Code seems to have been removed at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS Photo Import flow: the number of photos imported. Measured on
-    every successfull import operation.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.PhotoImport.ImportPercentage" units="%"
-    expires_after="2018-11-14">
-  <obsolete>
-    Code seems to have been removed at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS Photo Import flow: the percent of photos imported among all the
-    photos on the device. Measured on every successfull import operation.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.PhotoImport.Load" units="ms"
-    expires_after="2018-11-14">
-  <obsolete>
-    Code seems to have been removed at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS Photo Import flow: time to load the action dialog. Measured
-    between the moment window appears and the moment user see all available
-    actions for the device.
-  </summary>
-</histogram>
-
-<histogram name="FileBrowser.PhotoImport.Scan" units="ms"
-    expires_after="2018-11-14">
-  <obsolete>
-    Code seems to have been removed at an unknown time.
-  </obsolete>
-  <owner>slangley@chromium.org</owner>
-  <owner>weifangsun@chromium.org</owner>
-  <summary>
-    Chrome OS Photo Import flow: time to scan the external device.
-  </summary>
-</histogram>
-
-<histogram name="FileSystem.OriginFailedCanCommitURL" enum="BooleanHit"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    Logged when we fail the permission validation of the filesystem URL origin,
-    from ChildProcessSecurityPolicy::HasPermissionsForFileSystemFile. This is
-    not expected to happen in normal operation.
-  </summary>
-</histogram>
-
-<histogram name="FirstRun.NewUserExperience.EmailInterstitialInteraction"
-    enum="NuxEmailInterstitialInteractions" expires_after="M74">
-  <obsolete>
-    Removed from code March 2019.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <owner>scottchen@chromium.org</owner>
-  <summary>
-    Records when a user interacted with the email interstitial of the onboarding
-    process. We record that the page was seen and what action the user took.
-  </summary>
-</histogram>
-
-<histogram name="FirstRun.NewUserExperience.EmailProvidersInteraction"
-    enum="NuxEmailProvidersInteractions" expires_after="M74">
-  <obsolete>
-    Removed from code April 2019.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <owner>scottchen@chromium.org</owner>
-  <summary>
-    Records when a user interacted with the Email Providers new user experience.
-    We record the number of times the page is seen, how they interacted with the
-    page (i.e. interacting with presented options and button clicks), and
-    through what method they leave the page (i.e. confirm, cancel, neither). The
-    new user experience should only be shown once to new profiles. Hence, the
-    leaving method should be recorded at most once.
-  </summary>
-</histogram>
-
-<histogram name="FirstRun.NewUserExperience.EmailProvidersSelection"
-    enum="NuxEmailProvidersSelections" expires_after="M74">
-  <obsolete>
-    Removed from code April 2019.
-  </obsolete>
-  <owner>hcarmona@chromium.org</owner>
-  <owner>scottchen@chromium.org</owner>
-  <summary>
-    Records what email provider was selected as part of the Email Providers New
-    User Experience. Histogram is only recorded when a user confirms adding an
-    email provider.
-  </summary>
-</histogram>
-
-<histogram base="true" name="FirstUserAction.BackgroundTime.MainIntent"
-    units="minutes" expires_after="M81">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    The amount of time (in minutes) that the app was in the background before
-    the user started it (via an ACTION_MAIN intent) and performed a user action
-    that describes the intent of resuming the app. Only recorded if the action
-    took place within the first 10 seconds of starting Chrome. The actions are
-    further described in the FirstUserActionTypes suffix.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Gaia.AuthFetcher.ListAccounts.NetErrorCodes.Retry"
-    enum="NetErrorCodes" expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Enough data has been collected for investigation of
-    https://crbug.com/876306
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-<!-- Name completed by histogram_suffixes name="GaiaListAccountsRetry" -->
-
-  <summary>
-    Reports the network error code for requests to the ListAccounts Gaia
-    endpoint. There are suffixes for individual tries (0 is the initial request,
-    and 1-8 are retries).
-  </summary>
-</histogram>
-
-<histogram name="Gaia.AuthFetcher.ListAccounts.ProcessUptime.Error" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Enough data has been collected for investigation of
-    https://crbug.com/876306
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Reported when a request to the ListAccounts Gaia endpoint fails to complete
-    for network reasons (i.e. when the error is not OK). This histogram can be
-    used in conjunction with
-    &quot;Gaia.AuthFetcher.ListAccounts.ProcessUptime.Success&quot; in order to
-    compute the failure rate of ListAccounts depending on the process uptime
-    (measured as a base::TimeDelta between the start of the process and the
-    start of the request).
-  </summary>
-</histogram>
-
-<histogram name="Gaia.AuthFetcher.ListAccounts.ProcessUptime.Success"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Enough data has been collected for investigation of
-    https://crbug.com/876306
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Reported when a request to the ListAccounts Gaia endpoint completes without
-    network error (i.e. when the network error is OK). This histogram can be
-    used in conjunction with
-    &quot;Gaia.AuthFetcher.ListAccounts.ProcessUptime.Error&quot; in order to
-    compute the failure rate of ListAccounts depending on the process uptime
-    (measured as a base::TimeDelta between the start of the process and the
-    start of the request).
-  </summary>
-</histogram>
-
-<histogram name="Gaia.AuthFetcher.ListAccounts.SystemUptime.Error" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Enough data has been collected for investigation of
-    https://crbug.com/876306
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Reported when a request to the ListAccounts Gaia endpoint fails to complete
-    for network reasons (i.e. when the network error is not OK). This histogram
-    can be used in conjunction with
-    &quot;Gaia.AuthFetcher.ListAccounts.SystemUptime.Success&quot; in order to
-    compute the failure rate of ListAccounts depending on the system uptime
-    (measured as a base::TimeDelta between the start of the system and the start
-    of the request).
-  </summary>
-</histogram>
-
-<histogram name="Gaia.AuthFetcher.ListAccounts.SystemUptime.Success" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Enough data has been collected for investigation of
-    https://crbug.com/876306
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Reported when a request to the ListAccounts Gaia endpoint completes without
-    network error (i.e. when the network error is OK). This histogram can be
-    used in conjunction with
-    &quot;Gaia.AuthFetcher.ListAccounts.SystemUptime.Error&quot; in order to
-    compute the failure rate of ListAccounts depending on the system uptime
-    (measured as a base::TimeDelta between the start of the system and the start
-    of the request).
-  </summary>
-</histogram>
-
-<histogram name="Gaia.SuccessCountBeforeBadRequestForOAuth2AccessToken"
-    units="requests" expires_after="M86">
-  <obsolete>
-    No longer recorded as of M86.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <owner>chrome-signin-team@google.com</owner>
-  <summary>
-    Number of successful requests preceding a bad request for an OAuth2 refresh
-    token.
-  </summary>
-</histogram>
-
-<histogram name="Gamepad.KnownGamepadConnected" enum="GamepadId"
-    expires_after="2019-01-22">
-  <obsolete>
-    Removed as of 01/2018. Use Gamepad.KnownGamepadConnectedWithId instead.
-  </obsolete>
-  <owner>mattreynolds@chromium.org</owner>
-  <summary>
-    Records an enumeration value that can be used to identify the connected
-    device from a list of known gamepads. Reported when a device with a vendor
-    and product ID matching a known gaming input device is detected during
-    Gamepad API enumeration.
-  </summary>
-</histogram>
-
-<histogram name="GCM.AndroidGcmReceiverError" enum="GcmReceiverStatus"
-    expires_after="2016-01-25">
-  <obsolete>
-    Removed as of 01/2016. The error has been fixed by GCM. (crbug/580367)
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>Result of a message received by the GcmReceiver on Android.</summary>
-</histogram>
-
-<histogram name="GCM.APICallUnregister" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of times when gcm.unregister API is called.</summary>
-</histogram>
-
-<histogram name="GCM.CheckinCompleteTime" units="ms" expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time taken to complete a GCM checkin request successfully. If the
-    checkin is retried multiple times, the length of time is counted for the
-    last successful retry.
-  </summary>
-</histogram>
-
-<histogram name="GCM.CheckinRetryCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of retries before a GCM checkin succeeds.</summary>
-</histogram>
-
-<histogram name="GCM.ConnectedViaProxy" enum="Boolean"
-    expires_after="2018-03-20">
-  <obsolete>
-    Removed as of 03/2018 (M67).
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Whether the GCM connection was made via a proxy or not.</summary>
-</histogram>
-
-<histogram name="GCM.DataMessageBurstReceivedInterval" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in September 2020 as the data was no longer being used.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Interval between two successive received data message bursts.
-  </summary>
-</histogram>
-
-<histogram name="GCM.DataMessageReceivedHasRegisteredApp"
-    enum="BooleanRegistered" expires_after="2017-07-07">
-  <obsolete>
-    No longer used starting with Chrome 61 as the check was removed.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Records whether a matching registration was found for each received
-    DATA_MESSAGE message from Google Cloud Messaging. Recorded while processing
-    the received message. Prior to M56 this also counted received
-    DELETED_MESSAGES messages.
-  </summary>
-</histogram>
-
-<histogram name="GCM.FirstReceivedDataMessageLatencyAfterConnection" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The time between the successful completion of the connection and the arrival
-    of the first data message.
-  </summary>
-</histogram>
-
-<histogram name="GCM.GetInstanceIDData.ClientStarted" enum="GCMClientResult"
-    expires_after="2020-04-02">
-  <obsolete>
-    Removed in April 2020.
-  </obsolete>
-  <owner>tschumann@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Reports the client-started state when the GCM driver requested a read of the
-    instance id although the client was not ready. If != Success, the client is
-    likely leaking a registration.
-  </summary>
-</histogram>
-
-<histogram base="true" name="GCM.IgnoredWriteResult" enum="BooleanSuccess"
-    expires_after="M85">
-  <obsolete>
-    Removed in 2020-06.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="IgnoredWriteResultOperation" -->
-
-  <owner>tschumann@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Result of the outcome of persisting a change in the GCMStore. This histogram
-    is to meausure the frequency of such events and assess their severity. For
-    example, failing to write when calling AddInstanceIDData() likely results in
-    leaked FCM registrations.
-  </summary>
-</histogram>
-
-<histogram name="GCM.LoadSucceeded" enum="BooleanSuccess"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 2/2015.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Success indicates successfully loading an initialized persistent GCM store
-    at startup time. Failure indicates a failure loading the store.
-  </summary>
-</histogram>
-
-<histogram name="GCM.NumUsers" units="units" expires_after="2014-03-21">
-  <obsolete>
-    Removed as of 3/2014.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of GCM users associated with this client at startup time.
-  </summary>
-</histogram>
-
-<histogram name="GCM.OutgoingMessageTTL" enum="GCMOutgoingMessageTTLCategory"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Category of TTL specified in the outgoing message: 0, less than or equal to
-    1 minute, less than or equal to 1 hour and etc.
-  </summary>
-</histogram>
-
-<histogram name="GCM.ReceivedDataMessageBurstSize" units="messages"
-    expires_after="M85">
-  <obsolete>
-    Removed in September 2020 as the data was no longer being used.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>Number of messages in a received GCM data message burst.</summary>
-</histogram>
-
-<histogram name="GCM.ReceivedDataMessageIntervalWithinBurst" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Interval between messages within a received GCM data message burst.
-  </summary>
-</histogram>
-
-<histogram name="GCM.RegistrationCompleteTime" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time taken to complete a GCM registration request successfully. If
-    the registration is retried multiple times, the length of time is counted
-    for the last successful retry.
-  </summary>
-</histogram>
-
-<histogram name="GCM.RegistrationRetryCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of retries before a GCM registration succeeds.</summary>
-</histogram>
-
-<histogram name="GCM.ResetStore" enum="GCMResetStoreError"
-    expires_after="2016-11-04">
-  <obsolete>
-    Removed in M56 in favor of GCM.ResetStoreError
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Reports the problem encountered when resetting the GCM store.
-  </summary>
-</histogram>
-
-<histogram name="GCM.SendWebPushMessageForbiddenBody"
-    enum="ForbiddenResponseBody" expires_after="2020-08-30">
-  <obsolete>
-    Removed Sep 2020. No longer used.
-  </obsolete>
-  <owner>alexchau@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Categorized response body when 403: Forbidden is received from sending web
-    push messages. Recorded when received response after message has been sent.
-    All platforms.
-  </summary>
-</histogram>
-
-<histogram name="GCM.UnregistrationCompleteTime" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time taken to complete a GCM unregistration request successfully.
-    If the unregistration is retried multiple times, the length of time is
-    counted for the last successful retry.
-  </summary>
-</histogram>
-
-<histogram name="GCM.UnregistrationRequest" units="requests"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Number of unregistration requests sent to Google Cloud Messaging. Recorded
-    immediately after the request has started.
-  </summary>
-</histogram>
-
-<histogram name="GCM.UnregistrationRetryCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of retries before a GCM unregistration succeeds.</summary>
-</histogram>
-
-<histogram name="GCMInvalidations.IncomingMessageStatus"
-    enum="GCMInvalidationsIncomingMessageStatus" expires_after="M76">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>
-    Status of parsing incoming invalidations message from GCM channel.
-  </summary>
-</histogram>
-
-<histogram name="GCMInvalidations.OutgoingMessageStatus"
-    enum="GCMInvalidationsOutgoingMessageStatus" expires_after="M76">
-  <obsolete>
-    Removed 2020-02.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>
-    Status of sending outgoing invalidations message through GCM.
-  </summary>
-</histogram>
-
-<histogram name="GData.EntireFeedLoadTime" units="microseconds"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.EntireFeedLoadTime
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time spent to load the entire file system information from the server
-  </summary>
-</histogram>
-
-<histogram name="GData.EntryKind" enum="GDataEntryKind"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.EntryKind
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Provides breakdown of specific formats for hosted documents. Recorded when
-    feed is loaded from the server.
-  </summary>
-</histogram>
-
-<histogram name="GData.InitialFeedLoadTime" units="microseconds"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.InitialFeedLoadTime
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time spent to load the initial part of the file system information from the
-    server
-  </summary>
-</histogram>
-
-<histogram name="GData.NumberOfHostedDocuments" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.NumberOfHostedDocuments
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of hosted documents (spreadsheets etc.) on Drive. Logged when Drive
-    is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="GData.NumberOfRegularFiles" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.NumberOfRegularFiles
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of regualr files on Drive. Logged when Drive is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="GData.NumberOfTotalFiles" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012, and replaced by Drive.NumberOfTotalFiles
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of total files (regualr files + hosted documents) on Drive. Logged
-    when Drive is first accessed.
-  </summary>
-</histogram>
-
-<histogram name="Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy"
-    enum="BooleanEnabled" expires_after="2020-02-01">
-  <obsolete>
-    Removed 01/2020 because the metric is not needed anymore. See
-    https://crbug.com/1036861 for discussion on this metric.
-  </obsolete>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>device-dev@chromium.org</owner>
-  <summary>
-    Whether high accuracy geolocation information was requested.
-  </summary>
-</histogram>
-
-<histogram name="Geolocation.InfoBarDelegate.Event"
-    enum="GeolocationInfoBarDelegateEvent" expires_after="2014-09-29">
-  <obsolete>
-    Removed 9/2014, and replaced by
-    ContentSettings.PermissionActions_Geolocation.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>Events in GeolocationInfoBarDelegate.</summary>
-</histogram>
-
-<histogram name="Geolocation.InfoBarDelegateAndroid.Event"
-    enum="GeolocationInfoBarDelegateAndroidEvent" expires_after="2014-09-29">
-  <obsolete>
-    Removed 9/2014, and replaced by
-    ContentSettings.PermissionActions_Geolocation.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>Events in GeolocationInfoBarDelegateAndroid.</summary>
-</histogram>
-
-<histogram name="GeolocationDisclosure.PostDisclosureContentSetting"
-    enum="ContentSetting" expires_after="2017-12-04">
-  <obsolete>
-    Removed 2017/11. Use PostDisclosureDSESetting instead.
-  </obsolete>
-  <owner>benwells@chromium.org</owner>
-  <summary>
-    Records the geolocation content setting for the default search engine's
-    origin after the search geolocation disclosure has been shown and won't be
-    shown again. This metric is only recorded once per client.
-  </summary>
-</histogram>
-
-<histogram name="GeolocationDisclosure.PostDisclosurePermission"
-    enum="PermissionStatus" expires_after="2017-01-13">
-  <obsolete>
-    Removed 2017/01. Replaced by PostDisclosureContentSetting.
-  </obsolete>
-  <owner>benwells@chromium.org</owner>
-  <summary>
-    Records the geolocation permission for the default search engine's origin
-    after the search geolocation disclosure has been shown and won't be shown
-    again. This metric is only recorded once per client.
-  </summary>
-</histogram>
-
-<histogram name="GeolocationDisclosure.PreDisclosureContentSetting"
-    enum="ContentSetting" expires_after="2017-12-04">
-  <obsolete>
-    Removed 2017/11. Use PreDisclosureDSESetting instead.
-  </obsolete>
-  <owner>benwells@chromium.org</owner>
-  <summary>
-    Records the geolocation content setting for the default search engine's
-    origin immediately before the search geolocation disclosure has been shown.
-    This metric is only recorded once per client.
-  </summary>
-</histogram>
-
-<histogram name="GeolocationDisclosure.PreDisclosurePermission"
-    enum="PermissionStatus" expires_after="2017-01-13">
-  <obsolete>
-    Removed 2017/01. Replaced by PreDisclosureContentSetting.
-  </obsolete>
-  <owner>benwells@chromium.org</owner>
-  <summary>
-    Records the geolocation permission for the default search engine's origin
-    immediately before the search geolocation disclosure has been shown. This
-    metric is only recorded once per client.
-  </summary>
-</histogram>
-
-<histogram name="GestureNavigation.Abandoned" enum="GestureNavigationDirection"
-    expires_after="2020-05-23">
-  <obsolete>
-    Removed 2020/02. Replaced by Cancelled.
-  </obsolete>
-  <owner>jinsukkim@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Overscroll gestures that were abandoned before they were completed.
-    Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="GestureNavigation.SwipedOverThreshold"
-    enum="GestureNavigationDirection" expires_after="2020-05-23">
-  <obsolete>
-    Removed 2020/02.
-  </obsolete>
-  <owner>jinsukkim@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Overscroll gesture was made beyond a threshold that, upon release, would
-    trigger navigation. Users can swipe back below the threshold but this event
-    will still be logged. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="GestureNavigation.Triggered" enum="GestureNavigationDirection"
-    expires_after="2020-05-23">
-  <obsolete>
-    Removed 2020/02. Replaced by Activated.
-  </obsolete>
-  <owner>jinsukkim@chromium.org</owner>
-  <owner>clank-app-team@google.com</owner>
-  <summary>
-    Overscroll gestures initiated by the user. Note that not all overscroll
-    gestures triggered are completed (e.g. the overscroll gesture is aborted if
-    user swipes back to the edge before releasing the finger). Implemented for
-    Android.
-  </summary>
-</histogram>
-
-<histogram name="GoogleNow.Card.Button.Clicked0" enum="GoogleNowCardTypeId"
-    expires_after="M85">
-  <obsolete>
-    Removed in r454917 03/2017.
-  </obsolete>
-  <owner>robliao@chromium.org</owner>
-  <owner>skare@chromium.org</owner>
-  <summary>Types of cards which received an index 0 button click.</summary>
-</histogram>
-
-<histogram name="GoogleNow.Card.Button.Clicked1" enum="GoogleNowCardTypeId"
-    expires_after="M85">
-  <obsolete>
-    Removed in r454917 03/2017.
-  </obsolete>
-  <owner>robliao@chromium.org</owner>
-  <owner>skare@chromium.org</owner>
-  <summary>Types of cards which received an index 1 button click.</summary>
-</histogram>
-
-<histogram name="GoogleNow.Card.Clicked" enum="GoogleNowCardTypeId"
-    expires_after="M85">
-  <obsolete>
-    Removed in r454917 03/2017.
-  </obsolete>
-  <owner>robliao@chromium.org</owner>
-  <owner>skare@chromium.org</owner>
-  <summary>Types of cards which received a notification click.</summary>
-</histogram>
-
-<histogram name="GoogleNow.Event" enum="GoogleNowEvent" expires_after="M85">
-  <obsolete>
-    Removed in r454917 03/2017.
-  </obsolete>
-  <owner>robliao@chromium.org</owner>
-  <owner>skare@chromium.org</owner>
-  <summary>Events in Google Now component extension.</summary>
-</histogram>
-
-<histogram name="GoogleNow.MessageCenter.Displayed.NotificationsVisible"
-    units="count" expires_after="M85">
-  <obsolete>
-    Removed in r455117 03/2017.
-  </obsolete>
-  <owner>robliao@chromium.org</owner>
-  <owner>skare@chromium.org</owner>
-  <summary>
-    Count of the number of Google Now notifications visible when the message
-    center/notification center is shown.
-  </summary>
-</histogram>
-
-<histogram name="GooglePlayServices.ConnectionResult"
-    enum="GooglePlayServicesConnectionResult" expires_after="M77">
-  <obsolete>
-    Removed from code June 2019. See https://crbug.com/490710 for context.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    ConnectionResult error codes resulting from attempts to check whether or not
-    Google Play Services is available. Most of these checks are done lazily,
-    when a user accesses a feature that uses Google Play Services. Added for
-    http://crbug.com/490710.
-  </summary>
-</histogram>
-
-<histogram name="GooglePlayServices.ErrorHandlerAction"
-    enum="GooglePlayServicesErrorHandlerAction" expires_after="M77">
-  <obsolete>
-    Removed from code June 2019. See https://crbug.com/490710 for context.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Types of action taken in response to Google Play Services user-recoverable
-    errors. Added for http://crbug.com/490710.
-  </summary>
-</histogram>
-
-<histogram name="GoogleSearch.AccessPoint" enum="SearchAccessPoint"
-    expires_after="2015-09-15">
-  <obsolete>
-    Removed 2015/08.
-  </obsolete>
-  <owner>kmadhusu@chromium.org</owner>
-  <summary>
-    Counts number of Google searches from various access points in the browser.
-    WARNING: Do not use this histogram as it currently fails to classify a large
-    percentage of Omnibox searches correctly - http://crbug.com/421631.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.EffectivePolicy" enum="UpdatePolicy"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 09/2018; see https://crbug.com/871490.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The effective update policy for Chrome on Windows. Recorded once per startup
-    (following a 45 seconds delay).
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.InfoBar.ActionTaken"
-    enum="GoogleUpdateInfoBarActions" expires_after="2015-12-30">
-  <obsolete>
-    Removed 12/2015 in Issue 566085.
-  </obsolete>
-  <owner>yfriedman@chromium.org</owner>
-  <owner>dfalcantara@chromium.org</owner>
-  <summary>
-    (Android-only) Records what action the user took (if any) on the InfoBar
-    indicating that a new version of Chrome is available.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.InfoBar.InternalStorageSizeAvailable" units="MB"
-    expires_after="M85">
-  <obsolete>
-    Removed 6/2020.
-  </obsolete>
-  <owner>yfriedman@chromium.org</owner>
-  <owner>dfalcantara@chromium.org</owner>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    (Android-only) The amount of internal memory storage available on the user's
-    device when the InfoBar or update menu item is shown. Deprecating soon in
-    M64.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.InfoBar.TimeShown" units="ms"
-    expires_after="2015-12-30">
-  <obsolete>
-    Removed 12/2015 in Issue 566085.
-  </obsolete>
-  <owner>yfriedman@chromium.org</owner>
-  <owner>dfalcantara@chromium.org</owner>
-  <summary>
-    (Android-only) The amount of time which the InfoBar indicating a new version
-    is available is visible.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Notification.LaunchEvent"
-    enum="GoogleUpdateNotificationLaunchEvent" expires_after="2020-06-26">
-  <obsolete>
-    Removed 08/2020
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    (Android-only) Records events when try to launch the update work flow via an
-    update notification.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.UpdatePolicyIsOverridden" enum="Boolean"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 09/2018; see https://crbug.com/871490.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    True if the effective update policy for Chrome on Windows is the result of
-    an app-specific override; false if it is the default for all apps. Recorded
-    once per startup (following a 45 seconds delay).
-  </summary>
-</histogram>
-
-<histogram name="GPU.ANGLE.D3D11CreateDeviceMS" units="ms" expires_after="M77">
-  <obsolete>
-    Removed sometime around M77.
-  </obsolete>
-  <owner>jmadill@chromium.org</owner>
-  <summary>
-    The time that elapses for the initial call to D3D11CreateDevice on D3D11
-    ANGLE. A pure system call, with no ANGLE or Chromium code, called once every
-    GPU process startup.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ANGLE.Renderer11InitializeDeviceMS" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed sometime around M77.
-  </obsolete>
-  <owner>jmadill@chromium.org</owner>
-  <summary>
-    Time ANGLE spends initializing various shaders and internal classes. This is
-    time that isn't purely loading system DLLs and calling OS methods. It might
-    be work we can optimize or defer until later.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ANGLE.Renderer11InitializeDLLsMS" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed sometime around M77.
-  </obsolete>
-  <owner>jmadill@chromium.org</owner>
-  <summary>
-    Time ANGLE spends loading system DLLs, such as the D3D compiler DLL, and the
-    D3D11 and DXGI DLLs. Probably unavoidable startup costs, though very useful
-    to keep track of.
-  </summary>
-</histogram>
-
-<histogram name="GPU.AtExitMBytesAllocated" units="MB"
-    expires_after="2018-11-02">
-  <obsolete>
-    Removed sometime around M55.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The amount of GPU memory that was currently allocated as of just before the
-    GPU process' exit.
-  </summary>
-</histogram>
-
-<histogram name="GPU.AtExitMBytesAllocatedMax" units="MB"
-    expires_after="2018-11-02">
-  <obsolete>
-    Removed sometime around M55.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The maximum amount of GPU memory that had ever been allocated during the GPU
-    process' lifetime, as of just before the GPU process' exit.
-  </summary>
-</histogram>
-
-<histogram name="GPU.AtExitMBytesLimit" units="MB" expires_after="2018-11-02">
-  <obsolete>
-    Removed sometime around M55.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The GPU memory manager's limit on the amount of GPU memory that can be
-    allocated as of just before the GPU process' exit.
-  </summary>
-</histogram>
-
-<histogram name="GPU.AtExitWindowCount" units="units"
-    expires_after="2018-11-02">
-  <obsolete>
-    Removed sometime around M55.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The number of windows that the GPU memory manager believed to exist as of
-    just before the GPU process' exit.
-  </summary>
-</histogram>
-
-<histogram name="GPU.BlacklistFeatureTestResultsWindows"
-    enum="GPUBlocklistFeatureTestResultsWindows" expires_after="2018-02-28">
-  <obsolete>
-    Replaced by GPU.BlacklistFeatureTestResultsWindows2 in M67.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts number of browser invocations for which a GPU feature is
-    allowed/blacklisted/disabled in various Windows sub-versions.
-  </summary>
-</histogram>
-
-<histogram name="GPU.BlockStatusForClient3DAPIs"
-    enum="BlockStatusForClient3DAPIs" expires_after="M80">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>kbr@chromium.org</owner>
-  <summary>
-    Indicates whether WebGL / Pepper3D were blocked, and if so, for all domains,
-    or only a single one. This statistic is gathered every time an attempt is
-    made to create a 3D context.
-  </summary>
-</histogram>
-
-<histogram name="GPU.CheckFramebufferValidDuration" units="ms"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The amount of time spent in GLES2DecoderImpl::CheckFramebufferValid.
-  </summary>
-</histogram>
-
-<histogram name="GPU.CreateBrowserCompositor" units="microseconds"
-    expires_after="2018-07-13">
-  <obsolete>
-    Removed 07/2018: not useful anymore.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The time that the browser process takes to create the compositor from its
-    point of view. One of these is created for each top-level window (browser
-    frame, menus, etc.).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="GPU.D3D11_FeatureLevel" enum="D3D11FeatureLevel"
-    expires_after="2020-02-26">
-  <obsolete>
-    As of 02/26/2020 this has been superceded by GPU.D3D11FeatureLevel.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>The highest D3D11 feature level available.</summary>
-</histogram>
-
-<histogram name="GPU.DestroyProgramManagerPrograms.Elapsed" units="ms"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The amount of time spent destroying programs during ProgramManager::Destroy.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DestroyProgramManagerPrograms.Programs" units="programs"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The number of progams destroyed during ProgramManager::Destroy.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DestroyProgramManagerPrograms.ProgramsPerMs"
-    units="programs per ms" expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The number of programs destroyed per millisecond during
-    ProgramManager::Destroy. Only logged if both the number of programs and the
-    elapsed time are greater than zero.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.DCLayerResult" enum="DCLayerResult"
-    expires_after="2018-11-28">
-  <obsolete>
-    Removed 11/2018. Replaced by GPU.DirectComposition.DCLayerResult2.Clear.
-  </obsolete>
-  <owner>jbauman@chromium.org</owner>
-  <summary>
-    Recorded for each quad (on overlay processing) the reason it was or wasn't
-    put in an overlay.
-  </summary>
-</histogram>
-
-<histogram base="true" name="GPU.DirectComposition.DCLayerResult2"
-    enum="DCLayerResult" expires_after="2020-12-31">
-  <obsolete>
-    Removed 08/2019. Replaced by GPU.DirectComposition.DCLayerResult.Video
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="GPU.ProtectedVideoType" -->
-
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Recorded for each quad (on overlay processing) with protected video type the
-    reason it was or wasn't put in an overlay.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.DecodeSwapChainPresentResult"
-    enum="Hresult" expires_after="M75">
-  <obsolete>
-    Removed 3/2019. This either succeeds or fails with DXGI_STATUS_OCCLUDED
-    infrequently which we also handle.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Result of calling Present on decode swap chain. Recorded on each present.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.DecodeSwapChainSurfaceCreationResult"
-    enum="Hresult" expires_after="M75">
-  <obsolete>
-    Removed 3/2019. Creating the surface never fails.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Result of calling CreateSurfaceFromHandle. Recorded when decode swap chain
-    is created.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.DecodeSwapChainUsed"
-    enum="BooleanDecodeSwapChainUsed" expires_after="M76">
-  <obsolete>
-    Removed 4/2019. Replaced by GPU.DirectComposition.VideoPresentationMode.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Whether zero copy decode swap chain was used to present video frame instead
-    of video processor blit with flip swap chain. Recorded on each present.
-  </summary>
-</histogram>
-
-<histogram
-    name="GPU.DirectComposition.DisableLargerThanScreenOverlaysWorkaround"
-    enum="BooleanActive" expires_after="2019-07-09">
-  <obsolete>
-    No longer needed. Data has been collected.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Recorded for each overlay frame during the video playback whether the
-    workaround that reduces the swap chain size to fit the screen is active.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.FullScreenOverlay"
-    enum="BooleanFullScreen" expires_after="2019-04-08">
-  <obsolete>
-    Removed 4/2019. Replaced by GPU.DirectComposition.OverlayFullScreenTypes.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Recorded for each overlay/underlay quad during the video playback whether
-    the video is played in full screen mode
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.OverlayFormatUsed" enum="OverlayFormat"
-    expires_after="2018-10-03">
-  <obsolete>
-    Removed 10/2018. Replaced by GPU.DirectComposition.OverlayFormatUsed2.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <summary>Which overlay format was chosen for YUV overlays.</summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.OverlayFormatUsed2" enum="OverlayFormat"
-    expires_after="2019-05-31">
-  <obsolete>
-    Removed 5/2019. Replaced by GPU.DirectComposition.OverlayFormatUsed3.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Which overlay format was chosen for YUV overlays. Recorded once per GPU
-    process launch only if hardware overlays are supported.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.OverlayFullScreenTypes"
-    enum="OverlayFullScreenTypes" expires_after="2020-03-08">
-  <obsolete>
-    Removed 03/2020. Data has been collected.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    The overlay size types in comparison to the full screen size. Recorded for
-    each overlay quad during the video playback.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.OverlayNV12Rec709Supported"
-    enum="BooleanColorSpaceSupported" expires_after="2020-09-30">
-  <obsolete>
-    Removed 04/2019. Rec 709 is almost always supported.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Whether or not Rec709 color space is supported on NV12 supported machines.
-    Recorded during the GPU process initialization.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.OverlaySupportFlags"
-    enum="OverlaySupportFlag" expires_after="2018-07-10">
-  <obsolete>
-    Replaced by format specific histograms under OverlaySupportFlags2.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <summary>
-    These are the flags explaining how well overlays are supported on the
-    current display. The is recorded for every connected display when creating a
-    DirectComposition view context.
-  </summary>
-</histogram>
-
-<histogram base="true" name="GPU.DirectComposition.OverlaySupportFlags2"
-    enum="OverlaySupportFlag" expires_after="2019-04-06">
-  <obsolete>
-    Removed 04/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="GPU.DirectComposition.OverlayFormat" -->
-
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Flags that indicate if overlays are supported, and if additional features
-    such as scaling are supported for some common pixel formats.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapBuffersFailed" enum="BooleanHit"
-    expires_after="2018-08-25">
-  <obsolete>
-    Removed 08/2018. Replaced by SwapBuffersResult which is emitted on both
-    success and failure.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <summary>Emitted on direct composition surface swap buffers failure.</summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapBuffersLastError" enum="Hresult"
-    expires_after="2018-06-06">
-  <obsolete>
-    Removed 05/2018. GetLastError returns error for last successful or failed
-    win32 call so this doesn't work as expected.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <summary>Last error when presentation using DirectComposition fails.</summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapBuffersResult" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed 04/2019. SwapBuffers rarely fails.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>Whether or not swap buffers succeeded.</summary>
-</histogram>
-
-<histogram base="true" name="GPU.DirectComposition.SwapChainCreationResult"
-    enum="BooleanSuccess" expires_after="M75">
-  <obsolete>
-    Removed 04/2019 because of using histogram macros instead of functions.
-    Replaced by SwapChainCreationResult2.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="GPU.DirectComposition.OverlayFormat" -->
-
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Whether creating swap chain for overlay format succeeded. Recorded once per
-    swap chain creation.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapchainFormat" enum="SwapchainFormat"
-    expires_after="2018-10-03">
-  <obsolete>
-    Removed 10/2018. Replaced by GPU.DirectComposition.SwapChainFormatUsed.
-  </obsolete>
-  <owner>jbauman@chromium.org</owner>
-  <summary>What type of swapchain was actually created for an overlay.</summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapChainFormat2" enum="OverlayFormat"
-    expires_after="2019-05-31">
-  <obsolete>
-    Removed 5/2019. Replaced by GPU.DirectComposition.SwapChainFormatUsed3.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    What format was used for each overlay swap chain on each swap buffers.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DirectComposition.SwapChainResizeResult"
-    enum="BooleanSuccess" expires_after="M75">
-  <obsolete>
-    Removed 04/2019. ResizeBuffers rarely fails.
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Result of ResizeBuffers call. Recorded once per swap chain resize.
-  </summary>
-</histogram>
-
-<histogram name="GPU.DisplayCompositorLifetimeEvents"
-    enum="GPUProcessLifetimeEvent" expires_after="2018-06-05">
-  <obsolete>
-    Removed 05/2018. Moved to GPU.ProcessLifetimeEvents.DisplayCompositor.
-  </obsolete>
-  <owner>mohsen@chromium.org</owner>
-  <summary>
-    Counts of the number of gpu process crashes when it only has display
-    compositor (no hardware acceleration and software compositing).
-  </summary>
-</histogram>
-
-<histogram name="GPU.DisplayLinkInstallationStatus"
-    enum="DisplayLinkInstallationStatus" expires_after="2017-05-25">
-  <obsolete>
-    Removed 2/2017. The values hadn't been updated since it was created, and the
-    code gathering the installation status has been removed in Chrome CL
-    2679773002.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Whether a version of DisplayLink is installed that crashes the GPU process.
-    This information is collected at statup. It applies only to Windows. See
-    http://crbug.com/177611.
-  </summary>
-</histogram>
-
-<histogram base="true" name="GPU.EstablishGpuChannelDuration" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Expired in M75.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The duration from when a request to establish a GPU channel arrives in
-    viz::GpuClient and to when the response for the request is sent.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GpuBlockedBetweenSwapsUs" units="microseconds"
-    expires_after="2020-01-01">
-  <obsolete>
-    Removed November 27, 2019. See GPU.GpuBlockedBetweenSwapsUs2.
-  </obsolete>
-  <owner>vasilyt@chromium.org</owner>
-  <owner>backer@chromium.org</owner>
-  <summary>
-    This is logged once per frame if the output surface provides timing
-    information. It measures the time Gpu Main thread was blocked (difference
-    between wall time and cpu time) during tasks execution for currect frame.
-    Only reported when there is single surface swap in the same vsync interval.
-    Only reported for platforms supporting high resolution clocks.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUChannelHostWaitTime" units="ms"
-    expires_after="2019-10-07">
-  <obsolete>
-    Removed 10/2019. Moved to GPU.GPUChannelHostWaitTime.Max120Seconds.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    The wait time between the IPC message sent from the GPU channel host and the
-    event sync from the GPU process. If the wait time takes longer than 60
-    seconds, 60 seconds will be recoreded.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUChannelHostWaitTime.MicroSeconds" units="microseconds"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    Records how long the browser UI thread spent blocked for a sync IPC sent
-    using GpuChannelHost to see if it's contributing to jank.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GpuGeneration" enum="IntelGpuSeriesType"
-    expires_after="M90">
-  <obsolete>
-    Renamed to GPU.IntelGpuSeriesType 03/2020
-  </obsolete>
-  <owner>sunnyps@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Records user device's GPU generation. Only recorded on Windows platform at
-    GPU process launch time. Currently only meaningful with Intel GPUs.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUInitializationTime" units="ms"
-    expires_after="2020-01-08">
-  <obsolete>
-    Removed 01/2020. Moved to GPU.GPUInitializationTime.V2.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    The time between the GPU process starts and the GPU Info is collected in Viz
-    GPU service. If GPU initilization takes longer than 60 seconds, 60 seconds
-    will be recoreded.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUProcessLaunchCause" enum="GPUProcessLaunchCauses"
-    expires_after="2016-08-03">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts enumerating the initial cause for the GPU Process to be launched.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUProcessLifetimeEvents" enum="GPUProcessLifetimeEvent"
-    expires_after="2018-06-05">
-  <obsolete>
-    Removed 05/2018. Moved to GPU.ProcessLifetimeEvents.HardwareAccelerated.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts of the number of process launches and crashes (when running on h/w).
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUProcessSoftwareRendering" enum="GPUProcessType"
-    expires_after="2018-11-12">
-  <obsolete>
-    This histogram is no longer recorded. Use GPU.GLImplementation ==
-    kGLImplementationSwiftShaderGL to check if the gpu process is launched with
-    software rendering.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    A boolean indicating whether the gpu process that was launched uses software
-    or hardware 3d rendering.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GPUProcessTerminationStatus" enum="TerminationStatus"
-    expires_after="2018-04-23">
-  <obsolete>
-    Removed April 2018. Replaced by GPU.GPUProcessTerminationStatus2.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts for each time the GPU Process Host detects the process dies.
-  </summary>
-</histogram>
-
-<histogram name="GPU.GrContextMemoryKb" units="KB" expires_after="2020-05-31">
-  <obsolete>
-    Removed August 2020. Replaced by Memory.GPU.PeakMemoryAllocationSource.
-  </obsolete>
-  <owner>enne@chromium.org</owner>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    Kilobytes of memory used by Skia in the gpu process. This is recorded after
-    every block of commands in the raster decoder.
-  </summary>
-</histogram>
-
-<histogram name="GPU.InForceCompositingModeFieldTrial" enum="BooleanEnabled"
-    expires_after="2017-05-25">
-  <obsolete>
-    Removed 10/2013.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Records whether a client was selected for the force compositing mode field
-    trial or not.
-  </summary>
-</histogram>
-
-<histogram name="GPU.InitializeOneOffTime" units="microseconds"
-    expires_after="2015-04-10">
-  <obsolete>
-    Removed 4/2015.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The time that the GPU process spends in initializing the GL surface, and
-    collecting graphics information.
-  </summary>
-</histogram>
-
-<histogram name="Gpu.Metal.TestShaderCompileSucceeded" enum="BooleanSuccess"
-    expires_after="2019-12-03">
-  <obsolete>
-    It is not planned to use this approach to determine if Metal is to be used.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Compiling a MTLLibrary will sometimes hang forever. When initializing Metal,
-    a test shader is compiled to see if the MTLCompilerService is responding or
-    not. This records the success or failure of this test compile, once at
-    initialization.
-  </summary>
-</histogram>
-
-<histogram name="Gpu.Metal.TestShaderMethodTime" units="ms"
-    expires_after="2020-05-18">
-  <obsolete>
-    Removed 05/2020. Did not reveal interesting results.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Compiling a MTLLibrary will sometimes hang forever. When initializing the
-    gpu process, a test shader is compiled to see if the MTLCompilerService is
-    is responding or not. This records the time that it took for the compile
-    method to finish (not including the time for the compile itself to finish),
-    up to 1 minute. After 1 minute, a timeout sentinel value of 3 minutes is
-    reported.
-  </summary>
-</histogram>
-
-<histogram name="Gpu.MetalProxy.NewLibraryAttempt" units="units"
-    expires_after="2019-12-03">
-  <obsolete>
-    This did not substantially improve the situation and was removed.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Creating a new MTLLibrary will automatically retry if its callback is not
-    invoked within a short timeframe. This records the attempt number whose
-    callback was executed first. Recorded after every call to -[MTLDeviceProxy
-    newLibraryWithSource:] completes.
-  </summary>
-</histogram>
-
-<histogram name="Gpu.MetalProxy.NewRenderPipelineStateAttempt" units="units"
-    expires_after="2019-12-03">
-  <obsolete>
-    This did not substantially improve the situation and was removed.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Creating a new MTLRenderPipelineState will automatically retry if its
-    callback is not invoked within a short timeframe. This records the attempt
-    number whose callback was executed first. Recorded after every call to
-    -[MTLDeviceProxy newRenderPipelineStateWithDescriptor:] completes.
-  </summary>
-</histogram>
-
-<histogram name="GPU.OopRaster.PaintOpSerializationSize" units="bytes"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    This records the number of bytes required to serialize a paint op for OOP
-    rasterization. The metric is recorded each time an op is serialized with a
-    size &gt; 512k bytes.
-  </summary>
-</histogram>
-
-<histogram name="GPU.Output.MaxLuminance" units="lumens"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 07/2020. No longer used.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the display maximum lumens as reported by Windows. Recorded once for
-    each monitor when the gpu process starts. If monitor enumeration fails, this
-    metric will not be provided.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.CompressDataSuccess" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Whether we succeeded in compressing program data. Expected to always be
-    true.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.CompressDataTime" units="microseconds"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The time to compress a program's binary data during insertion into the
-    program cache.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.CompressionPercentage" units="%"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The percentage of raw size that a program binary takes after compression.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.DecompressDataSuccess" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Whether we succeeded in decompressing program data. Failure indicates disk
-    or memory corruption.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.DecompressDataTime" units="microseconds"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The time to decompress a program's binary data during retrieval from the
-    program cache.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.LoadBinarySuccess" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Records if the call to glProgramBinary was successful. This can legitimately
-    fail if the driver wants chrome to re-link and re-cache the gpu program.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.MemoryReleasedOnPressure" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    Amount of memory released from the program cache on memory pressure.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.MemorySizeAfterKb" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Records the total in-memory cache size, before a program is cached. Can be
-    used with GPU.ProgramCache.MemorySizeBeforeKb to find the maximum cache size
-    distribution.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.MemorySizeBeforeKb" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Records the total in-memory cache size, after a program is cached. Can be
-    used with GPU.ProgramCache.MemorySizeAfterKb to find the maximum cache size
-    distribution.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ProgramCache.ProgramBinarySizeBytes" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. ProgramCache not actively being tuned.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The size of program binaries loaded into the gpu program cache.
-  </summary>
-</histogram>
-
-<histogram name="GPU.SoftwareRendererLifetimeEvents"
-    enum="GPUProcessLifetimeEvent" expires_after="2018-06-05">
-  <obsolete>
-    Never used.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts of the number of gpu process crashes when the software rasterizer is
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="GPU.SupportsVulkan" enum="BooleanSupported"
-    expires_after="2020-06-22">
-  <obsolete>
-    Removed 06/2020. Data has been collected on Windows.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>magchen@chromium.org</owner>
-  <summary>
-    This metric shows whether the GPU supports Vulkan. It is recorded 15 seconds
-    after the browser launch.
-  </summary>
-</histogram>
-
-<histogram name="GPU.SurfaceCountAtExit" units="units"
-    expires_after="2017-05-25">
-  <obsolete>
-    Removed 12/2012. Moved to GPU.AtExitSurfaceCount.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The number of surfaces that the GPU process was rendering to right before
-    exiting. This should be equal to the number of tabs (both visible and
-    hidden) rendering via the compositor.
-  </summary>
-</histogram>
-
-<histogram name="GPU.SwiftShaderLifetimeEvents" enum="GPUProcessLifetimeEvent"
-    expires_after="2018-06-05">
-  <obsolete>
-    Removed 05/2018. Moved to GPU.ProcessLifetimeEvents.SwiftShader.
-  </obsolete>
-  <owner>capn@chromium.org</owner>
-  <summary>
-    Counts of the number of process launches and crashes (when running on s/w).
-  </summary>
-</histogram>
-
-<histogram name="GPU.TextureR16Ext_LuminanceF16" enum="GpuTextureResultR16_L16"
-    expires_after="2020-06-21">
-  <obsolete>
-    Removed 06/2020. Both LUMINANCE_F16 and R16_EXT must be supported for now.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>rijubrata.bhaumik@intel.com</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Whether LUMINANCE_F16 and/or R16_EXT texture support is available. Recorded
-    each time a new context group is initialized and extensions are detected.
-  </summary>
-</histogram>
-
-<histogram name="GPU.ThreeDAPIInfoBarDismissal"
-    enum="GPUThreeDAPIInfoBarDismissal" expires_after="2018-04-12">
-  <obsolete>
-    Removed 04/2018. Infobar has been removed.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <summary>Counts user actions when a 3D API info bar is raised.</summary>
-</histogram>
-
-<histogram name="GPU.VulkanExtSupport.VK_KHR_external_memory_win32"
-    enum="BooleanSupported" expires_after="2020-06-22">
-  <obsolete>
-    Removed 06/2020. Data has been collected on Windows.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>magchen@chromium.org</owner>
-  <summary>
-    Whether the Vulkan extension VK_KHR_external_memory_win32 is supported in
-    the GPU drivers. It is recorded 15 seconds after the browser launch.
-  </summary>
-</histogram>
-
-<histogram name="GPU.VulkanExtSupport.VK_KHR_external_semaphore_win32"
-    enum="BooleanSupported" expires_after="2020-06-22">
-  <obsolete>
-    Removed 06/2020. Data has been collected on Windows.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>magchen@chromium.org</owner>
-  <summary>
-    Whether the Vulkan extension VK_KHR_external_semaphore_win32 is supported in
-    the GPU drivers. It is recorded 15 seconds after the browser launch.
-  </summary>
-</histogram>
-
-<histogram name="GPU.VulkanExtSupport.VK_KHR_win32_keyed_mutex"
-    enum="BooleanSupported" expires_after="2020-06-22">
-  <obsolete>
-    Removed 06/2020. Data has been collected on Windows.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>magchen@chromium.org</owner>
-  <summary>
-    Whether the Vulkan extension VK_KHR_win32_keyed_mutex is supported in the
-    GPU drivers. It is recorded 15 seconds after the browser launch.
-  </summary>
-</histogram>
-
-<histogram name="GPU.VulkanVersion" enum="VulkanVersion"
-    expires_after="2020-06-22">
-  <obsolete>
-    Removed 06/2020. Data has been collected on Windows.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>magchen@chromium.org</owner>
-  <summary>
-    The maximum Vulkan API version supported in the gpu drivers. It is recorded
-    15 seconds after the browser launch.
-  </summary>
-</histogram>
-
-<histogram name="GPU.WatchdogThread.Event.V2" enum="GpuWatchdogThreadEvent"
-    expires_after="2020-06-08">
-  <obsolete>
-    No longer used after GPU watchdog V2 is enabled by default in M82. It's the
-    same as the default histogram GPU.WatchdogThread.Event.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Recorded for each time the GPU watchdog V2 thread starts, crashes and ends.
-  </summary>
-</histogram>
-
-<histogram name="GPU.WatchdogThread.V1.ExtraThreadTime" units="ms"
-    expires_after="2020-06-08">
-  <obsolete>
-    GPU watchdog V1 is disabled in M82. Please see
-    GPU.WatchdogThread.ExtraThreadTime for the result of V2.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    The time the GPU main thread needs to make any progress after the first
-    watchdog timeout.
-  </summary>
-</histogram>
-
-<histogram name="GPU.WatchdogThread.V1.Timeout" enum="GpuWatchdogTimeoutEvent"
-    expires_after="2020-06-08">
-  <obsolete>
-    GPU watchdog V1 is disabled in M82. Please see GPU.WatchdogThread.Timeout
-    for the result of V2.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Recorded timeout events when the GPU watchdog V2 enters OnWatchdogTimeout.
-  </summary>
-</histogram>
-
-<histogram name="GPU.WatchdogThread.V1.WaitTime" units="ms"
-    expires_after="2020-06-08">
-  <obsolete>
-    GPU watchdog V1 is disabled in M82. Please see GPU.WatchdogThread.WaitTime
-    for the result of V2.
-  </obsolete>
-  <owner>magchen@chromium.org</owner>
-  <owner>zmo@chromium.org</owner>
-  <summary>
-    Record the wait time in OnWatchdogTimeout() for the GPU main thread to make
-    any progress.
-  </summary>
-</histogram>
-
-<histogram name="Graphics.Smoothness.Throughput" units="%"
-    expires_after="2020-12-31">
-  <obsolete>
-    As of 2020-02-12, this is deprecated in favor of
-    Graphics.Smoothness.PercentDroppedFrames.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-</histogram>
-
-<histogram name="Graphics.Smoothness.Throughput.AllAnimations" units="%"
-    expires_after="2020-12-31">
-  <obsolete>
-    As of 2020-02-12, this is deprecated in favor of
-    Graphics.Smoothness.PercentDroppedFrames.AllAnimations.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-</histogram>
-
-<histogram name="Graphics.Smoothness.Throughput.AllInteractions" units="%"
-    expires_after="2020-12-31">
-  <obsolete>
-    As of 2020-02-12, this is deprecated in favor of
-    Graphics.Smoothness.PercentDroppedFrames.AllInteractions.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    As of 2020-02-12, this is deprecated in favor of
-    Graphics.Smoothness.PercentDroppedFrames.AllInteractions.
-  </summary>
-</histogram>
-
-<histogram name="Graphics.Smoothness.Throughput.AllSequences" units="%"
-    expires_after="2020-12-31">
-  <obsolete>
-    As of 2020-02-12, this is deprecated in favor of
-    Graphics.Smoothness.PercentDroppedFrames.AllSequence.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-</histogram>
-
-<histogram base="true" name="GwpAsan.AllocatorOom.Malloc" units="allocations"
-    expires_after="2020-05-10">
-  <obsolete>
-    Removed 07/2020; currently unowned, and histogram gathering was causing
-    crashes.
-  </obsolete>
-  <owner>vtsyrklevich@chromium.org</owner>
-  <owner>dynamic-tools@google.com</owner>
-  <summary>
-    Reports how many allocations it took for malloc GWP-ASan to OOM. Reported
-    the first time the allocator fails to consecutively allocate
-    GuardedPageAllocator::kOutOfMemoryCount allocations in a row.
-  </summary>
-</histogram>
-
-<histogram base="true" name="GwpAsan.AllocatorOom.PartitionAlloc"
-    units="allocations" expires_after="2020-05-10">
-  <obsolete>
-    Removed 07/2020; currently unowned, and histogram gathering was causing
-    crashes.
-  </obsolete>
-  <owner>vtsyrklevich@chromium.org</owner>
-  <owner>dynamic-tools@google.com</owner>
-  <summary>
-    Reports how many allocations it took for PartitionAlloc GWP-ASan to OOM.
-    Reported the first time the allocator fails to consecutively allocate
-    GuardedPageAllocator::kOutOfMemoryCount allocations in a row.
-  </summary>
-</histogram>
-
-<histogram name="Hardware.Drive.HasSeekPenalty" enum="BooleanHasSeekPenalty"
-    expires_after="M81">
-  <obsolete>
-    Removed 1/2020 - but the data exists in system_profile under
-    hardware.app_drive and hardware.user_data_app_drive
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <summary>
-    Whether a drive has a seek penalty (i.e. is a spinning disk). Emitted 0-2
-    times shortly after startup when constructing the initial UMA log.
-  </summary>
-</histogram>
-
-<histogram name="Hardware.Drive.HasSeekPenalty_Success" enum="BooleanSuccess"
-    expires_after="M81">
-  <obsolete>
-    Removed 1/2020 - but the data exists in system_profile under
-    hardware.app_drive and hardware.user_data_app_drive
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <summary>
-    Whether it was possible to determine if a drive has a seek penalty. This can
-    fail for various reasons (device drivers don't offer this information, the
-    drive is still mounting, lack of access, etc.). Emitted twice shortly after
-    startup when constructing the initial UMA log.
-
-    Seek penalty detection is disabled on XP/Vista as of 9/24/2015 because it
-    crashes too much. http://crbug.com/514822
-  </summary>
-</histogram>
-
-<histogram name="Hardware.Drive.HasSeekPenalty_Time" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 1/2020 - but the data exists in system_profile under
-    hardware.app_drive and hardware.user_data_app_drive
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <summary>
-    The amount of time it takes to determine whether a drive has a seek penalty.
-    Emitted twice shortly after startup when constructing the initial UMA log.
-  </summary>
-</histogram>
-
-<histogram name="Hardware.Serial.NewMinusOldDeviceListSize" units="units"
-    expires_after="M82">
-  <obsolete>
-    Removed in M83 after all code for the old enumeration method had been
-    removed.
-  </obsolete>
-  <owner>charliea@chromium.org</owner>
-  <summary>
-    On Windows and Mac, we're implementing new methods to enumerate serial
-    devices that provide us more information about the actual devices. This
-    metric measures the difference between the number of devices that the new
-    and old enumeration methods find. Once this metric gives us confidence that
-    the new and old methods are at parity, we can cut out the old method
-    altogether.
-  </summary>
-</histogram>
-
-<histogram name="HeavyPageCapping.BlacklistReason" enum="OptOutBlacklistReason"
-    expires_after="M75">
-  <obsolete>
-    Removed 3/2019.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records that the capping heavy pages InfoBar was allowed or the specific
-    reason that the feature was blacklisted from heavy page capping. Recorded
-    when the triggering threshold is met for users with capping heavy pages
-    enabled. Reasons are ordered in the same order they are checked.
-  </summary>
-</histogram>
-
-<histogram name="HeavyPageCapping.InfoBarInteraction"
-    enum="HeavyPageCappingInfoBarInteraction" expires_after="M75">
-  <obsolete>
-    Removed 3/2019.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the details of user interaction with the heavy page capping InfoBar.
-  </summary>
-</histogram>
-
-<histogram name="HeavyPageCapping.RecordedDataSavings" units="KB"
-    expires_after="M75">
-  <obsolete>
-    Removed 3/2019.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Records the data savings due to heavy page capping. This is recorded when
-    the page is being terminated. This is not recorded when the tab is
-    backgrounded, so android fast shutdown may result in this metric not being
-    recorded. This is only recorded for page loads that were still paused when
-    the page was terminated.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesBrowser" enum="Inconsistencies"
-    expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a browser for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA. Each type of inconsistency is a bit, and all bits found
-    in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency MAY appear time and
-    again as the same corrupt histogram is examined for each potenital UMA
-    upload.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesBrowserUnique" enum="Inconsistencies"
-    expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a browser for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA. Each type of inconsistency is a bit, and all bits found
-    in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency will only appear at
-    most one time for each histogram in a single process (i.e., duplicate
-    corruption in a single histogram is not noted in this chart.)
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesChildProcess" enum="Inconsistencies"
-    expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a child process for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA. Each type of inconsistency is a bit, and all bits found
-    in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency MAY appear time and
-    again as the same corrupt histogram is examined for each potenital UMA
-    upload.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesChildProcessUnique"
-    enum="Inconsistencies" expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a child process for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA. Each type of inconsistency is a bit, and all bits found
-    in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency will only appear at
-    most one time for each histogram in a single process (i.e., duplicate
-    corruption in a single histogram is not noted in this chart.)
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesRenderer" enum="Inconsistencies"
-    expires_after="2014-08-12">
-  <obsolete>
-    Removed 7/2012.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a renderer for transmission to the browser. Inconsistent data is NOT
-    transmitted to the browser. Each type of inconsistency is a bit, and all
-    bits found in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency MAY appear time and
-    again as the same corrupt histogram is examined for each potenital UMA
-    upload.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistenciesRendererUnique"
-    enum="Inconsistencies" expires_after="2014-08-12">
-  <obsolete>
-    Removed 7/2012.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of inconsistency events found when examining a single histogram's
-    data in a renderer for transmission to the browser. Inconsistent data is NOT
-    transmitted to the browser. Each type of inconsistency is a bit, and all
-    bits found in one histogram examination are added together to summarize the
-    inconsistent event. Note that the same inconsistency will only appear at
-    most one time for each histogram in a single renderer process (i.e.,
-    duplicate corruption in a single histogram is not noted in this chart.)
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistentCountHigh" units="units"
-    expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of extra samples counted in the redundant_count in a histogram
-    that were not found by summing the samples in the buckets.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistentCountLow" units="units"
-    expires_after="2017-07-25">
-  <obsolete>
-    Removed 7/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of missing samples in the redundant_count in a histogram that
-    were found by summing the samples in the buckets.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistentSnapshotRenderer" units="units"
-    expires_after="2014-08-12">
-  <obsolete>
-    Removed 7/2012.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The amount of discrepancy found when examining a single histogram's data in
-    a renderer process for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA.
-  </summary>
-</histogram>
-
-<histogram name="History.ClearBrowsingData.Duration.PartialDeletion" units="ms"
-    expires_after="M83">
-  <obsolete>
-    Removed May 2020, replaced with more detailed histograms:
-    History.ClearBrowsingData.Duration.TimeRangeDeletion,
-    History.ClearBrowsingData.Duration.OriginDeletion,
-    History.ClearBrowsingData.Duration.FilteredDeletion.
-  </obsolete>
-  <owner>dullweber@chromium.org</owner>
-  <owner>msramek@chromium.org</owner>
-  <summary>
-    The time that passed while performing a browsing data deletion for a
-    restricted amount of time (e.g. &quot;Last hour&quot;) or with an origin
-    filter.
-  </summary>
-</histogram>
-
-<histogram name="History.ClearBrowsingData.SpannableStringAppliedCorrectly"
-    enum="Boolean" expires_after="2020-03-01">
-  <obsolete>
-    Removed 02/2020 since the histogram indicators were stable.
-  </obsolete>
-  <owner>dullweber@chromium.org</owner>
-  <owner>msramek@chromium.org</owner>
-  <summary>
-    Track whether the SpannableString is applied correctly in
-    ClearBrowsingDataCheckbox.java. (crbug.com/783866)
-  </summary>
-</histogram>
-
-<histogram name="History.FaviconsRecoveredPercentage" units="%"
-    expires_after="2017-04-12">
-  <obsolete>
-    No longer tracked as of March 2017.
-  </obsolete>
-  <owner>rpop@google.com</owner>
-  <summary>
-    Size of the recovered Favicons database relative to the original corrupt
-    database. Recovery is VACUUM-like, so the resulting database should always
-    be smaller. Substantial 100% results would indicate empty databases being
-    recovered, substantial low% results would indicate very little data being
-    recovered.
-  </summary>
-</histogram>
-
-<histogram name="History.FaviconsRecoveredRowsFaviconBitmaps" units="units"
-    expires_after="2017-04-12">
-  <obsolete>
-    No longer tracked as of March 2017.
-  </obsolete>
-  <owner>rpop@google.com</owner>
-  <summary>
-    Rows recovered from [favicon_bitmaps] table in Favicons recovery.
-  </summary>
-</histogram>
-
-<histogram name="History.FaviconsRecoveredRowsFavicons" units="units"
-    expires_after="2017-04-12">
-  <obsolete>
-    No longer tracked as of March 2017.
-  </obsolete>
-  <owner>rpop@google.com</owner>
-  <summary>Rows recovered from [favicons] table in Favicons recovery.</summary>
-</histogram>
-
-<histogram name="History.FaviconsRecoveredRowsIconMapping" units="units"
-    expires_after="2017-04-12">
-  <obsolete>
-    No longer tracked as of March 2017.
-  </obsolete>
-  <owner>rpop@google.com</owner>
-  <summary>
-    Rows recovered from [icon_mapping] table in Favicons recovery.
-  </summary>
-</histogram>
-
-<histogram name="History.FaviconsRecovery" enum="HistoryFaviconsRecoveryEnum"
-    expires_after="2017-04-12">
-  <obsolete>
-    No longer tracked as of March 2017.
-  </obsolete>
-  <owner>rpop@google.com</owner>
-  <summary>
-    Track results of SQLite database recovery code in thumbnail_database.cc.
-  </summary>
-</histogram>
-
-<histogram name="History.HistoryServiceInitTime" units="ms" expires_after="M81">
-  <obsolete>
-    Removed as of 02/2020. The vast majority of the time this is under 50ms.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during HistoryService::Init.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryDBKeywordTermsPopulate" units="ms"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed July 2020 as not deemed necessary.
-  </obsolete>
-  <owner>sky@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Time to load in-memory keyword_search_terms table from disk. Recorded on
-    profile open.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryDBKeywordURLPopulate" units="ms"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed July 2020 as not deemed necessary.
-  </obsolete>
-  <owner>sky@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Time to load in-memory urls table from disk urls table. Recorded on profile
-    open.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryTypedUrlVisitCount" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    No longer needed. Removed Aug 2019 as part of crbug.com/969934 cleanup.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The sum of the visit_count fields for all URLs in the &quot;in memory&quot;
-    history database. This corresponds to the number of times the user has
-    visited the typed URLs in the last 30 days (excluding page reloads, since
-    the history database does not increment the visit_count in that case).
-    Recorded on profile open.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryURLCacheSize" units="bytes"
-    expires_after="M86">
-  <obsolete>
-    Removed August 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Size of on-disk cache for in-memory url index. Recorded on profile open when
-    restoring from a cache file.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryURLChars" units="units" expires_after="M86">
-  <obsolete>
-    Removed August 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Number of items in the in-memory url index char_word_map_. Recorded on
-    profile open when restoring from a cache file and again shortly after
-    profile open when rebuilding the in-memory url index from history.
-  </summary>
-</histogram>
-
-<histogram name="History.InMemoryURLWords" units="units" expires_after="M86">
-  <obsolete>
-    Removed August 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Number of items in in-memory url index word_map_. Recorded on profile open
-    when restoring from a cache file and again shortly after profile open when
-    rebuilding the in-memory url index from history.
-  </summary>
-</histogram>
-
-<histogram name="History.TopHostsVisitsByRank" units="rank"
-    expires_after="2018-11-02">
-  <obsolete>
-    Removed as of 11/2018, not used in production since 2/2018.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Page visits to each of a user's top 50 hosts. The bucket is the 1-based rank
-    of the host. Visits to all other hosts go into the 51st bucket.
-    Android-only. Only counts the last URL in a redirect chain and does not
-    include reloads. The list of top hosts is computed approximately nightly.
-    This means that a given day will likely include a recalculation of top
-    hosts, and therefore a given bucket may represent two different hosts at
-    different times of day.
-  </summary>
-</histogram>
-
-<histogram name="History.TopSitesVisitsByRank" units="rank"
-    expires_after="2014-11-17">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page visits to each of a user's top 50 sites. Visits to all other sites go
-    into the 51st bucket. Only count the page visit if it came from user
-    browsing and only count it once when cycling through a redirect chain.
-  </summary>
-</histogram>
-
-<histogram name="History.UpdateTopSitesOnDBThreadTime" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed because only the execution time at startup is of interest. See
-    histogram History.UpdateTopSitesOnDBThread_Startup_Time.
-  </obsolete>
-  <owner>yiyaoliu@chromium.org</owner>
-  <summary>
-    The amount of time for function
-    history::TopSitesBackend::UpdateTopSitesOnDBThread to execute. Excludes the
-    case where local TopSitesDatabase db_ is unavailable, i.e. where the update
-    doesn't really happen.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.AudioLoggingEnabled" enum="BooleanEnabled"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>rlp@chromium.org</owner>
-  <summary>
-    The state of the hotword audio logging preference. This value is emitted
-    each time the hotword availability is requested by the extension if the user
-    is also opted in to hotword voice search. This check typically happens each
-    time a hotword search is initiated.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.Enabled" enum="HotwordPrefState"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>rlp@chromium.org</owner>
-  <summary>
-    The state of the hotword preference. This value is emitted during
-    HotwordService initialization which happens during Profile initialization.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.ExtensionAvailability" enum="HotwordAvailability"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>rlp@chromium.org</owner>
-  <summary>
-    Whether the external component hotword extension exists (i.e., not pending
-    download, disabled, etc.). This value is emitted each time the hotword
-    availability is requested by the extension which typically happens each time
-    a hotword search is initiated.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.HotwordError" enum="HotwordError"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>rlp@chromium.org</owner>
-  <summary>
-    Errors reported by the hotword service when determining if hotwording is
-    available. Non-errors are also reported so that errors can be seen as a
-    percentage of total requests.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.HotwordMediaStreamResult"
-    enum="HotwordMediaStreamResult" expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>rlp@chromium.org</owner>
-  <owner>somast@chromium.org</owner>
-  <summary>
-    Success or error when attempting to open a MediaStream for the microphone.
-    At most one success or error will be logged for an attempt to open a stream.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.HotwordNaClMessageTimeout"
-    enum="HotwordNaClMessageTimeout" expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>rlp@chromium.org</owner>
-  <owner>somast@chromium.org</owner>
-  <summary>
-    Timeout occured while waiting for a message from the NaCl hotword detector
-    plugin. This value is the message that was expected to be received from the
-    plugin.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.HotwordNaClPluginLoadResult"
-    enum="HotwordNaClPluginLoadResult" expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>rlp@chromium.org</owner>
-  <owner>somast@chromium.org</owner>
-  <summary>
-    Success or error when attempting to load the NaCl hotword detector plugin.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.HotwordTriggerSource" enum="HotwordTriggerSource"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>rlp@chromium.org</owner>
-  <owner>somast@chromium.org</owner>
-  <summary>
-    Location of hotword trigger. Emitted every time the hotword is triggered by
-    the user saying 'Ok Google'.
-  </summary>
-</histogram>
-
-<histogram name="Hotword.SharedModuleReinstallLanguage" enum="LanguageName"
-    expires_after="2017-11-28">
-  <obsolete>
-    Removed as of 10/2017. Feature removed with crbug/761426.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>rlp@chromium.org</owner>
-  <owner>somast@chromium.org</owner>
-  <summary>
-    Language, switched to by the user, that triggered a hotword shared module
-    reinstall.
-  </summary>
-</histogram>
-
-<histogram name="HTMLImport.UnexpectedRequest" enum="ResourceType"
-    expires_after="M82">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    Logs the type of requests made by HTML imports with wrong fetcher.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.AsyncValidationDuration" units="ms"
-    expires_after="2015-06-19">
-  <obsolete>
-    Removed as of 3/2015.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    The time spent performing an asynchronous revalidation that was triggered by
-    a Cache-Control: stale-while-revalidate directive. This is recorded when the
-    asynchronous revalidation completes, either after the response was
-    completely read or an error occurred. One entry is recorded for each
-    asynchronous revalidation that is performed.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.ExternallyConditionalized"
-    enum="ExternallyConditionalizedType" expires_after="2017-03-27">
-  <obsolete>
-    stale-while-revalidate implementation removed for now, see
-    https://crbug.com/700568.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count of the number of external (ie. from Blink) conditionalized requests,
-    and whether or not those requests could have been served from the browser
-    cache.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.NetworkIsolationKeyPresent"
-    enum="BooleanNetworkIsolationKeyPresent" expires_after="2020-06-07">
-  <obsolete>
-    Removed in favor of HttpCache.NetworkIsolationKeyPresent2.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>shivanisha@chromium.org</owner>
-  <summary>
-    Records whether a cache request has a network isolation key set or not,
-    which is used for double-keying.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.OfflineStatus" enum="OfflineStatus"
-    expires_after="2015-04-27">
-  <obsolete>
-    Removed 4/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Result of a main page HttpCacheTransaction if offline mode had been enabled.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.PercentBeforeSend" units="%" expires_after="M77">
-  <obsolete>
-    Removed 2019-07-03.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For http cache transactions in which a network request was sent, the
-    percentage of total request time that elapsed before sending the request
-    over the network; this is the time spent accessing the disk cache.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed"
-    units="units" expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For each http cache transaction for which a cache entry exists but it cannot
-    be used because the entry's age is beyond its freshness: counts how many
-    freshness periods have elapsed since the entry was last used (x1000).
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.StaleEntry.Updated.Age" units="seconds"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For each http cache transaction for which a validation attempt is made due
-    to a stale entry and is updated (e.g., 200), records the age of the entry in
-    seconds.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.StaleEntry.Updated.AgeInFreshnessPeriods" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For each http cache transaction for which a validation attempt is made due
-    to a stale entry and is updated (e.g., 200), records the age of the entry as
-    percentage of freshness period.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.StaleEntry.Validated.Age" units="seconds"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For each http cache transaction for which a validation attempt is made due
-    to a stale entry and is validated (304), records the age of the entry in
-    seconds.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.StaleEntry.Validated.AgeInFreshnessPeriods"
-    units="%" expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For each http cache transaction for which a validation attempt is made due
-    to a stale entry and is validated (304), records the age of the entry as
-    percentage of freshness period.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.TopFrameOriginPresent"
-    enum="BooleanTopFrameOriginPresent" expires_after="2020-02-26">
-  <obsolete>
-    Removed 07/2019 and replaced by HttpCache.NetworkIsolationKeyPresent.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>shivanisha@chromium.org</owner>
-  <summary>
-    Records whether a cache request has a top frame origin set or not, which is
-    used for double-keying.
-  </summary>
-</histogram>
-
-<histogram name="HttpCache.Vary" enum="VaryType" expires_after="2014-11-04">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The type of Vary header for a given GET response.</summary>
-</histogram>
-
-<histogram name="Import.IncludesPasswords.Firefox" enum="BooleanChecked"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>hurims@gmail.com</owner>
-  <summary>
-    Whether or not the password checkbox is checked when importing a profile of
-    Firefox. Note that canceled imports could be counted also.
-  </summary>
-</histogram>
-
-<histogram name="Import.NumberOfImportedPasswords.Firefox" units="units"
-    expires_after="M86">
-  <obsolete>
-    Removed 07/2020.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>hurims@gmail.com</owner>
-  <summary>
-    The number of passwords that are imported from Firefox. This is recorded
-    when importing a profile of Firefox with the password checkbox checked. Note
-    that the reported number of password could be slightly bigger than the
-    actual number of imported passwords because some incomplete or blacklisted
-    passwords that are dropped while importing might be included in the reported
-    value.
-  </summary>
-</histogram>
-
-<histogram name="Import.ShowDialog.FromBookmarkBarView" units="seconds"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed and removed BookmarkBarView
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time from install time to time that user opens import dialog
-    from BookmarkBarView.
-  </summary>
-</histogram>
-
-<histogram name="Import.ShowDialog.FromFloatingBookmarkBarView" units="seconds"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed and removed BookmarkBarView
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time from install time to time that user opens import dialog
-    from NTP floating BookmarkBarView.
-  </summary>
-</histogram>
-
-<histogram name="Import_ShowDlg.FromBookmarkBarView" units="seconds"
-    expires_after="2013-05-20">
-  <obsolete>
-    Removed and replaced by Import.ShowDialog.FromBookmarkBarView
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time from install time to time that user opens import dialog
-    from BookmarkBarView.
-  </summary>
-</histogram>
-
-<histogram name="Import_ShowDlg.FromFloatingBookmarkBarView" units="seconds"
-    expires_after="2013-05-20">
-  <obsolete>
-    Removed and replaced by Import.ShowDialog.FromFloatingBookmarkBarView
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time from install time to time that user opens import dialog
-    from NTP floating BookmarkBarView.
-  </summary>
-</histogram>
-
-<histogram name="ImportantFile.FileDeleteError" enum="PlatformFileError"
-    expires_after="2021-01-19">
-  <obsolete>
-    Replaced by ImportantFile.FileDeleteNoRetryError,
-    ImportantFile.FileDeleteRetryExceededError, and
-    ImportantFile.FileDeleteRetrySuccessCount in M84.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <owner>xaerox@yandex-team.ru</owner>
-  <summary>
-    File error happened upon temporary file deletion at ImportantFileWriter.
-  </summary>
-</histogram>
-
-<histogram name="ImportantFile.FileOpenError" enum="PlatformFileError"
-    expires_after="M77">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>xaerox@yandex-team.ru</owner>
-  <summary>
-    File error happened upon opening temporary file at ImportantFileWriter.
-  </summary>
-</histogram>
-
-<histogram name="ImportantFile.TimeToWrite" units="ms"
-    expires_after="2019-11-05">
-  <obsolete>
-    Removed in 2019-11.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Time used to atomically write string into a file using ImportantFileWriter.
-  </summary>
-</histogram>
-
-<histogram name="InertialSensor.RotationVectorAndroidAvailable"
-    enum="BooleanAvailable" expires_after="2014-11-19">
-  <obsolete>
-    Removed 11/2014 (crbug.com/347507). Replaced by
-    InertialSensor.DeviceOrientationSensorAndroid.
-  </obsolete>
-  <owner>timvolodine@chromium.org</owner>
-  <summary>
-    Whether the Sensor.TYPE_ROTATION_VECTOR was available at the start of Device
-    Orientation.
-  </summary>
-</histogram>
-
-<histogram name="InputMethod.Commit.Type" enum="IMECommitType"
-    expires_after="2015-03-23">
-  <obsolete>
-    Removed 03/2015, and replaced by InputMethod.Commit.Type2.
-  </obsolete>
-  <owner>shuchen@chromium.org</owner>
-  <summary>
-    The suggestion accuracy type which the user chooses to commit.
-  </summary>
-</histogram>
-
-<histogram name="InputMethod.ID" enum="InputMethodID"
-    expires_after="2015-07-16">
-  <obsolete>
-    This is deprecated since M46, InputMethod.ID2 is used since then.
-  </obsolete>
-  <owner>shuchen@chromium.org</owner>
-  <summary>
-    The breakdown of input method usage by input method IDs. Recorded when the
-    user presses keys on physical or on-screen keyboard.
-  </summary>
-</histogram>
-
-<histogram name="InputMethod.RegisterProxyView" enum="IMERegisterProxyView"
-    expires_after="M77">
-  <obsolete>
-    Removed as of Jan 2020.
-  </obsolete>
-  <owner>changwan@chromium.org</owner>
-  <summary>The result of registering proxy view to InputMethodManager.</summary>
-</histogram>
-
-<histogram name="Installer.Recovery.Count" units="count"
-    expires_after="2017-08-17">
-  <obsolete>
-    Superseded by Installer.Recovery.Reason in 8/2017.
-  </obsolete>
-  <owner>ahassani@chromium.org</owner>
-  <owner>chromeos-core-services@google.com</owner>
-  <summary>
-    The number of times the device has been recovered.
-
-    This is reported on reboot after a successful recovery. Cleared only when
-    switching to dev mode or on factory reset.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="InstallSigner.InvalidCount" units="units"
-    expires_after="2015-04-23">
-  <obsolete>
-    Removed 4/2015. It appears the code at some point changed to use the
-    histogram name 'ExtensionInstallSigner.InvalidCount' and we forgot to update
-    this histogram name.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This is a count of the number of ids that we asked to be signed which the
-    server response indicated were not in the webstore.
-  </summary>
-</histogram>
-
-<histogram name="InstallSigner.InvalidSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallSigner.ResultWasValid.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extensions install signer got a well-formed result from the server but
-    the signature check on it failed.
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.CallbackInvalidSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.GetSignatureResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier tried to get a new signature and received a
-    response but it wasn't properly signed.
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.CallbackNoSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.GetSignatureResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier tried to get a new signature but was unable
-    to (network error contacting the server, response from server was malformed,
-    etc.).
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.CallbackValidSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.GetSignatureResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier got a new signature from the server that was
-    valid.
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.InitGoodSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.InitResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier found a valid signature at startup, and this
-    is a count of the number of signed ids it contained.
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.InitInvalidSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.InitResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier found a signature in the prefs at startup,
-    and it parsed properly, but it was invalid (some ids may have been
-    added/removed, could not verify it was signed with the correct private key,
-    etc.).
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.InitNoSignature" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.InitResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier did not find any signature in the prefs at
-    startup.
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.InitUnparseablePref" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.InitResult.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier found a signature in the prefs at startup,
-    but it wasn't parseable (missing/wrong format of required keys, etc.).
-  </summary>
-</histogram>
-
-<histogram name="InstallVerifier.SignatureFailedButNotEnforcing" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed 1/2014 (crbug.com/333934). Replaced by
-    ExtensionInstallVerifier.MustRemainDisabled.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The extension install verifier would have disabled an extension but is not
-    in enforcement mode.
-  </summary>
-</histogram>
-
-<histogram name="InstanceID.DeleteToken.CompleteTime" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time taken to complete the DeleteToken request successfully. If
-    the request is retried multiple times, the length of time is counted for the
-    last successful retry.
-  </summary>
-</histogram>
-
-<histogram name="InstanceID.DeleteToken.RetryCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of retries before DeleteToken succeeds.</summary>
-</histogram>
-
-<histogram name="InstanceID.Enabled" enum="BooleanEnabled"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether the Instance ID API is enabled. Checked when a chrome.instanceID
-    function is called.
-  </summary>
-</histogram>
-
-<histogram name="InstanceID.GeneratedNewID" enum="BooleanHit"
-    expires_after="M85">
-  <obsolete>
-    Removed in 2020-06.
-  </obsolete>
-  <owner>tschumann@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Counts the events when the GCM integration generates and registers a new
-    instance ID with FCM. This histogram acts as a pure counter and only emits
-    'true' values. The goal of the histogram is to detect potential instance ID
-    leaks. It's best interpreted in relation to the reported number of
-    syncing/sync-transport users.
-  </summary>
-</histogram>
-
-<histogram name="InstanceID.GetToken.RetryCount" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 7/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of retries before GetToken succeeds.</summary>
-</histogram>
-
-<histogram name="Instant.InstantControllerEvent" enum="InstantControllerEvent"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records various events of interest in the InstantController. E.g. When URLs
-    are blacklisted.
-  </summary>
-</histogram>
-
-<histogram name="Instant.SessionsStorageNamespace"
-    enum="InstantSessionStorageNamespace" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How often an Instant preview is committed onto a different tab than it was
-    created from.
-  </summary>
-</histogram>
-
-<histogram name="Instant.TimeToFirstShow" units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time between the first Omnibox interaction and when the Instant preview
-    shows. If the instant preview was already showing when the user interacted
-    with the omnibox, this histogram is not recorded.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.CacheableNTPLoad"
-    enum="InstantExtended_CacheableNTPLoad" expires_after="M77">
-  <obsolete>
-    Removed as of 07/2019, see crbug.com/975798.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    Records a histogram for how often the Cacheable NTP fails to load.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.FallbackToLocalOverlay"
-    enum="InstantExtended_FallbackCause" expires_after="2014-02-03">
-  <obsolete>
-    Depcreated as of 10/2013. No longer relevant since the HTML overlay was
-    abandoned.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records the cause for falling back to a local overlay at the time of
-    fallback.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.InstantNavigation"
-    enum="InstantExtended_InstantNavigation" expires_after="2013-10-28">
-  <obsolete>
-    Removed as of 10/2013. This histogram is no longer relevant since the HTML
-    overlay went away.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records a histogram for instant extended (Local NTP and Online NTP) and
-    non-extended navigations.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.NewOptInState"
-    enum="InstantExtended_NewOptInState" expires_after="2013-11-20">
-  <obsolete>
-    Removed as of 11/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records, on startup, whether the user has chosen to opt-in to or opt-out of
-    InstantExtended via chrome://flags.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.OptInState" enum="InstantExtended_OptInState"
-    expires_after="2013-06-27">
-  <obsolete>
-    Removed 2013-06. As of m30 use InstantExtended.NewOptInState.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records, on startup, whether the user has chosen to opt-in to or opt-out of
-    InstantExtended via chrome://flags.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchQuerytoQuery" units="%"
-    expires_after="2013-07-24">
-  <obsolete>
-    Removed 2013-07. Please see InstantExtended.PercentageMatchV2_QuerytoQuery
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a search query to another search query.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchQuerytoURL" units="%"
-    expires_after="2013-07-24">
-  <obsolete>
-    Removed 2013-07. Please see InstantExtended.PercentageMatchV2_QuerytoURL
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a search query to a url. Example: Accidental search for
-    google.con, then navigation to google.com.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchURLtoQuery" units="%"
-    expires_after="2013-07-24">
-  <obsolete>
-    Removed 2013-07. Please see InstantExtended.PercentageMatchV2_URLtoQuery
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a url to a search query.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchURLtoURL" units="%"
-    expires_after="2013-07-24">
-  <obsolete>
-    Removed 2013-07. Please see InstantExtended.PercentageMatchV2_URLtoURL
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a url to another url.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchV2_QuerytoQuery" units="%"
-    expires_after="2016-09-22">
-  <obsolete>
-    Removed in August 2016 with the removal of query in the omnibox code.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a search query to another search query.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchV2_QuerytoURL" units="%"
-    expires_after="2016-09-22">
-  <obsolete>
-    Removed in August 2016 with the removal of query in the omnibox code.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a search query to a url. Example: Accidental search for
-    google.con, then navigation to google.com.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchV2_URLtoQuery" units="%"
-    expires_after="2016-09-22">
-  <obsolete>
-    Removed in September 2016 because (i) this measurement was somewhat wrong,
-    (ii) it's difficult to understand the data, and (iii) there are better ways
-    to answer the same question. The measurement is somewhat wrong because
-    reloads, link drops, and pasting URLs and pressing enter are all incorrectly
-    logged to the URLtoQuery histogram, not the URLtoURL histogram. Futhermore,
-    this histogram is difficult to analyze because it's not broken up by input
-    length. Short URLs can by random chance have a sizable percentage match with
-    a query. Finally, there are better source for data like this; ask mpearson
-    for details.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a url to a search query.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PercentageMatchV2_URLtoURL" units="%"
-    expires_after="2016-09-22">
-  <obsolete>
-    Removed in September 2016 because (i) this measurement was somewhat wrong,
-    and (ii) there are better ways to answer the same question. The measurement
-    is somewhat wrong because reloads, link drops, and pasting URLs and pressing
-    enter are all incorrectly logged to the URLtoQuery histogram, not the
-    URLtoURL histogram. Furthermore, there are better source for data like this;
-    ask mpearson for details.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Records the number of matching characters at the start of the user's text as
-    a percentage of average length between the old and new text when the user
-    navigates from a url to another url.
-  </summary>
-</histogram>
-
-<histogram name="InstantExtended.PrefValue" enum="BooleanEnabled"
-    expires_after="2013-07-08">
-  <obsolete>
-    Removed 2013-06. This preference has not been exposed or used for months,
-    and we do not plan to use it in the future.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records, on startup, the value of the &quot;Allow your search engine to
-    provide Instant result&quot; preference setting for the first profile
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="InstantSearchClicks.PreviewScrollState"
-    enum="InstantSearchClicks_PreviewScrollState" expires_after="2015-07-22">
-  <obsolete>
-    Removed as of 7/2015.
-  </obsolete>
-  <owner>ksimbili@chromium.org</owner>
-  <summary>
-    Records the scroll state on the preview page when instant search clicks
-    feature is triggered.
-  </summary>
-</histogram>
-
-<histogram name="InstantSearchClicks.ReasonForSwap"
-    enum="InstantSearchClicks_ReasonForSwap" expires_after="2015-07-22">
-  <obsolete>
-    Removed as of 7/2015.
-  </obsolete>
-  <owner>ksimbili@chromium.org</owner>
-  <summary>
-    Records the reason that triggered the page swap when instant search clicks
-    feature is triggered.
-  </summary>
-</histogram>
-
-<histogram name="InstantSearchClicks.TimeInPreview" units="ms"
-    expires_after="2015-07-22">
-  <obsolete>
-    Removed as of 7/2015.
-  </obsolete>
-  <owner>ksimbili@chromium.org</owner>
-  <summary>
-    The time spent by the user in preview page before swapping to original or
-    navigating out of preview page.
-  </summary>
-</histogram>
-
-<histogram name="InstantSearchClicks.TimeToSwap" units="ms"
-    expires_after="2015-07-22">
-  <obsolete>
-    Removed as of 7/2015.
-  </obsolete>
-  <owner>ksimbili@chromium.org</owner>
-  <summary>
-    The time it took for swap to trigger for all swaps. The is the time between
-    preview page load start to preview page swap with the original page.
-  </summary>
-</histogram>
-
-<histogram name="InstantTethering.ConnectionToHostResult.SuccessRate"
-    enum="InstantTethering_ConnectionToHostResult_SuccessRate"
-    expires_after="2019-02-21">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Captures the count of successful and failed connection attempts.
-
-    This metric counts the top-level user action from beginning to connect, all
-    the way through success or failure of the connection (excluding any
-    programmatic retries within the connection attempt).
-
-    This metric provides an immediate understanding of the Instant Tethering
-    connection success rate. The counts of failure are broken down in
-    InstantTethering.ConnectionToHostResult.Failure.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.GattConnectionAttempt.EffectiveSuccessRateWithRetries"
-    enum="BooleanSuccess" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Captures the effective count of successful and failed GATT connection
-    attempts, including retries. This means that if a GATT connection attempt
-    fails but then succeeds on a future retry, this is counted as a single
-    success. In the context of this metric, a failure represents a GATT failure
-    in all retry attempts.
-
-    An individual attempt is considered successful if a GATT connection was
-    created and authenticated successfully (i.e., the connection was ready for
-    Instant Tethering to exchange protocol messages).
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.GattConnectionAttempt.EffectiveSuccessRateWithRetries.Background"
-    enum="BooleanSuccess" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Captures the effective count of successful and failed GATT connection
-    attempts, including retries. This means that if a GATT connection attempt
-    fails but then succeeds on a future retry, this is counted as a single
-    success. In the context of this metric, a failure represents a GATT failure
-    in all retry attempts.
-
-    An individual attempt is considered successful if a GATT connection was
-    created and authenticated successfully (i.e., the connection was ready for
-    Instant Tethering to exchange protocol messages).
-
-    This metric is the background advertisement analog of
-    InstantTethering.GattConnectionAttempt.EffectiveSuccessRateWithRetries.
-  </summary>
-</histogram>
-
-<histogram name="InstantTethering.GattConnectionAttempt.SuccessRate"
-    enum="BooleanSuccess" expires_after="2019-02-21">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Captures the count of successful and failed GATT connection attempts.
-
-    An attempt is considered successful if a GATT connection was created and
-    authenticated successfully (i.e., the connection was ready for Instant
-    Tethering to exchange protocol messages).
-  </summary>
-</histogram>
-
-<histogram name="InstantTethering.GattConnectionAttempt.SuccessRate.Background"
-    enum="BooleanSuccess" expires_after="2019-02-21">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    Captures the count of successful and failed GATT connection attempts.
-
-    An attempt is considered successful if a GATT connection was created and
-    authenticated successfully (i.e., the connection was ready for Instant
-    Tethering to exchange protocol messages).
-
-    This metric is the background advertisement analog of
-    InstantTethering.GattConnectionAttempt.SuccessRate.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.AdvertisementToConnectionDuration"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client begins to scan and advertise, and
-    connects to a host (before authentication).
-
-    This histogram only considers the time from when the client *sends* an
-    advertisement, and not when the client *receives* an advertisement. See
-    InstantTethering.Performance.StartScanToReceiveAdvertisementDuration and
-    InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration for
-    histograms that consider when the client receives an advertisement.
-
-    This histogram is the foreground advertisement analog of
-    InstantTethering.Performance.StartScanToConnectionDuration.Background.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.ConnectionToAuthenticationDuration"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client connects to a host, and
-    authenticates with that host.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.ConnectionToAuthenticationDuration.Background"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client connects to a host, and
-    authenticates with that host.
-
-    This histogram is the background advertisement analog of
-    InstantTethering.Performance.ConnectionToAuthenticationDuration.
-  </summary>
-</histogram>
-
-<histogram name="InstantTethering.Performance.ConnectToHostDuration" units="ms"
-    expires_after="2019-02-21">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time it takes for the client to connect to the host, from
-    the moment the user taps 'Connect', until the client connects to the host's
-    hotspot. This does not include timeouts.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client received a foreground
-    advertisement from a host, and connected to that host (before
-    authentication).
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration.Background"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client received a background
-    advertisement from a host, and connected to that host (before
-    authentication).
-
-    This histogram is the background advertisement analog of
-    InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.StartScanToConnectionDuration.Background"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client begins to scan, and connects to a
-    host (before authentication).
-
-    This histogram is the background advertisement analog of
-    InstantTethering.Performance.AdvertisementToConnectionDuration.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.StartScanToReceiveAdvertisementDuration"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client begins to scan and advertise, and
-    receives a foreground advertisement from a host.
-  </summary>
-</histogram>
-
-<histogram
-    name="InstantTethering.Performance.StartScanToReceiveAdvertisementDuration.Background"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019/02 in favor of MultiDevice.* equivalent.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when a client begins to scan, and receives a
-    background advertisement from a host.
-
-    This histogram is the background advertisement analog of
-    InstantTethering.Performance.AdvertisementToConnectionDuration.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.authority_invalid_time" units="ms"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed on 8/1/13.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between the SSL interstitial display and the user decision, which
-    may be either accept or deny. This is only recorded for overridable SSL
-    warnings with a CERT_AUTHORITY_INVALID warning. Timing begins when user
-    first focuses on the page.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.common_name_invalid_time" units="ms"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed on 8/1/13.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between the SSL interstitial display and the user decision, which
-    may be either accept or deny. This is only recorded for overridable SSL
-    warnings with a CERT_COMMON_NAME_INVALID warning. Timing begins when user
-    first focuses on the page.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.date_invalid_time" units="ms"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed on 8/1/13.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between the SSL interstitial display and the user decision, which
-    may be either accept or deny. This is only recorded for overridable SSL
-    warnings with a CERT_DATE_INVALID warning. Timing begins when user first
-    focuses on the page.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl" enum="SSLResponseTypesV2"
-    expires_after="2015-01-17">
-  <obsolete>
-    Replaced by interstitial.ssl_overridable.* and
-    interstitial.ssl_nonoverridable.* in Jan 2015 (M42).
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    User action when the user is shown a SSL interstitial. SHOW_ALL and MORE
-    refer to the total number of SSL errors; all of the other numbers pertain to
-    the number of actions related to SSL errors that are overridable. The counts
-    do not sum to 100%; SHOW_ALL is a superset of SHOW_OVERRIDABLE, which in
-    turn will be a supserset of the PROCEED/DONT_PROCEED variables.
-    SHOW_UNDERSTAND is only being used by an experimental field trial. The
-    interstitials due to captive portals are now recorded in the
-    &quot;SSLCaptivePortal&quot;.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.clockstate.network" enum="ClockStates"
-    expires_after="2016-08-30">
-  <obsolete>
-    Removed August 2016. Replaced with interstitial.ssl.clockstate.network2,
-    which records reasons why network time might be unavailable.
-  </obsolete>
-  <owner>mab@chromium.org</owner>
-  <summary>
-    State of the system clock, relative to network time, when an SSL
-    CERT_INVALID_DATE error is seen.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.clockstate.network2"
-    enum="NetworkClockStates" expires_after="2016-10-18">
-  <obsolete>
-    Removed October 2016. Due to a bug, data in this histogram is mislabelled
-    and should be disregarded. Replaced with
-    interstitial.ssl.clockstate.network3.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>mab@chromium.org</owner>
-  <summary>
-    State of the system clock, relative to network time, when an SSL
-    CERT_INVALID_DATE error is seen.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.did_user_revoke_decisions"
-    enum="BooleanRevoked" expires_after="2017-09-21">
-  <obsolete>
-    Removed September 13 2017.
-  </obsolete>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    Specifies when a user enters the page info menu whether or not the user
-    pressed the SSL decisions revoke button. This can only by done if the user
-    is in the &quot;Remember Certificate Error Decisions&quot; experiment. This
-    is logged when the page info UI is closed. Replaced by
-    .did_user_revoke_decisions2 to keep data separate after changing
-    functionality to only log when button was visible.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.expiration_and_decision.nonoverridable"
-    enum="SSLIsExpiredAndDecision" expires_after="2017-12-13">
-  <obsolete>
-    Removed Dec 2017 (M65).
-  </obsolete>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    Records when a user has made a decision to proceed on a nonoverridable SSL
-    interstitial. Also records whether a prior decision had been made but the
-    decision expired.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.expiration_and_decision.overridable"
-    enum="SSLIsExpiredAndDecision" expires_after="2017-12-13">
-  <obsolete>
-    Removed Dec 2017 (M65).
-  </obsolete>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    Records when a user has made a decision to proceed on an overridable SSL
-    interstitial. Also records whether a prior decision had been made but the
-    decision expired.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.good_cert_seen" enum="SSLGoodCertSeenEvent"
-    expires_after="2017-11-14">
-  <obsolete>
-    Removed Nov 2017 (M64).
-  </obsolete>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    Emitted when a good certificate is seen, specifying whether the user already
-    gave an exception for a bad certificate for the same host.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.good_cert_seen_type_is_frame" enum="Boolean"
-    expires_after="2017-12-04">
-  <obsolete>
-    Removed December 2017 (M65).
-  </obsolete>
-  <owner>jam@chromium.org</owner>
-  <summary>
-    Whether the resource type for a request that succeeded with a good cert and
-    revoked a certificate exception is for a frame (as opposed to subresource).
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.severity_score.authority_invalid" units="%"
-    expires_after="2015-01-14">
-  <obsolete>
-    Removed Jan 2015 (M42).
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The likelihood of a |CERT_AUTHORITY_INVALID| error being an attack.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.severity_score.common_name_invalid" units="%"
-    expires_after="2015-01-14">
-  <obsolete>
-    Removed Jan 2015 (M42).
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The likelihood of a |CERT_COMMON_NAME_INVALID| error being an attack.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl.severity_score.date_invalid" units="%"
-    expires_after="2015-01-14">
-  <obsolete>
-    Removed Jan 2015 (M42).
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The likelihood of a |CERT_DATE_INVALID| error being an attack.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl_accept_time" units="ms"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed on 8/1/13.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between the SSL interstitial display and the user decision, when
-    the user accepts the SSL warning. This is only recorded for overridable SSL
-    warnings. Timing begins when user first focuses on the page.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl_error_handler.superfish" enum="Boolean"
-    expires_after="2018-11-01">
-  <obsolete>
-    Removed 2018-11.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    When encountering a certificate error, Chrome looks for the well-known
-    Superfish certificate in the certificate chain and records this histogram as
-    true if the Superfish certificate is present and false otherwise. The
-    Superfish certificate is an indication that the user is vulnerable to
-    man-in-the-middle attacks because of software installed on their computer.
-  </summary>
-</histogram>
-
-<histogram name="interstitial.ssl_reject_time" units="ms"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed on 8/1/13.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between the SSL interstitial display and the user decision, when
-    the user rejects the SSL warning. This is only recorded for overridable SSL
-    warnings. Timing begins when user first focuses on the page.
-  </summary>
-</histogram>
-
-<histogram name="Invalidations.NetworkChannel"
-    enum="InvalidationNetworkChannel" expires_after="M76">
-  <obsolete>
-    Histogram for the deprecated implementation.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <owner>melandory@chromium.org</owner>
-  <summary>Network channel used for invalidations.</summary>
-</histogram>
-
-<histogram name="IOS.CanonicalURLResult" enum="CanonicalURLResult"
-    expires_after="2018-01-02">
-  <obsolete>
-    Removed 2018-01. As of M65 use Mobile.CanonicalURLResult.
-  </obsolete>
-  <owner>gchatz@chromium.org</owner>
-  <summary>
-    The result of the operation to retrieve the page's canonical URL.
-  </summary>
-</histogram>
-
-<histogram name="IOS.Inspect.Console" enum="IOSInspectConsoleAction"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <owner>michaeldo@chromium.org</owner>
-  <summary>
-    Recorded when the iOS JavaScript Console logging is manually enabled or
-    manually disabled.
-  </summary>
-</histogram>
-
-<histogram name="IOS.MailtoURLRewritten" enum="Boolean"
-    expires_after="2018-12-04">
-  <obsolete>
-    Removed 2018-12.
-  </obsolete>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    Counts the times when a mailto: URL is tapped by user and whether the URL
-    has been rewritten for an available native Mail client app or not.
-  </summary>
-</histogram>
-
-<histogram name="IOS.PageLoadCountMigration.Counts"
-    enum="IOSPageLoadCountNavigationType" expires_after="2017-11-28">
-  <obsolete>
-    Removed 2017-11.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Counts different types of navigation and loading events that are relevant to
-    counting page loads.
-  </summary>
-</histogram>
-
-<histogram name="IOS.ProviderIsValidOnShutdown" enum="Boolean"
-    expires_after="2020-08-01">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    Recorded when the user quits the app. True if ChromeBrowserProvider is a
-    non-null pointer. Chrome for iOS has frequent crashes during shutdown caused
-    by dereferencing null or dangling ChromeBrowserProvider pointer
-    (crbug.com/983504). ChromeBrowserProvider can only be null if iOS did not
-    call application:didFinishLaunchingWithOptions: callback. This metric should
-    help to understand if ChromeBrowserProvider can even be null after app is
-    launched.
-  </summary>
-</histogram>
-
-<histogram name="IOS.ShowTabSwitcherSnapshotResult"
-    enum="ShowTabSwitcherSnapshotResult" expires_after="2019-08-01">
-  <obsolete>
-    Removed 2019-01.
-  </obsolete>
-  <owner>edchin@chromium.org</owner>
-  <summary>
-    Tracks the result of snapshotting when the user enters the tab switcher.
-    Recorded whenever the user enters the tab switcher.
-  </summary>
-</histogram>
-
-<histogram name="IOS.TabGridMediator.DidDetachNilWebStateList"
-    enum="BooleanNil" expires_after="2019-05-01">
-  <obsolete>
-    Removed 2019-04.
-  </obsolete>
-  <owner>edchin@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    WebStateList should be guaranteed to be non-nil during a
-    WebStateListObserver callback. This histogram counts the frequency of this
-    invariant holding when webStateList:DidDetachWebState: is invoked in
-    TabGridMediator. Violations of this invariant is the cause of real-world
-    crashes (https://crbug.com/877792), which were not currently reproducible in
-    testing. This histogram is used to retain visibility of the severity of this
-    issue, while preventing the crashes with a no-op.
-  </summary>
-</histogram>
-
-<histogram name="IOS.TabGridMediator.GetActiveTabIDNilWebStateList"
-    enum="BooleanNil" expires_after="2019-05-01">
-  <obsolete>
-    Removed 2019-04.
-  </obsolete>
-  <owner>edchin@chromium.org</owner>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    WebStateList should be guaranteed to be non-nil during a
-    WebStateListObserver callback. This histogram counts the frequency of this
-    invariant holding when GetActiveTabID() is invoked in TabGridMediator.
-    Violations of this invariant is the cause of real-world crashes
-    (https://crbug.com/877792), which were not currently reproducible in
-    testing. This histogram is used to retain visibility of the severity of this
-    issue, while preventing the crashes with a no-op.
-  </summary>
-</histogram>
-
-<histogram name="IOS.WKWebViewStartProvisionalNavigationWithEmptyURL"
-    enum="Boolean" expires_after="2020-04-19">
-  <obsolete>
-    Removed 2020-03.
-  </obsolete>
-  <owner>mrsuyi@chromium.org</owner>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    On iOS9, didStartProvisionalNavigation may be called with empty URL. However
-    in didCommitNavigation the URL will be about:blank. This historgram checks
-    if this still happens in later iOS versions, and records it when it happens.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CharacterCount" units="characters"
-    expires_after="2020-07-06">
-  <obsolete>
-    Removed 2020-01.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of characters in JavaScript dialog messages.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CharacterCountUserSuppressed" units="characters"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed 2018-06.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of characters in JavaScript dialog messages that
-    were suppressed by the user. Compare with
-    JSDialogs.CountOfJSDialogMessageCharacters.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CountOfJSDialogMessageCharacters" units="characters"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed 2018-06.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of characters in JavaScript dialog messages.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CountOfJSDialogMessageNewlines" units="units"
-    expires_after="2018-06-25">
-  <obsolete>
-    Removed 2018-06.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of newlines in JavaScript dialog messages. (This
-    does not count breaks inserted by the UI toolkit in wrapping the messages.)
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CountOfOnBeforeUnloadMessageCharacters"
-    units="characters" expires_after="2016-03-11">
-  <obsolete>
-    Removed 2016-02.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of characters in onbeforeunload messages.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.CountOfOnBeforeUnloadMessageNewlines" units="units"
-    expires_after="2016-03-11">
-  <obsolete>
-    Removed 2016-02.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The count of the number of newlines in onbeforeunload messages. (This does
-    not count breaks inserted by the UI toolkit in wrapping the messages.)
-  </summary>
-</histogram>
-
-<histogram base="true" name="JSDialogs.DismissalCause"
-    enum="JavaScriptDialogDismissalCause" expires_after="M81">
-  <obsolete>
-    Removed 2020-01.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>The cause of dismissal of JavaScript dialogs.</summary>
-</histogram>
-
-<histogram
-    name="JSDialogs.FineTiming.TimeBetweenDialogClosedAndNextDialogCreated"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between closing a Javascript dialog and opening
-    another, to track very frequent dialogs.
-  </summary>
-</histogram>
-
-<histogram
-    name="JSDialogs.FineTiming.TimeBetweenDialogCreatedAndNextDialogCreated"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between opening a Javascript dialog and opening
-    another, to track very frequent dialogs.
-  </summary>
-</histogram>
-
-<histogram
-    name="JSDialogs.FineTiming.TimeBetweenDialogCreatedAndSameDialogClosed"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between opening a Javascript dialog and closing
-    it, to track very short-lived dialogs.
-  </summary>
-</histogram>
-
-<histogram base="true" name="JSDialogs.IsForemost" enum="BooleanForemost"
-    expires_after="M81">
-  <obsolete>
-    Removed 2020-01.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    For dialogs, whether or not they were spawned by a tab that was foremost.
-  </summary>
-</histogram>
-
-<histogram name="JSDialogs.SiteEngagementOfBeforeUnload" units="%"
-    expires_after="2017-10-11">
-  <obsolete>
-    Removed 2017-10.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The site engagement values of sites showing onbeforeunload dialogs. Logged
-    once per dialog, whether shown or suppressed.
-  </summary>
-</histogram>
-
-<histogram base="true" name="JSDialogs.SiteEngagementOfDialogs" units="%"
-    expires_after="2016-10-19">
-  <obsolete>
-    Removed 2016-10. Site engagement needed to be measured in small buckets
-    anyway so it was never high-resolution enough for use.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <summary>
-    The site engagement values of sites showing dialogs. Logged once per dialog,
-    whether shown or suppressed.
-  </summary>
-</histogram>
-
-<histogram name="Keyboard.KeystrokeDeltas" units="ms"
-    expires_after="2016-07-28">
-  <obsolete>
-    Removed 07/2016 in crbug.com/631204 with KeyboardUmaEventFilter removal.
-  </obsolete>
-  <owner>girard@chromium.org</owner>
-  <summary>
-    The time between keystrokes in Aura text fields. The only keystrokes that
-    are measured are ones that produce a printable character and are not over 5
-    seconds apart.
-  </summary>
-</histogram>
-
-<histogram name="Keyboard.Shortcuts.CrosSearchKeyDelay" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-07. Search key shortcut analysis is done.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>zalcorn@chromium.org</owner>
-  <summary>
-    The time between a user pressing the Chrome OS &quot;Search&quot; key and
-    the second key being pressed down to active a shortcut. e.g. Search + L
-    would record the time between Search key down and L key down. If the user
-    pressed multiple keys after Search, we only record the first key down.
-  </summary>
-</histogram>
-
-<histogram name="Keyboard.ShortcutViewer.SearchUpdateTime" units="microseconds"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06. Shortcut viewer has been in production for many milestones
-    and its performance is adequate.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <owner>msw@chromium.org</owner>
-  <owner>wutao@chromium.org</owner>
-  <summary>
-    Time delay to make the visual update in response to a search-query. Note
-    that this does *not* include the initial delay to trigger the update after
-    the initial keystroke to change the search-query string.
-  </summary>
-</histogram>
-
-<histogram name="Keyboard.ShortcutViewer.SearchUpdateTimeVisual" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06. Shortcut viewer has been in production for many milestones
-    and its performance is adequate.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <owner>msw@chromium.org</owner>
-  <owner>wutao@chromium.org</owner>
-  <summary>
-    Time delay for the visual update to be visible on screen in response to a
-    search-query. Note that this does *not* include the initial delay to trigger
-    the update after the initial keystroke to change the search-query string.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.GeneratedPasswordDialog"
-    enum="BooleanAccepted" expires_after="M77">
-  <obsolete>
-    Removed 2019-07 -- Replaced by
-    KeyboardAccessory.GeneratedPasswordDialogChoice*.
-  </obsolete>
-  <owner>ioanap@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Android only. Records the interaction with the password generation dialog.
-  </summary>
-</histogram>
-
-<histogram name="KioskNextHome.Bridge.Action" enum="KioskNextHomeBridgeAction"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed in 2019-07.
-  </obsolete>
-  <owner>brunoad@chromium.org</owner>
-  <owner>maroun@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>
-    Records usage of methods in KioskNextHome Mojo bridge. Recorded on every
-    method invocation.
-  </summary>
-</histogram>
-
-<histogram name="KioskNextHome.Bridge.GetAndroidIdSuccess"
-    enum="BooleanSuccess" expires_after="2019-12-31">
-  <obsolete>
-    Removed in 2019-07.
-  </obsolete>
-  <owner>brunoad@chromium.org</owner>
-  <owner>maroun@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>
-    Records the result (success or failure) of every call from KioskNextHome
-    bridge to get the Android id.
-  </summary>
-</histogram>
-
-<histogram name="KioskNextHome.Bridge.LaunchIntentResult"
-    enum="KioskNextHomeLaunchIntentResult" expires_after="2019-12-31">
-  <obsolete>
-    Removed in 2019-07.
-  </obsolete>
-  <owner>brunoad@chromium.org</owner>
-  <owner>maroun@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>
-    Records the result (success or error reason) of every call from
-    KioskNextHome bridge to launch an intent.
-  </summary>
-</histogram>
-
-<histogram base="true" name="KioskNextHome.StateTransition.AnimationSmoothness"
-    units="%" expires_after="2019-12-31">
-  <obsolete>
-    Removed on 2019-07.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="EnterOrExitOverview" -->
-
-  <owner>agawronska@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>
-    Relative smoothness of animations of KioskNext Home state transitions. 100%
-    represents ideally smooth 60 frames per second. 50% represents only 30
-    frames per second is achieved during the animations. 0% should not happen.
-    This metric is recorded exactly once when the user switches states of the
-    KioskNext Home.
-  </summary>
-</histogram>
-
-<histogram name="KioskNextShell.EnabledState" enum="BooleanEnabled"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed in 2019-07.
-  </obsolete>
-  <owner>brunoad@chromium.org</owner>
-  <owner>maroun@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>Records when KioskNextShell becomes enabled or disabled.</summary>
-</histogram>
-
-<histogram name="KioskNextShell.Launched" enum="Boolean"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed in 2019-07.
-  </obsolete>
-  <owner>brunoad@chromium.org</owner>
-  <owner>maroun@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>Records launches of KioskNextShell. Only true is recorded.</summary>
-</histogram>
-
-<histogram name="Launch.InvalidIntent" enum="BooleanHit"
-    expires_after="2016-06-14">
-  <obsolete>
-    Removed 2016-06 -- hit rate is neglible.
-  </obsolete>
-  <owner>dfalcantara@chromium.org</owner>
-  <summary>
-    Records whether or not an invalid Android Intent was fired to launch Chrome.
-    (http://crbug.com/445136)
-  </summary>
-</histogram>
-
-<histogram name="Launch.MashService" enum="MashService" expires_after="M80">
-  <obsolete>
-    Removed 2019-05 -- removed as part of removing mash code
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Records when a mojo ash UI service is started, for example the mojo app
-    version of the keyboard shortcut viewer.
-  </summary>
-</histogram>
-
-<histogram name="Layout.ScrollRestoration.PrecededByJsScroll"
-    enum="BooleanPrecededByJsScroll" expires_after="2018-09-07">
-  <obsolete>
-    Removed 2018-09. No longer needed.
-  </obsolete>
-  <owner>chaopeng@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    We are considering allowing JS scrolling to prevent browser scroll position
-    restoration. This histogram measures the impact of that change, in terms of
-    how often restoration would be prevented by JS Scroll. Recorded after each
-    successful scroll restoration attempt.
-  </summary>
-</histogram>
-
-<histogram name="LevelDB.ApproximateMemoryUse" units="bytes"
-    expires_after="2018-09-17">
-  <obsolete>
-    Replaced by LevelDB.ApproximateMemTableMemoryUse indefinitely.
-  </obsolete>
-  <owner>thildebr@chromium.org</owner>
-  <summary>
-    The approximate memory use of a LevelDB in bytes. Recorded right after
-    initializing an on-disk database.
-  </summary>
-</histogram>
-
-<histogram name="LevelDB.Open" enum="LevelDBStatus" expires_after="M83">
-  <obsolete>
-    Removed in 2020-04.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>The result of an open attempt of a leveldb.</summary>
-</histogram>
-
-<histogram name="LevelDB.SharedCache.BytesUsed" units="Bytes"
-    expires_after="2017-10-20">
-  <obsolete>
-    Removed 2017-10. Superceded by LevelDB.SharedCache.KBUsed.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The estimated size (in bytes) of the leveldb shared cache. Recorded once per
-    UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="LevelDB.SharedCache.DBCount" units="count" expires_after="M81">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    The number of databases currently using the shared block cache. Recorded
-    once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="LevelDB.SharedCache.KBUsed" units="KB"
-    expires_after="2020-06-28">
-  <obsolete>
-    No longer used. Removed in April, 2020.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The estimated size (in kilobytes) of the leveldb shared cache. Recorded once
-    per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.All.SafeThreadAccess" units="accesses"
-    expires_after="2013-10-16">
-  <obsolete>
-    Removed 2013-10. No thread-unsafety was found.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Linux and CrOS use unlocked_stdio(3). If it is used unsafely, record it
-    here. If there is no record of unsafety after chrome 29 has been in the
-    stable channel for a few weeks then revert this change.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError." enum="PlatformFileError"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use LevelDBEnv.IOError.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>PlatformFileErrors encountered by a single leveldb method.</summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.BFE" enum="PlatformFileError"
-    expires_after="M83">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    Errors (base::File::Error) encountered by a single leveldb method.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.NewLogger" enum="PopularOSErrno"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use LevelDBEnv.IOError.BFE.NewLogger.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>Errno of errors encountered in NewLogger.</summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.NewSequentialFile" enum="PopularOSErrno"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use LevelDBEnv.IOError.BFE.NewSequentialFile.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>Errno of errors encountered in NewSequentialFile.</summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.RandomAccessFile" enum="PlatformFileError"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed 2013-04. As of m28 use LevelDBEnv.IOError.NewRandomAccessFile.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    File errors in leveldb ChromiumEnv's NewRandomAccessFile method.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.WritableFileAppend" enum="PopularOSErrno"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use LevelDBEnv.IOError.BFE.WritableFileAppend.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>Errno of errors encountered in WritableFileAppend.</summary>
-</histogram>
-
-<histogram name="LevelDBEnv.IOError.WritableFileFlush" enum="PopularOSErrno"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use LevelDBEnv.IOError.BFE.WritableFileFlush.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>Errno of errors encountered in WritableFileFlush.</summary>
-</histogram>
-
-<histogram name="LevelDBEnv.LockFileAncestorsNotFound" units="directories"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-06.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Number of directories missing when Non-IDB LevelDBEnv tries to create a Lock
-    file.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.MaxFDs" units="files" expires_after="2017-09-21">
-  <obsolete>
-    Removed as of September 20, 2017.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    File descriptor limit recorded every time LevelDB calls NewRandomAccessFile
-    for clients other than IndexedDB.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.RetryRecoveredFromErrorIn" enum="PlatformFileError"
-    expires_after="M83">
-  <obsolete>
-    Removed April, 2020.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    When Non-IDB LevelDBEnv successfully retries an operation that had failed,
-    record the error from the most recent failed attempt.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.Table" enum="BooleanSuccess"
-    expires_after="2016-08-12">
-  <obsolete>
-    As of M54 no longer creating or using table backup files.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Success indicates a successful backup or restore operation for .ldb table
-    files when used by LevelDB clients other than IndexedDB.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.TimeTo" units="ms" expires_after="2013-04-30">
-  <obsolete>
-    Removed 2013-04. As of m28 use LevelDBEnv.TimeUntilSuccessFor.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Time Non-IDB LevelDBEnv slept before successfully completing this operation.
-    0 means success on the first try.
-  </summary>
-</histogram>
-
-<histogram name="LevelDBEnv.TimeUntilSuccessFor" units="ms" expires_after="M83">
-  <obsolete>
-    Removed in 2020-04.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    Time Non-IDB LevelDBEnv slept before successfully completing this operation.
-    0 means success on the first try, as LevelDBEnv only sleeps when retries are
-    needed.
-  </summary>
-</histogram>
-
-<histogram name="LibraryLoader.NativeLibraryHack" enum="BooleanUsage"
-    expires_after="2014-11-26">
-  <obsolete>
-    Removed as of 11/2014, removed from code.
-  </obsolete>
-  <owner>feng@chromium.org</owner>
-  <summary>
-    A boolean that indicates whether the workaround of a Sony framework bug was
-    used. The metric is Android-specific, and is logged when the browser starts.
-    See more details at http://crbug.com/311644.
-  </summary>
-</histogram>
-
-<histogram name="LibraryLoader.PrefetchDetailedStatus"
-    enum="LibraryLoaderPrefetchDetailedStatus" expires_after="2020-04-12">
-  <obsolete>
-    Removed 2019-10.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Detailed status of the library prefetch final status. This is an expanded
-    version of LibraryLoader.PrefetchStatus. Android only, recorded at most once
-    per browser startup.
-  </summary>
-</histogram>
-
-<histogram name="LibraryLoader.PrefetchStatus" enum="BooleanSuccess"
-    expires_after="2020-04-12">
-  <obsolete>
-    Removed 2019-10. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Indicates whether the forking of a child process to prefetch the native
-    library succeeded. Android only, recorded at most once per browser startup.
-  </summary>
-</histogram>
-
-<histogram name="Linux.Distro" enum="LinuxDistro" expires_after="2020-04-20">
-  <obsolete>
-    Deprecated 2020-04 in favor of Linux.Distro2 because distro-specific version
-    metrics were added.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <owner>thomasanderson@chromium.org</owner>
-  <summary>The Linux distro used. Logged on each start up.</summary>
-</histogram>
-
-<histogram name="Linux.X11.ServerRTT" units="microseconds" expires_after="M77">
-  <obsolete>
-    Removed 11/20 due to lack of usage.
-  </obsolete>
-  <owner>thomasanderson@chromium.org</owner>
-  <summary>
-    RTT between Chrome and the X11 server. Tracked in X11EventSource by
-    measuring the latency to receive a property event after changing a property.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="LoadingPredictor.SubresourceConnectDuration" units="ms"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Records the time measured before starting DNS lookup until after the
-    connection is complete for main frame subresources observed by the
-    LoadingPredictor. Only resources that required network connection and
-    happened before the first contentful paint are recorded.
-  </summary>
-</histogram>
-
-<histogram name="LocalDiscovery.ClientRestartAttempts" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Records number of attempts to start local discovery.</summary>
-</histogram>
-
-<histogram name="LocalDiscovery.DetectorRestartTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Time between detector restarts.</summary>
-</histogram>
-
-<histogram name="LocalDiscovery.DetectorTriggerTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Time before detector trigger notifications.</summary>
-</histogram>
-
-<histogram name="LocalDiscovery.DevicesPage" enum="DevicesPageEvents"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Records events related to devices page.</summary>
-</histogram>
-
-<histogram name="LocalDiscovery.FirewallAccessTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Windows only histogram that reports request time spend accessing firewall
-    rules. It's logged once per browser process lifetime, when local discovery
-    is used first time.
-  </summary>
-</histogram>
-
-<histogram name="LocalDiscovery.IsFirewallReady" enum="BooleanEnabled"
-    expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Windows only histogram that reports, whether a firewall is set, so we can
-    bind inbound sockets. It's logged once per browser process lifetime, when
-    local discovery is used first time.
-  </summary>
-</histogram>
-
-<histogram name="LocalDiscovery.PrivetNotificationsEvent"
-    enum="PrivetNotificationsEvent" expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Records events related to local discovery notifications.</summary>
-</histogram>
-
-<histogram name="LocalStorage.BrowserLocalStorageSizeInKB" units="KB"
-    expires_after="M77">
-  <obsolete>
-    No longer emitted after onion soup refactor.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Size of the HTML5 LocalStorage DB in KB in the browser-side cache.
-  </summary>
-</histogram>
-
-<histogram
-    name="LocalStorage.BrowserTimeToPrimeLocalStorage{LocalStorageSizes}"
-    units="units" expires_after="M77">
-  <obsolete>
-    No longer emitted after onion soup refactor.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Time to load HTML5 LocalStorage into the browser-side cache.
-    {LocalStorageSizes}
-  </summary>
-  <token key="LocalStorageSizes" variants="LocalStorageSizes"/>
-</histogram>
-
-<histogram name="LocalStorage.CommitDelay" units="ms" expires_after="M95">
-  <obsolete>
-    No longer emitted after onion soup refactor. Replaced with
-    LevelDBWrapper.CommitDelay.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Delay between a page making changes and those changes being written to the
-    DB.
-  </summary>
-</histogram>
-
-<histogram
-    name="LocalStorage.RendererTimeToPrimeLocalStorage{LocalStorageSizes}"
-    units="units" expires_after="M95">
-  <obsolete>
-    No longer omitted after onion soup refactor. Replaced by
-    LocalStorage.MojoTimeToPrime. {LocalStorageSizes}
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Time to load HTML5 LocalStorage into the renderer-side cache.
-  </summary>
-  <token key="LocalStorageSizes" variants="LocalStorageSizes"/>
-</histogram>
-
-<histogram name="LocalStorage.TimeToPrimeLocalStorage" units="units"
-    expires_after="M95">
-  <obsolete>
-    No longer omitted after onion soup refactor. Replaced by
-    LocalStorage.MojoTimeToPrime.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Time to load HTML5 LocalStorage into the renderer-side cache. Note that the
-    name is not 'Renderer' prefixed for continuity with the old naming.
-  </summary>
-</histogram>
-
-<histogram name="Login.DefaultPageZoom" units="%" expires_after="2020-03-01">
-  <obsolete>
-    Removed 01/2020. It was added to decide if the SplitSettings project could
-    safely decouple browser page zoom from ARC++/OS zoom. We decided it was safe
-    and did the decoupling in M78.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <owner>jessejames@chromium.org</owner>
-  <owner>cros-system-services@google.com</owner>
-  <summary>The user's default page zoom setting, recorded on login.</summary>
-</histogram>
-
-<histogram name="Login.ReauthReason" enum="LoginReauthReasons"
-    expires_after="2020-09-27">
-  <obsolete>
-    Removed in M85. Splitted in two: Login.PasswordChanged.ReauthReason and
-    Login.PasswordNotChanged.ReauthReason.
-  </obsolete>
-  <owner>achuith@chromium.org</owner>
-  <summary>
-    Tracks the reason why a user was sent through the GAIA re-auth flow.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MachineLearningService.ElapsedTimeMicrosec"
-    units="microseconds" expires_after="2020-02-01">
-  <obsolete>
-    Removed 2020-02-01 because elapsed time should be measured by clients, if
-    they need it.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="MachineLearningServiceRequests" -->
-
-  <owner>amoylan@chromium.org</owner>
-  <owner>alanlxl@chromium.org</owner>
-  <summary>Elapsed time of one Chrome OS ML Service request.</summary>
-</histogram>
-
-<histogram name="MachineLearningService.PeakPrivateMemoryKb" units="KB"
-    expires_after="2019-07-18">
-  <obsolete>
-    Removed 07/2019 because we change to record total (shared+unshared) memory
-    rather than only private memory. Replaced by
-    MachineLearningService.PeakTotalMemoryKb.
-  </obsolete>
-  <owner>alanlxl@chromium.org</owner>
-  <owner>amoylan@chromium.org</owner>
-  <summary>
-    Peak private (non-shared) memory used by Chrome OS ML Service over the last
-    24 hours. Sampled every 5 minutes, so may miss short-lived spikes.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MachineLearningService.PrivateMemoryDeltaKb"
-    units="KB" expires_after="2019-07-18">
-  <obsolete>
-    Removed 07/2019 because we change to record total (shared+unshared) memory
-    rather than only private memory. Replaced by
-    MachineLearningService.TotalMemoryDeltaKb.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="MachineLearningServiceRequests" -->
-
-  <owner>amoylan@chromium.org</owner>
-  <owner>alanlxl@chromium.org</owner>
-  <summary>
-    Memory usage increase caused by one Chrome OS ML Service request.
-  </summary>
-</histogram>
-
-<histogram name="MachineLearningService.PrivateMemoryKb" units="KB"
-    expires_after="2019-07-18">
-  <obsolete>
-    Removed 07/2019 because we change to record total (shared+unshared) memory
-    rather than only private memory. Replaced by
-    MachineLearningService.TotalMemoryKb.
-  </obsolete>
-  <owner>alanlxl@chromium.org</owner>
-  <owner>amoylan@chromium.org</owner>
-  <summary>
-    Private (non-shared) memory used by Chrome OS ML Service, sampled every 5
-    minutes.
-  </summary>
-</histogram>
-
-<histogram name="ManagedUsers.BlockedFrameDepth" units="depth"
-    expires_after="M85">
-  <obsolete>
-    Removed in M86.
-  </obsolete>
-  <owner>yilkal@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <owner>cros-families-eng@google.com</owner>
-  <summary>
-    The depth of blocked frame in the frame tree. The value is recorded when the
-    renderer frame hosting the blocking page finishes loading.
-  </summary>
-</histogram>
-
-<histogram name="ManagedUsers.ChromeOS.PasswordChange"
-    enum="ManagedUserPasswordChange" expires_after="M77">
-  <obsolete>
-    Removed 07/2020 as it is no longer used.
-  </obsolete>
-  <owner>achuith@chromium.org</owner>
-  <summary>
-    Chrome OS histogram that keeps track of supervised user password change
-    result.
-  </summary>
-</histogram>
-
-<histogram name="ManagedUsers.Whitelist.JsonParseDuration" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>escordeiro@chromium.org</owner>
-  <owner>menegola@chromium.org</owner>
-  <summary>
-    The total amount of time taken to parse the JSON contents of a whitelist out
-    of process.
-  </summary>
-</histogram>
-
-<histogram name="ManagedUsers.Whitelist.ReadDuration" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>escordeiro@chromium.org</owner>
-  <owner>menegola@chromium.org</owner>
-  <summary>
-    The amount of time taken to read a whitelist file from disk.
-  </summary>
-</histogram>
-
-<histogram name="ManagedUsers.Whitelist.TotalLoadDuration" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>escordeiro@chromium.org</owner>
-  <owner>menegola@chromium.org</owner>
-  <summary>
-    The total amount of time taken to load a whitelist from disk and parse it,
-    including jumps to the blocking thread.
-  </summary>
-</histogram>
-
-<histogram name="Manifest.IsEmpty" enum="Boolean" expires_after="2020-06-07">
-  <obsolete>
-    Removed as of 2019-10-21.
-  </obsolete>
-  <owner>mgiuca@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>Tracks whether the parsed Manifest is the empty Manifest.</summary>
-</histogram>
-
-<histogram name="Media.AcceleratedCompositingActive" enum="BooleanSuccess"
-    expires_after="2014-07-22">
-  <obsolete>
-    Removed as of July 21, 2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether accelerated compositing was used for HTML5 media rendering.
-  </summary>
-</histogram>
-
-<histogram name="Media.Android.IsHttpLiveStreamingMedia" enum="MediaUrlType"
-    expires_after="2017-08-21">
-  <obsolete>
-    Removed as of 08/2017
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records whether a regular media URL is HLS (HTTP Live Streaming)
-    media or not.
-  </summary>
-</histogram>
-
-<histogram name="Media.Android.IsHttpLiveStreamingMediaPredictionResult"
-    enum="MediaTypePredictionResult" expires_after="2017-08-21">
-  <obsolete>
-    Removed as of 08/2017
-  </obsolete>
-  <owner>sandersd@chromium.org</owner>
-  <summary>
-    Android: Records which HLS prediction based on the original URL was best.
-  </summary>
-</histogram>
-
-<histogram name="Media.Android.NumMediaServerCrashes" units="units"
-    expires_after="2017-04-12">
-  <obsolete>
-    Removed as of 04/2017
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Number of consecutive media server crashes monitored before it is
-    reset to 0. Reset happens if there are no crashes in a minute, or if user
-    hits the &quot;try again&quot; button on the media throttle info bar.
-  </summary>
-</histogram>
-
-<histogram name="Media.Android.ThrottleInfobarResponse"
-    enum="ThrottleInfobarResponse" expires_after="2017-04-12">
-  <obsolete>
-    Removed as of 04/2017
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: The distribution of responses to the media throttle infobar prompt.
-  </summary>
-</histogram>
-
-<histogram name="Media.ArcGpuVideoDecodeAccelerator.InitializeResult"
-    enum="ArcVideoDecodeAcceleratorResult" expires_after="2017-06-14">
-  <obsolete>
-    Removed as of June 12, 2017. Replaced by
-    Media.ChromeArcVideoDecodeAccelerator.InitializeResult.
-  </obsolete>
-  <owner>johnylin@chromium.org</owner>
-  <summary>
-    Counts of status values returned from calls to
-    ArcGpuVideoDecodeAccelerator::Initialize().
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.AutomaticGainControlMac" enum="BooleanEnabled"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Indicates if the Automatic Gain Control (AGC) is enabled or not. Only
-    sampled when Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Autoplay.Attribute.WaitTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records time from load starts until audio starts based on autoplay
-    attribute.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Autoplay.PlayMethod.WaitTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records time from load starts until audio starts based on play method.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Bitstream" enum="BooleanSupported"
-    expires_after="2019-07-31">
-  <obsolete>
-    Removed as of May 2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="BitstreamAudioFormats" -->
-
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records whether the given bitstream audio output format is supported.
-    Recorded when the browser or audio process AudioManager is constructed.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.CallbackError" enum="BooleanError"
-    expires_after="2017-02-03">
-  <obsolete>
-    Removed as of 02/2017.
-  </obsolete>
-  <owner>tommi@chromium.org</owner>
-  <summary>
-    A boolean that reflects whether or not an error was reported during audio
-    capture.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.DeviceLatency" units="ms"
-    expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The audio input device latency. The time from when a frame was captured
-    until it reaches Chrome's platform audio implementation. Sampled for every
-    buffer received from the device, and reports the latency for the first frame
-    in the buffer.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.StreamBrokerDisconnectReason"
-    enum="AudioInputStreamDisconnectReason" expires_after="2020-08-01">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>maxmorin@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Error codes from AudioInputStreamBroker::ObserverBindingLost. They describe
-    why an audio input stream ended.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.StreamCallbackError" enum="BooleanError"
-    expires_after="2018-06-07">
-  <obsolete>
-    Replaced by Media.Audio.Capture.StreamCallbackError2
-  </obsolete>
-  <owner>maxmorin@chromium.org</owner>
-  <summary>
-    When AudioInputDevice is stopped, this stat is recorded with whether an
-    error callback was ever received over IPC.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.ConcurrentGlitchAndDiscontinuities"
-    units="occurrences" expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The number of times a glitch was detected by detecting skipped frames (as
-    with Media.Audio.Capture.Glitches) and disconinuity was flagged by the OS at
-    the same time (as with Media.Audio.Capture.Win.Discontinuities). Sometimes
-    these indications are not consistent with each other so this metric helps
-    understanding how often they aren't. This value is logged when an audio
-    input stream is closed.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.DevicePeriod" units="ms"
-    expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The audio engine's period between processing passes. See
-    IAudioClient::GetDevicePeriod. This value is logged when an audio input
-    stream is opened.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.DevicePositionLessThanExpected"
-    units="occurrences" expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The number of times the device position was less than expected during the
-    lifetime of an audio stream. This value is logged when an audio input stream
-    is closed.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.Discontinuities"
-    units="discontinuities" expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The number of glitches that were detected at the OS level on Windows while
-    an audio stream was active, as reported by the OS via the discontinuity flag
-    (see IAudioCaptureClient::GetBuffer). This value is logged when an audio
-    input stream is closed.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.EndpointBufferSize" units="ms"
-    expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The endpoint buffer size for input audio. This value is logged when an audio
-    input stream is opened.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Capture.Win.StreamLatency" units="ms"
-    expires_after="2019-03-31">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The maximum stream latency as reported by the OS. See
-    IAudioClient::GetStreamLatency. This value is logged when an audio input
-    stream is opened.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputBufferSizeWasChangedAudioWorkedMac"
-    enum="BooleanChanged" expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Indicates if the size of the audio unit's IO buffer was changed when
-    starting an input audio stream. Sampled each time an AUAudioInputStream
-    instance is closed, i.e., we know that input audio has started as it should
-    when this value is stored. Can be compared with
-    Media.Audio.InputBufferSizeWasChangedMac which is only added when input
-    audio fails to start.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputDevicePropertyChangedMac"
-    enum="AudioDevicePropertyResult" expires_after="2018-02-07">
-  <obsolete>
-    Removed Feb 2018. Was put in place to debug missing callback issues that
-    have since been resolved.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Lists device properties that have been changed during an audio input stream
-    session. We update a map of different property changes during a session and
-    all these values are recorded when an AUAudioInputStream object is closed,
-    hence multiple enum values can be emitted when the histogram is stored.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputDevicePropertyChangedStartupFailedMac"
-    enum="AudioDevicePropertyResult" expires_after="2018-02-07">
-  <obsolete>
-    Removed Feb 2018. Was put in place to debug missing callback issues that
-    have since been resolved.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Lists device properties that have been changed during an audio input stream
-    session. Only sampled when Media.Audio.InputStartupSuccessMac reports
-    'Failure' and multiple enum values can be emitted each time that happens.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputRestartAttemptsMac" units="units"
-    expires_after="2017-05-24">
-  <obsolete>
-    Removed May 2017. Restart mechanism is removed.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Counts the total number of times an attempt to restart input audio has been
-    done. The value is stored once when a stream is closed and updated when it
-    has been detected that input audio callbacks are not generated as expected.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputStartWasDeferredAudioWorkedMac"
-    enum="BooleanDeferred" expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Indicates if audio capturing started with a small delay or not. Sampled each
-    time an AUAudioInputStream instance is closed, i.e., we know that input
-    audio has started as it should when this value is stored. Can be compared
-    with Media.Audio.InputStartWasDeferredMac which is only added when input
-    audio fails to start.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.InputStartWasDeferredMac" enum="BooleanDeferred"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Indicates if audio capturing started with a small delay or not. Only sampled
-    when Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.IsOnBatteryPowerMac" enum="BooleanOnBattery"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Indicates if the Mac OSX device is on battery power or not. Only sampled
-    when Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.NumberOfBasicInputStreamsMac" units="units"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Number of created default input audio streams. Only sampled when
-    Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.NumberOfLowLatencyInputStreamsMac" units="units"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Number of created low-latency input audio streams. Only sampled when
-    Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.NumberOfOutputStreamsMac" units="units"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Number of created output audio streams. Only sampled when
-    Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.OutputStreamsCanceledByBrowser" units="streams"
-    expires_after="2019-10-24">
-  <obsolete>
-    Removed as of October 2019.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <summary>
-    When a mojo audio stream factory is destructed, the streams it created are
-    also destructed. This is a potential source of stat differences between the
-    new mojo code and the old Chrome IPC code, where streams could potentially
-    stick around until the destruction of the owning RenderProcessHost. This
-    histogram measures how many output streams are destructed each time a mojo
-    output stream factory is destructed.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.AudioInputsPerMixer.LatencyExact"
-    units="inputs" expires_after="M85">
-  <obsolete>
-    Removed in June 2020.
-  </obsolete>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Number of simultaneous inputs coming to the AudioRendererMixer which renders
-    audio with user specified latency. The value is logged each time it reaches
-    a new maximum for the mixer. It is useful for evaluating how mixing audio in
-    renderer reduces the number of output audio streams going from the renderer
-    to the browser.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.AudioInputsPerMixer.LatencyInteractive"
-    units="inputs" expires_after="M85">
-  <obsolete>
-    Removed in June 2020.
-  </obsolete>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Number of simultaneous inputs coming to the AudioRendererMixer which renders
-    audio with interactive latency. The value is logged each time it reaches a
-    new maximum for the mixer. It is useful for evaluating how mixing audio in
-    renderer reduces the number of output audio streams going from the renderer
-    to the browser.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.AudioInputsPerMixer.LatencyPlayback"
-    units="inputs" expires_after="2020-04-05">
-  <obsolete>
-    Removed in June 2020.
-  </obsolete>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Number of simultaneous inputs coming to the AudioRendererMixer which renders
-    audio with playback latency. The value is logged each time it reaches a new
-    maximum for the mixer. It is useful for evaluating how mixing audio in
-    renderer reduces the number of output audio streams going from the renderer
-    to the browser.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.AudioInputsPerMixer.LatencyRtc"
-    units="inputs" expires_after="M85">
-  <obsolete>
-    Removed in June 2020.
-  </obsolete>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Number of simultaneous inputs coming to the AudioRendererMixer which renders
-    audio with real time latency. The value is logged each time it reaches a new
-    maximum for the mixer. It is useful for evaluating how mixing audio in
-    renderer reduces the number of output audio streams going from the renderer
-    to the browser.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.AudioMixing.LatencyMap" units="subsets"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Subset of audio output latencies encountered by the renderer so far. Logged
-    each time an audio output with a new latency starts playing. The values are
-    bitsets where each bit represents corresponding latency according to
-    AudioLatency::LatencyType. Useful for understanding usecases for audio
-    output mixing in renderer.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.BrowserCallbackRegularity" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Reflects how regularly browser issues audio requests to renderer. Depends on
-    how well the system buffer size the browser side renders audio at and the
-    buffer size it requests from renderer are aligned. When zero, it means
-    renderer buffer size is a multiple of system buffer size, and render calls
-    from browser to renderer are issued evenly. When -1, it means the renderer
-    buffer size is larger than system buffer size, but is not an exact multiple
-    of it; in this case browser periodically skips a call to renderer. When
-    positive, floor(value/2) reflects the number of extra consecutive render
-    requests issued by browser to renderer each time to fulfill the system audio
-    render request; if (value/2) is not integer, then plus one more extra call
-    is issued periodically. The metric is recorded on the edge between browser
-    and renderer. On Mac the system buffer size may vary dynamically, the metric
-    does not capture that: only the buffer size mismatch introduced by audio
-    output device configuration is captured.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.InputDeviceStartTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The time delta from an AudioInputDevice sending a RecordStream message to it
-    getting its first data callback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.InputDeviceStreamCreationTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The time delta between the moment a MojoAudioInputIPC instance on the
-    renderer process requests a new stream from the browser to the moment it
-    receives a response.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.OutputDeviceStartTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The time delta from an AudioOutputDevice sending its first PlayStream
-    message to it getting its first data callback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.OutputDeviceStreamCreationTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The time delta between the moment a MojoAudioOutputIPC instance on the
-    renderer process requests a new stream from the browser to the moment it
-    receives a response.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.StreamBrokerDisconnectReason"
-    enum="AudioOutputStreamDisconnectReason" expires_after="2019-08-01">
-  <obsolete>
-    Removed 09/2018, and replaced by
-    Media.Audio.Render.StreamBrokerDisconnectReason2.
-  </obsolete>
-  <owner>jonasolsson@chromium.org</owner>
-  <owner>maxmorin@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Error codes from AudioOutputStreamBroker::ObserverBindingLost. They describe
-    why an audio output stream ended.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.StreamBrokerDisconnectReason2"
-    enum="AudioOutputStreamDisconnectReason2" expires_after="2020-03-31">
-  <obsolete>
-    Removed on April 2020.
-  </obsolete>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Describes why and in which state an audio output stream ended.
-  </summary>
-</histogram>
-
-<histogram
-    name="Media.Audio.Render.StreamBrokerDocumentDestroyedAwaitingCreatedTime"
-    units="ms" expires_after="2020-03-31">
-  <obsolete>
-    Removed as of March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    If the document was destroyed after the broker requested the output stream
-    from the audio service, but before it received the reply: how long ago the
-    stream was requested.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.StreamBrokerStreamCreationTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed as of March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    Time interval between the moment the broker requested the output stream from
-    the audio service, and the moment it received the reply.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.Render.StreamCallbackError" enum="BooleanError"
-    expires_after="2018-06-07">
-  <obsolete>
-    Replaced by Media.Audio.Render.StreamCallbackError2
-  </obsolete>
-  <owner>maxmorin@chromium.org</owner>
-  <summary>
-    When AudioOutputDevice is stopped, this stat is recorded with whether an
-    error callback was ever received over IPC.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.ResumeEventsMac" units="units"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Counts the number of times the system has resumed from power suspension.
-    Counting is reset each time Chrome restarts. Only sampled when
-    Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.Audio.UptimeMac" units="hours"
-    expires_after="2018-08-22">
-  <obsolete>
-    Removed as of Aug 2018.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Reports the system uptime in hours for Mac OS X devices. Only sampled when
-    Media.Audio.InputStartupSuccessMac reports 'Failure'.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioCapturerRepetition" units="ms"
-    expires_after="2018-01-18">
-  <obsolete>
-    Removed as of Jan 2018.
-  </obsolete>
-  <owner>minyue@chromium.org</owner>
-  <summary>
-    Captures bit-exact audio repetitions with pre-defined look back time. As
-    soon as a repetition is detected, its look back time is reported. Ideally,
-    no reports should be generated.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioChannelLayout" enum="ChannelLayout"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975301.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Audio channel layout in HTML5 media.</summary>
-</histogram>
-
-<histogram name="Media.AudioInputControllerCaptureStartupSuccess"
-    enum="CaptureStartupResult" expires_after="2017-02-03">
-  <obsolete>
-    Removed as of 02/2017.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Whether capture started successfully after an input stream startup was
-    requested.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioInputDeviceManager" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 06/2020. No longer needed.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Measures the time taken for AudioInputDeviceManager::</summary>
-</histogram>
-
-<histogram name="Media.AudioOutputController" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 06/2020. No longer needed.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Measures the time taken for AudioOutputController::</summary>
-</histogram>
-
-<histogram name="Media.AudioRendererEvents" enum="AudioRendererEvents"
-    expires_after="2016-03-18">
-  <obsolete>
-    Removed Mar 2016 in favor of a new PipelineStatus code.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>Captures statistics for various AudioRendererImpl events.</summary>
-</histogram>
-
-<histogram name="Media.AudioRendererIpcStreams" units="units"
-    expires_after="2017-02-08">
-  <obsolete>
-    Removed 02/2017. No longer needed.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The maximum number of simultaneous audio render streams over IPC created in
-    AudioRendererHost for a render process. Logged at render process shutdown.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioRendererIpcStreamsTotal" units="units"
-    expires_after="2017-02-08">
-  <obsolete>
-    Removed 02/2017. No longer needed.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    The maximum number of simultaneous audio render streams over IPC created in
-    AudioRendererHost for all render processes. Logged at render process
-    shutdown.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioSampleFormat" enum="AudioSampleFormat"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975301.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Audio sample format in HTML5 media. Logged when Audio Decoder initializes.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioSamplesPerSecond" enum="AudioSampleRate"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019 in issue 975301.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Audio samples per second in HTML5 media.</summary>
-</histogram>
-
-<histogram name="Media.AudioSamplesPerSecondUnexpected" units="Hz"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975301.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Audio samples per second in HTML5 media (atypical values, in Hz).
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedDowntime" units="ms"
-    expires_after="2018-06-09">
-  <obsolete>
-    Removed 06/2018. Split into Media.AudioService.ObservedInitialDowntime and
-    Media.AudioService.ObservedDowntime2.
-  </obsolete>
-  <owner>marinaciocea@chromium.org</owner>
-  <owner>maxmorin@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The audio service downtime, observed from the browser process. The downtime
-    interval is measured either from when the audio service listener is
-    initialized to the first audio service start, or from the audio service
-    shutdown to the next startup.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedDowntime2" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The audio service downtime, observed from the browser process. The downtime
-    interval is measured from the audio service shutdown to the next startup.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedInitialDowntime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The audio service downtime, observed from the browser process. The downtime
-    interval is measured from when the audio service listener is initialized to
-    the first audio service start.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedProcessTerminationStatus"
-    enum="AudioServiceProcessTerminationStatus" expires_after="2018-10-19">
-  <obsolete>
-    Removed 10/2018. Covered by the more generic stats
-    ChildProcess.Crashed.UtilityProcessHash and
-    ChildProcess.Launched.UtilityProcessHash.
-  </obsolete>
-  <owner>marinaciocea@chromium.org</owner>
-  <owner>maxmorin@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The termination status of the audio service process, observed from the
-    browser process.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedStartStatus"
-    enum="AudioServiceStartStatus" expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The start result of the audio service, observed from the browser process.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedStartupTime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The startup time of the audio service, observed from the browser process.
-    The startup time interval is measured from when a connect request results in
-    the audio service being created to the moment when the audio service is
-    started.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.ObservedUptime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The uptime of the audio service, observed from the browser process. The
-    uptime interval is measured from when the audio service starts to when it is
-    shut down (either normally or through kill/crash). This metric includes
-    Media.AudioService.Uptime measurements, logged by the audio service on
-    normal shutdown. A difference between Media.AudioService.ObservedUptime and
-    Media.AudioService.Uptime indicates buggy audio service behavior.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.SystemInfoClient" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="AudioSystemInfoRequest" -->
-
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The time interval between the moment when a client issues a system
-    information request to the audio service, and the moment it receives the
-    responce. Logged individually for each request type.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioService.Uptime" units="ms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on March 2020.
-  </obsolete>
-  <owner>armax@chromium.org</owner>
-  <owner>guidou@chromium.org</owner>
-  <owner>olka@chromium.org</owner>
-  <summary>
-    The uptime of the audio service, observed from the audio service. The uptime
-    interval is measured from the audio service start to the audio service stop.
-  </summary>
-</histogram>
-
-<histogram name="Media.AudioTrackProcessingStates"
-    enum="AudioTrackProcessingStates" expires_after="M77">
-  <obsolete>
-    Removed July 2019. No longer needed.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    State of the media stream audio track processing, sampled once during the
-    life time of a MediaStreamAudioProcessor.
-  </summary>
-</histogram>
-
-<histogram name="Media.Autoplay.CrossOrigin.Result"
-    enum="CrossOriginAutoplayResult" expires_after="2019-01-25">
-  <obsolete>
-    Removed January 2019. No longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The result of autoplaying video elements in cross-origin iframes.
-  </summary>
-</histogram>
-
-<histogram name="Media.AVDA.InputQueueTime" units="ms"
-    expires_after="2016-03-31">
-  <obsolete>
-    Removed 03/2016. No longer needed.
-  </obsolete>
-  <owner>watk@chromium.org</owner>
-  <summary>
-    The time that a bitstream buffer spends in AVDA's pending bitstream buffer
-    queue before it is fed to MediaCodec.
-  </summary>
-</histogram>
-
-<histogram name="Media.AVDA.MissingFormatChanged" enum="BooleanFormatChanged"
-    expires_after="2016-10-21">
-  <obsolete>
-    Removed 10/2016. No longer needed.
-  </obsolete>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Number of times that AVDA stopped decoding because MediaCodec failed to
-    provide a FORMAT_CHANGED message before sending decoded frames back. True
-    counts indicate instances where FORMAT_CHANGE was missed, while false
-    instances indicate any MediaCodec initialization by AVDA.
-  </summary>
-</histogram>
-
-<histogram name="Media.AVDA.NumAVDAInstances" units="AVDA instances"
-    expires_after="2016-10-21">
-  <obsolete>
-    Removed 10/2016. No longer needed.
-  </obsolete>
-  <owner>watk@chromium.org</owner>
-  <summary>
-    The number of concurrently running AndroidVideoDecodeAccelerators. Logged
-    during each AVDA initialization.
-  </summary>
-</histogram>
-
-<histogram name="Media.AVDA.VirtualContext" enum="BooleanVirtualContext"
-    expires_after="2016-10-21">
-  <obsolete>
-    Removed 10/2016. No longer needed.
-  </obsolete>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Number of times that AVDA's deferred rendering encountered a virtual GL
-    context. True counts indicate virtual, false counts indicate not.
-  </summary>
-</histogram>
-
-<histogram name="Media.AvdaCodecImage.WaitTimeForFrame" units="ms"
-    expires_after="2018-06-14">
-  <obsolete>
-    Removed 06/2018. This has been renamed to
-    Media.CodecImage.SurfaceTextureGLOwner.WaitTimeForFrame and
-    Media.CodecImage.ImageReaderGLOwner.WaitTimeForFrame.
-  </obsolete>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Time spent waiting for a frame to become available in a Non Overlay after
-    requesting that MediaCodec renders it.
-  </summary>
-</histogram>
-
-<histogram name="Media.BytesReadFromCache" units="KB" expires_after="M82">
-  <obsolete>
-    Removed 10/2019 in issue 1000058; no longer needed.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>Kb read by media demuxer from MultiBuffer cache.</summary>
-</histogram>
-
-<histogram name="Media.BytesReadFromNetwork" units="KB"
-    expires_after="2020-06-07">
-  <obsolete>
-    Removed 10/2019 in issue 1000058; no longer needed.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>Kb read by from network into MultiBuffer cache.</summary>
-</histogram>
-
-<histogram base="true" name="Media.BytesReceived" units="KB"
-    expires_after="2019-10-15">
-  <obsolete>
-    Removed 10/2019 in issue 1000058; no longer needed.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Total number of bytes buffered over the lifetime of a WebMediaPlayer,
-    suffixed by type of playback.
-  </summary>
-</histogram>
-
-<histogram name="Media.CacheUseful" enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975278.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Whether a media response might be used to satisfy a future request.
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeArcVideoDecodeAccelerator.InitializeResult"
-    enum="ArcVideoDecodeAcceleratorResult" expires_after="2017-12-19">
-  <obsolete>
-    Removed as of Dec 18, 2017. Replaced by
-    Media.GpuArcVideoDecodeAccelerator.InitializeResult.
-  </obsolete>
-  <owner>johnylin@chromium.org</owner>
-  <summary>
-    Counts of status values returned from calls to
-    ChromeArcVideoDecodeAccelerator::Initialize().
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeCast.DelayedAndDroppedFramesPer5Sec"
-    units="frames/5s" expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    The average number of delayed and dropped frames for the ChromeCast
-    application. Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeCast.DisplayedFramesPerSecond" units="frames/s"
-    expires_after="2015-07-15">
-  <obsolete>
-    Removed 07/2015 in issue 508534.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    The average number of displayed frames for the ChromeCast application.
-    Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeCast.TimeToBufferAv" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Time needed to pre-buffer A/V data before the actual playback for the
-    ChromeCast application.
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeCast.TimeToBufferAvAfterAbort" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Time needed to buffer A/V data after an abort for the ChromeCast
-    application.
-  </summary>
-</histogram>
-
-<histogram name="Media.ChromeCast.TimeToBufferAvAfterUnderrun" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Not collected as of M83.
-  </obsolete>
-  <owner>mfoltz@chromium.org</owner>
-  <summary>
-    Time needed to buffer A/V data after an underrun for the ChromeCast
-    application.
-  </summary>
-</histogram>
-
-<histogram name="Media.CodecImage.ImageReaderGLOwner.FrameTimedOut"
-    enum="BooleanTimedOut" expires_after="M76">
-  <obsolete>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.FrameTimedOut
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.FrameTimedOut
-  </summary>
-</histogram>
-
-<histogram name="Media.CodecImage.ImageReaderGLOwner.WaitTimeForFrame"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.WaitTimeForFrame
-  </obsolete>
-  <owner>vikassoni@chromium.org</owner>
-  <summary>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.WaitTimeForFrame
-  </summary>
-</histogram>
-
-<histogram name="Media.CodecImage.SurfaceTextureGLOwner.FrameTimedOut"
-    enum="BooleanTimedOut" expires_after="M76">
-  <obsolete>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.FrameTimedOut
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.FrameTimedOut
-  </summary>
-</histogram>
-
-<histogram name="Media.CodecImage.SurfaceTextureGLOwner.WaitTimeForFrame"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.WaitTimeForFrame
-  </obsolete>
-  <owner>liberato@chromium.org</owner>
-  <summary>
-    Removed 07/2019. This has been renamed to
-    Media.CodecImage.CodecBufferWaitCoordinator.WaitTimeForFrame
-  </summary>
-</histogram>
-
-<histogram name="Media.Controls.Download" enum="MediaControlsDownloadReason"
-    expires_after="2017-07-14">
-  <obsolete>
-    Removed July 2017 in favor of Media.Controls.CTR.DownloadButton.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records events and user interactions related to the download button shown on
-    media elements.
-  </summary>
-</histogram>
-
-<histogram name="Media.Controls.Overflow.TimeToAction" units="seconds"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the amount of time the overflow menu is displayed until the user
-    clicked on a menu item. The overflow menu is shown by clicking the three
-    dots on the media controls and is used to show more controls when there is
-    not enough space. This histogram will record up to 100 seconds with accuracy
-    to the second.
-  </summary>
-</histogram>
-
-<histogram name="Media.Controls.Overflow.TimeToDismiss" units="seconds"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the amount of time the overflow menu is displayed until the user
-    dismissed the menu without clicking on a menu item. The overflow menu is
-    shown by clicking the three dots on the media controls and is used to show
-    more controls when there is not enough space. This histogram will record up
-    to 100 seconds with accuracy to the second.
-  </summary>
-</histogram>
-
-<histogram name="Media.Controls.Show" enum="MediaControlsShowReason"
-    expires_after="2016-05-24">
-  <obsolete>
-    Removed May 19 2016 in favor of Media.Controls.Show.{Audio,Video}
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Record whether the default media controls were shown and why every time they
-    could be shown.
-  </summary>
-</histogram>
-
-<histogram name="Media.DetectedAudioCodec" enum="FFmpegCodecs"
-    expires_after="2015-09-17">
-  <obsolete>
-    Removed Sep 15 2015 in favor of Media.DetectedAudioCodecHash
-  </obsolete>
-  <owner>jrummell@chromium.org</owner>
-  <summary>Audio codec used in HTML5 media.</summary>
-</histogram>
-
-<histogram name="Media.DetectedTrackCount.Audio" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in issue 975315.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected audio tracks in HTML5 media. Not all may be usable by the
-    player.
-  </summary>
-</histogram>
-
-<histogram name="Media.DetectedTrackCount.Text" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in issue 975315.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected text tracks in HTML5 media. Not all may be usable by the
-    player.
-  </summary>
-</histogram>
-
-<histogram name="Media.DetectedTrackCount.Video" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in issue 975315.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected video tracks in HTML5 media. Not all may be usable by the
-    player.
-  </summary>
-</histogram>
-
-<histogram name="Media.DetectedVideoCodec" enum="FFmpegCodecs"
-    expires_after="2015-09-17">
-  <obsolete>
-    Removed Sep 15 2015 in favor of Media.DetectedVideoCodecHash
-  </obsolete>
-  <owner>jrummell@chromium.org</owner>
-  <summary>Video codec used in HTML5 media.</summary>
-</histogram>
-
-<histogram name="Media.DevicePermissionActions" enum="DevicePermissionActions"
-    expires_after="2015-11-09">
-  <obsolete>
-    Removed 10/2015 in favor of Permissions.Action.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the actions taken in the media infobar, which prompts the users for
-    device permission.
-  </summary>
-</histogram>
-
-<histogram name="Media.Duration" units="ms" expires_after="2017-03-04">
-  <obsolete>
-    Removed 03/2017 in favor of Media.Duration2 with larger max bucket.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>Duration in milliseconds of HTML5 media (when known).</summary>
-</histogram>
-
-<histogram name="Media.Duration2" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 06/2019. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Duration in milliseconds of HTML5 media (when known).</summary>
-</histogram>
-
-<histogram name="Media.DXVAVDA.CreateDecoderStatus" enum="BooleanSuccess"
-    expires_after="M73">
-  <obsolete>
-    Removed 12/2018 since we had enough data to make a decision.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Did IsResolutionSupportedForDevice() succeed or fail during
-    ID3D11VideoDevice::CreateVideoDecoder().
-  </summary>
-</histogram>
-
-<histogram name="Media.DXVAVDA.ErrorLine" units="units" expires_after="M82">
-  <obsolete>
-    Removed 02/2020. Not useful.
-  </obsolete>
-  <owner>liberato@chromium.org</owner>
-  <owner>sandersd@chromium.org</owner>
-  <summary>
-    Whenever an error is logged from the DXVAVDA, this records the line in
-    dxva_video_decode_accelerator.cc where the failure occurred.
-  </summary>
-</histogram>
-
-<histogram name="Media.DXVAVDA.GetDecoderConfigStatus" enum="BooleanSuccess"
-    expires_after="M73">
-  <obsolete>
-    Removed 12/2018 since we had enough data to make a decision.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Did IsResolutionSupportedForDevice() succeed or fail during
-    ID3D11VideoDevice::GetVideoDecoderConfig().
-  </summary>
-</histogram>
-
-<histogram name="Media.DXVAVDA.PictureBufferErrorLine" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 02/2020. Not useful.
-  </obsolete>
-  <owner>jbauman@chromium.org</owner>
-  <owner>sandersd@chromium.org</owner>
-  <summary>
-    Whenever an error is logged from the DXVAVDA picture buffer code, this
-    records the line in dxva_picture_buffer_win.cc where the failure occurred.
-    This histogram can only meaningfully be compared between different versions
-    of Chromium if no line numbers in that file changed between those versions.
-  </summary>
-</histogram>
-
-<histogram name="Media.EME.CdmFileIO.ReadTime" units="ms" expires_after="M84">
-  <obsolete>
-    Removed 08/2019, replaced with Media.EME.CdmFileIO.TimeTo.ReadFile.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The actual time spent by the CDM reading a file.</summary>
-</histogram>
-
-<histogram name="Media.EME.CdmFileIO.WriteTime" units="ms" expires_after="M84">
-  <obsolete>
-    Removed 08/2019, replaced with Media.EME.CdmFileIO.TimeTo.WriteFile.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The actual time spent by the CDM writing a file.</summary>
-</histogram>
-
-<histogram name="Media.EME.KeySystemSupport.Widevine"
-    enum="MediaKeySystemSupportStatus" expires_after="2016-02-22">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Key system support query status and result. Each enum value will be reported
-    at most once per renderer process.
-  </summary>
-</histogram>
-
-<histogram name="Media.EME.NeedKey" units="units" expires_after="2017-10-21">
-  <obsolete>
-    Renamed to Media.EME.EncryptedEvent in 10/2017.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>EME NeedKey event count.</summary>
-</histogram>
-
-<histogram name="Media.EME.{KeySystem}.addKey" enum="MediaKeyException"
-    expires_after="2018-01-04">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>addKey result</summary>
-  <token key="KeySystem" variants="KeySystem"/>
-</histogram>
-
-<histogram name="Media.EME.{KeySystem}.cancelKeyRequest"
-    enum="MediaKeyException" expires_after="2018-01-04">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <summary>cancelKeyRequest result.</summary>
-  <token key="KeySystem" variants="KeySystem"/>
-</histogram>
-
-<histogram name="Media.EME.{KeySystem}.generateKeyRequest"
-    enum="MediaKeyException" expires_after="2018-01-04">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>generateKeyRequest result.</summary>
-  <token key="KeySystem" variants="KeySystem"/>
-</histogram>
-
-<histogram name="Media.EME.{KeySystem}.KeyAdded" units="units"
-    expires_after="2018-01-04">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>KeyAdded event count.</summary>
-  <token key="KeySystem" variants="KeySystem"/>
-</histogram>
-
-<histogram name="Media.EME.{KeySystem}.KeyError" enum="MediaKeyError"
-    expires_after="2018-01-04">
-  <obsolete>
-    Removed 02/2016 with removal of prefixed EME.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>KeyError event count.</summary>
-  <token key="KeySystem" variants="KeySystem"/>
-</histogram>
-
-<histogram name="Media.Engagement.Clear" enum="MediaEngagementClearReason"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the reason why the Media Engagement data was cleared. Partial
-    changes and full wipeout will both be recorded as one event.
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.PreloadedList.LoadTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Time taken to load the Media Engagement Preloaded List. It should be
-    recorded once per load of the list which will be once per start up with
-    additional loads when the list is updated while running.
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.PreloadedList.LookupTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Time taken to lookup an entry in the Media Engagement Preloaded List. This
-    is recorded for every lookup, regardless of its success.
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.ScoreAtStartup" units="%"
-    expires_after="2018-11-13">
-  <obsolete>
-    Removed 11/2018 in Issue 900679 as we are no longer using this.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Media engagement scores for each origin, recorded at Chrome startup. It is
-    converted to a percentage so should be divided by 100 to get the actual
-    score.
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.Session" enum="MediaEngagementSessionEvent"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records creation and playback status of a Media Engagement Session. This is
-    recorded at the same time as the data is commited into the content settings
-    database.
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.Session.Restored"
-    enum="MediaEngagementSessionEvent" expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records creation and playback status of a restored Media Engagement Session.
-    This is recorded at the same time as the data is commited into the content
-    settings database. Restored information are recorded in addition of regular
-    ones (Media.Engagement.Session).
-  </summary>
-</histogram>
-
-<histogram name="Media.Engagement.URLsDeletedScoreReduction" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 as no longer needed.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Recorded when the history is cleared and the media engagement data are
-    similarly cleared. It records the reduction in score for each affected
-    origin. The algorithm is made to reduce the score by 0.0 as much as possible
-    and if it fails, the score will actually become 0.0 so every reduction also
-    represent the value of the previous score.
-  </summary>
-</histogram>
-
-<histogram name="Media.FallbackHardwareAudioBitsPerChannel" units="units"
-    expires_after="2018-05-04">
-  <obsolete>
-    Removed May 2018; has been 32-bit for years now.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Bits per channel of the hardware audio device which failed to open in low
-    latency mode and required high latency fallback.
-  </summary>
-</histogram>
-
-<histogram name="Media.FallbackHardwareAudioChannelCount" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975072. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Channel count of the hardware audio device which failed to open in low
-    latency mode and required high latency fallback.
-  </summary>
-</histogram>
-
-<histogram name="Media.FallbackHardwareAudioChannelLayout" enum="ChannelLayout"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975072. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Channel layout of the hardware audio device which failed to open in low
-    latency mode and required high latency fallback.
-  </summary>
-</histogram>
-
-<histogram name="Media.FallbackHardwareAudioSamplesPerSecond"
-    enum="AudioSampleRate" expires_after="M80">
-  <obsolete>
-    Removed 06/2019 in issue 975072. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Samples per second of the hardware audio device which failed to open in low
-    latency mode and required high latency fallback.
-  </summary>
-</histogram>
-
-<histogram name="Media.FallbackHardwareAudioSamplesPerSecondUnexpected"
-    units="Hz" expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975072. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Samples per second of the hardware audio device (atypical values, in Hz)
-    which failed to open in low latency mode and required high latency fallback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Fling.DelayedAndDroppedFramesPer5Sec" units="frames/5s"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average number of delayed and dropped frames for the Fling application.
-    Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.Fling.DisplayedFramesPerSecond" units="frames/s"
-    expires_after="2015-07-15">
-  <obsolete>
-    Removed 07/2015 in issue 508534.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    The average number of displayed frames for the Fling application. Reported
-    every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.Fling.TimeToBufferAv" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time needed to pre-buffer A/V data before the actual playback for the Fling
-    application.
-  </summary>
-</histogram>
-
-<histogram name="Media.Fling.TimeToBufferAvAfterAbort" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time needed to buffer A/V data after an abort for the Fling application.
-  </summary>
-</histogram>
-
-<histogram name="Media.Fling.TimeToBufferAvAfterUnderrun" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time needed to buffer A/V data after an underrun for the Fling application.
-  </summary>
-</histogram>
-
-<histogram name="Media.GpuVideoDecoderError" enum="VideoDecodeAcceleratorError"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed in December 2019 because GpuVideoDecoderError is gone and
-    crbug.com/902968 is fixed.
-  </obsolete>
-  <owner>sandersd@chromium.org</owner>
-  <summary>Counts of video decode errors reported to GpuVideoDecoder.</summary>
-</histogram>
-
-<histogram name="Media.GpuVideoDecoderInitializeStatus" enum="PipelineStatus"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed in December 2019 because GpuVideoDecoderError is gone and
-    crbug.com/902968 is fixed.
-  </obsolete>
-  <owner>posciak@chromium.org</owner>
-  <summary>Results of attempts to GpuVideoDecoder::Initialize().</summary>
-</histogram>
-
-<histogram name="Media.HardwareAudioBitsPerChannel" units="units"
-    expires_after="2018-05-04">
-  <obsolete>
-    Removed May 2018; has been 32-bit for years now.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Bits per channel of the hardware audio device.</summary>
-</histogram>
-
-<histogram name="Media.HardwareAudioSamplesPerSecondUnexpected" units="Hz"
-    expires_after="M80">
-  <obsolete>
-    Removed 06/2019 in issue 975072. Not useful.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Samples per second of the hardware audio device (atypical values, in Hz).
-  </summary>
-</histogram>
-
-<histogram name="Media.InfoLoadDelay" units="ms" expires_after="2017-06-26">
-  <obsolete>
-    Removed June 2017. Found that the MediaInfoLoader class (the only user of
-    this histogram) is no longer used by anyone.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    The time it takes to perform redirect tracking and a CORS access check while
-    preparing to play a media file.
-  </summary>
-</histogram>
-
-<histogram name="Media.Initialize.Windows" enum="WinGetLastError"
-    expires_after="2015-06-08">
-  <obsolete>
-    Removed 05/2015 in Issue 1141703002. FFmpeg is now statically linked.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>
-    Errors returned by LoadLibraryEx on Windows while attempting to load
-    ffmpegsumo.dll.
-  </summary>
-</histogram>
-
-<histogram name="Media.InputInvalidSampleRateMac" units="Hz"
-    expires_after="2016-02-11">
-  <obsolete>
-    Removed and removed from code as of 02/2016.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Invalid input sample rate when calling AUAudioInputStream::Open on Mac.
-  </summary>
-</histogram>
-
-<histogram name="Media.IsStreaming" enum="Boolean" expires_after="2020-06-03">
-  <obsolete>
-    Removed from code on 05/2020.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>sandersd@chromium.org</owner>
-  <summary>
-    Whether the WMPI data source is streaming (does not support range requests).
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Media.Learning.MediaCapabilities.DroppedFrameRatioTask"
-    enum="ConfusionMatrix" expires_after="2019-06-30">
-  <obsolete>
-    Removed in favor of Media.Learning.BinaryThreshold.Aggregate.*
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="MediaLearningDroppedFrameRatioTask" -->
-
-  <owner>liberato@chromium.org</owner>
-  <owner>chcunningham@chromium.org</owner>
-  <summary>
-    Confusion matrix for MediaCapabilities local learning experiment, using a
-    lookup table and the base MediaCapabilities features (resolution, frame
-    rate, video format). A positive outcome is smooth playback, while a negative
-    outcome is not smooth. For example, a False Negative indicates that we
-    predicted a negative result (not smooth playback), but we later observed
-    that the result was positive (smooth playback).
-
-    For those observations for which we could not make a prediction due to data
-    sparsity, the &quot;no-prediction&quot; buckets indicate whether the
-    observation was positive or negative.
-
-    This is very similar to the existing MediaCapabilities implementation, but
-    uses the same training set as other learners.
-
-    The &quot;BaseTable&quot; variant uses a lookup table as the model, and uses
-    the original MediaCapabilities features (resolution, frame rate, video
-    format).
-
-    The &quot;BaseTree&quot; variant uses ExtraTrees model and the same features
-    as the BaseTable variant.
-
-    The &quot;EnhancedTree&quot; variant uses ExtraTrees, plus additional
-    features such as NetworkType. The exact set of features is still in flux, so
-    be sure to restrict reporting to a particular Chromium version.
-  </summary>
-</histogram>
-
-<histogram name="Media.MediaElement.PlaybackPositionIsInfinity"
-    enum="BooleanInfinity" expires_after="2019-01-11">
-  <obsolete>
-    Removed and removed from code as of January 2019.
-  </obsolete>
-  <owner>ossu@chromium.org</owner>
-  <owner>grunell@chromium.org</owner>
-  <summary>
-    Whether or not the MediaElement is at a playback position of infinity when
-    checking if playback has ended.
-  </summary>
-</histogram>
-
-<histogram name="Media.MicrophoneVolume" units="%" expires_after="2018-08-22">
-  <obsolete>
-    Removed 08/2018. Histogram Eraser marked this histogram as unnecessary. See
-    https://crbug.com/871467 for details.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Level of the microphone volume measured in percent. This value can be larger
-    than 100% on Linux. Measured approximately four times per minute.
-  </summary>
-</histogram>
-
-<histogram name="Media.Midi.InputPorts" units="devices" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>midi-dev@chromium.org</owner>
-  <summary>Connected input port numbers on the initialization.</summary>
-</histogram>
-
-<histogram name="Media.Midi.OutputPorts" units="devices" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>midi-dev@chromium.org</owner>
-  <summary>Connected output port numbers on the initialization.</summary>
-</histogram>
-
-<histogram name="Media.Midi.ResultOnShutdown" enum="MidiResult"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>midi-dev@chromium.org</owner>
-  <summary>
-    The final status of MidiManager on destruction. This can monitor unexpected
-    failures on initializing platform dependent MIDI stuff.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.AudioSpliceDurationType"
-    enum="StreamParserBufferDurationType" expires_after="2018-05-25">
-  <obsolete>
-    Removed 05/2018. Splicing no longer performed on buffers with estimated
-    duration. See https://crbug.com/396634.
-  </obsolete>
-  <owner>chcunningham@chromium.org</owner>
-  <summary>
-    Categorizes MSE audio splicing by the type of duration used in the
-    overlapped buffer.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.DetectedTrackCount.Audio" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975090.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected audio tracks in Media Source Extensions playback. Not all
-    may be usable by the player.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.DetectedTrackCount.Text" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975090.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected text tracks in Media Source Extensions playback. Not all
-    may be usable by the player. This count includes only explicitly signalled
-    tracks in MSE initialization segments parsed from WebM or ISO BMFF
-    bytestreams.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.DetectedTrackCount.Video" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975090.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of detected video tracks in Media Source Extensions playback. Not all
-    may be usable by the player.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.LateAudioFrames"
-    units="late frames per million frames" expires_after="2016-10-03">
-  <obsolete>
-    Deleted along with browser side MSE implementation.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>timav@chromium.org</owner>
-  <summary>
-    Relative number of late audio frames wrt total number of audio frames in MSE
-    playback, multiplied by one million. The audio frame is considered late if
-    it might cause an underrun, i.e. comes from decoder when audio buffer is
-    already depleted.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.LateVideoFrames"
-    units="late frames per million frames" expires_after="2016-10-03">
-  <obsolete>
-    Deleted along with browser side MSE implementation.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>timav@chromium.org</owner>
-  <summary>
-    Relative number of late video frames wrt total number of video frames in MSE
-    playback, multiplied by one million. The video frame is late if it missed
-    its presentation time as determined by PTS when it comes from decoder. The
-    rendering policy (i.e. render or skip) does not affect it.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.NumberOfTracks" units="units"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975898.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Number of tracks specified to AddId() for Media Source Extensions playback.
-    May be called multiple times per element if playback is dynamically altered.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.Playback" enum="BooleanSuccess"
-    expires_after="2015-08-06">
-  <obsolete>
-    Renamed to Media.LoadType.
-  </obsolete>
-  <owner>acolwell@chromium.org</owner>
-  <summary>
-    Whether Media Source Extensions is specified for playback of Media elements.
-    Sampled when media pipeline starts.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.PlaybackDuration" units="ms"
-    expires_after="2016-10-03">
-  <obsolete>
-    Deleted along with browser side MSE implementation.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>timav@chromium.org</owner>
-  <summary>
-    Duration of an uninterrupted MSE playback. This is the time interval between
-    the playback starts or resumes and the moment when user stops the playback
-    by pressing pause, initiating a seek etc. Measured in media time in
-    milliseconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.MSE.Starvations" units="starvations per million frames"
-    expires_after="2016-10-03">
-  <obsolete>
-    Deleted along with browser side MSE implementation.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>timav@chromium.org</owner>
-  <summary>
-    Relative number of starvations wrt total number of frames in MSE playback,
-    multiplied by one million. Starvation happens when the player interrupts the
-    regular playback and asks for more data, conditions are player-specific.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.AudioBitrate" units="kbps"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The audio bit rate as reported by the Netflix application. May be reported
-    multiple times as network conditions change during playback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.AudioNumChannels" units="channels"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of audio channels as reported by the Netflix application. May be
-    reported multiple times as network conditions change during playback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.DelayedAndDroppedFramesPer5Sec"
-    units="frames/5s" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average number of delayed and dropped frames for the Netflix
-    application. Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.DisplayedFramesPerSecond" units="frames/s"
-    expires_after="2015-07-15">
-  <obsolete>
-    Removed 07/2015 in issue 508534.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    The average number of displayed frames for the Netflix application. Reported
-    every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.VideoBitrate" units="kbps"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Video bit rate as reported by the Netflix application. May be reported
-    multiple times as network conditions change during playback.
-  </summary>
-</histogram>
-
-<histogram name="Media.Netflix.VideoHeight" units="pixels"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Video height as reported by the Netflix application. May be reported
-    multiple times as network conditions change during playback.
-  </summary>
-</histogram>
-
-<histogram name="Media.PlayMovies.DelayedAndDroppedFramesPer5Sec"
-    units="frames/5s" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average number of delayed and dropped frames for the PlayMovies
-    application. Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.PlayMovies.DisplayedFramesPerSecond" units="frames/s"
-    expires_after="2015-07-15">
-  <obsolete>
-    Removed 07/2015 in issue 508534.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    The average number of displayed frames for the PlayMovies application.
-    Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.PreloadMetadataSuspendWasIdeal" enum="Boolean"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053019.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Indicates if a suspend initiated for preload=metadata was ideal. I.e. we did
-    not immediately resume after completing the suspend when signaling
-    ReadyState::HAVE_FUTURE_DATA.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.CapacityOverMediaBitrate" units="kbps"
-    expires_after="2017-11-29">
-  <obsolete>
-    Removed 11/2017 in issue 788940.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    The difference between the estimated transmission capacity and the media
-    bitrate when capacity is higher.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.MediaBitrateOverCapacity" units="kbps"
-    expires_after="2017-11-29">
-  <obsolete>
-    Removed 11/2017 in issue 788940.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    The difference between the media bitrate and the estimated transmission
-    capacity when media bitrate is higher.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.PosterDownloadDuration.Fail" units="ms"
-    expires_after="2017-08-02">
-  <obsolete>
-    Removed as no more poster image is being downloaded while remoting content.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    Measures the amount of time it took to ultimately fail to download a poster
-    image for an HTML5 video while remoting content.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.PosterDownloadDuration.Success" units="ms"
-    expires_after="2017-08-02">
-  <obsolete>
-    Removed as no more poster image is being downloaded while remoting content.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    Measures the amount of time it took to successfully download a poster image
-    for an HTML5 video while remoting content.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.StartMediaBitrate" units="kbps"
-    expires_after="2017-11-29">
-  <obsolete>
-    Removed 11/2017 in issue 788940.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    The estimated content bitrate (including both audio and video) when starting
-    a remoting session.
-  </summary>
-</histogram>
-
-<histogram name="Media.Remoting.TransmissionCapacity" units="kbps"
-    expires_after="2017-11-29">
-  <obsolete>
-    Removed 11/2017 in issue 788940.
-  </obsolete>
-  <owner>miu@chromium.org</owner>
-  <summary>
-    The estimated transmission capacity when starting a remoting session.
-  </summary>
-</histogram>
-
-<histogram name="Media.RTCVideoDecoderInitDecodeStatus" enum="BooleanSuccess"
-    expires_after="2013-10-22">
-  <obsolete>
-    Renamed to Media.RTCVideoDecoderInitDecodeSuccess.
-  </obsolete>
-  <owner>posciak@chromium.org</owner>
-  <summary>Results of attempts to RTCVideoDecoder::InitDecode().</summary>
-</histogram>
-
-<histogram name="Media.Session.AudioFocus.Abandon"
-    enum="AudioFocusAbandonSource" expires_after="2019-10-03">
-  <obsolete>
-    Removed 8/2019 in Issue 995521 due to expiry and not needed anymore.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The number of times a media session abandon audio focus and where the
-    abandon audio focus call originated from. This is recorded every time a
-    media session abandons audio focus because it has stopped playing.
-  </summary>
-</histogram>
-
-<histogram name="Media.Session.AudioFocus.Request"
-    enum="AudioFocusRequestSource" expires_after="2019-10-03">
-  <obsolete>
-    Removed 8/2019 in Issue 995521 due to expiry and not needed anymore.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The number of times a media session requested audio focus and where that
-    focus request originated from. This is recorded every time a media session
-    requests audio focus because it wants to start playing.
-  </summary>
-</histogram>
-
-<histogram name="Media.Session.AudioFocus.Type" enum="AudioFocusType"
-    expires_after="2019-10-03">
-  <obsolete>
-    Removed 8/2019 in Issue 995521 due to expiry and not needed anymore.
-  </obsolete>
-  <owner>beccahughes@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The number of times a media session requested audio focus for a specific
-    audio focus type. This is recorded every time a media session requests a new
-    audio focus type. This may be because the session has started playing or the
-    type of media being played has changed.
-  </summary>
-</histogram>
-
-<histogram name="Media.SRC.PreloadAutoHasPoster" enum="Boolean"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975367.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Whether a SRC= playback had a poster set at load() when the effective
-    preload type is &quot;auto&quot;. Note that this includes audio playbacks,
-    since we do not have track metadata at load(); audio elements never have
-    posters.
-  </summary>
-</histogram>
-
-<histogram name="Media.SRC.PreloadMetaDataHasPoster" enum="Boolean"
-    expires_after="2020-02-02">
-  <obsolete>
-    Removed 07/2019 in issue 975367.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Whether a SRC= playback had a poster set at load() when the effective
-    preload type is &quot;metadata&quot;. Note that this includes audio
-    playbacks, since we do not have track metadata at load(); audio elements
-    never have posters.
-  </summary>
-</histogram>
-
-<histogram name="Media.Timeline.Width" units="CSS px" expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="MediaElementConfigurations" -->
-
-  <owner>mlamouri@google.com</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The width of the media timeline track in CSS pixels, recorded the first time
-    a media element with controls starts playing (strictly speaking, it's the
-    width in CSS pixels ignoring CSS transforms, multiplied by pageZoomFactor,
-    but deliberately ignoring pinch zoom's pageScaleFactor).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Media.TimeToFirstFrame.SRC.ManyVideos" units="ms"
-    expires_after="2018-12-01">
-  <obsolete>
-    Removed from code 2018/11/29.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Time in milliseconds from when WebMediaPlayerImpl starts loading until the
-    first video frame has been shown IFF six or more videos are loading in
-    parallel.
-  </summary>
-</histogram>
-
-<histogram name="Media.TimeToPipelineStarted" units="ms"
-    expires_after="2014-06-21">
-  <obsolete>
-    Removed from code 2014/6/18.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>
-    Time in milliseconds from HTML5 media pipeline creation to playing event.
-  </summary>
-</histogram>
-
-<histogram name="Media.UncacheableReason" enum="UncacheableReason"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019 in issue 975278.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Reasons a media response won't be used to satisfy a future request.
-  </summary>
-</histogram>
-
-<histogram name="Media.UnderflowCount" units="units" expires_after="2017-02-22">
-  <obsolete>
-    Removed Feb 2017. Media.UnderflowDuration provides more useful counts.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    The number of times a src= playback has underflowed; i.e. ran out of data.
-  </summary>
-</histogram>
-
-<histogram name="Media.UnderflowDuration" units="ms" expires_after="2017-08-07">
-  <obsolete>
-    Removed Aug 2017. Media.UnderflowDuration2.SRC removes zero-weighting so
-    that we only report actual underflows.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    The amount of time taken to leave the underflow state (i.e. resume playback)
-    for src= playbacks.
-  </summary>
-</histogram>
-
-<histogram name="Media.UnderflowDuration.EME" units="ms"
-    expires_after="2017-08-07">
-  <obsolete>
-    Removed Aug 2017. Media.UnderflowDuration2.EME removes zero-weighting so
-    that we only report actual underflows.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The amount of time taken to leave the underflow state (i.e. resume playback)
-    for Encrypted Media Extensions (EME) based playbacks.
-  </summary>
-</histogram>
-
-<histogram name="Media.UnderflowDuration.MSE" units="ms"
-    expires_after="2017-08-07">
-  <obsolete>
-    Removed Aug 2017. Media.UnderflowDuration2.MSE removes zero-weighting so
-    that we only report actual underflows.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    The amount of time taken to leave the underflow state (i.e. resume playback)
-    for Media Source Extensions (MSE) based playbacks.
-  </summary>
-</histogram>
-
-<histogram name="Media.URLScheme" enum="URLSchemeForHistogram"
-    expires_after="2018-08-30">
-  <obsolete>
-    Replaced with Media.URLScheme2 which is only recorded for src=URL playbacks
-    instead of including MediaSource playbacks which are always blob.
-  </obsolete>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    URL scheme used with HTML5 media. (each URL provides one sample)
-  </summary>
-</histogram>
-
-<histogram name="Media.VAIP.VppFailure" enum="VAIPFailure"
-    expires_after="2021-01-01">
-  <obsolete>
-    Removed as of 08/2020.
-  </obsolete>
-  <owner>hiroh@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Count of VAAPI errors that occur inside the VaapiWrapper due to VPP
-    functionality needed by the VaapiImageProcessor.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAJDA.DecoderFailure" enum="VAJDAFailure"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Media.VaapiMjpegDecodeAccelerator.VAAPIError as of 08/2020.
-  </obsolete>
-  <owner>andrescj@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Count of VAAPI errors that occur inside the VaapiWrapper due to decoding
-    functionality needed by the VaapiMjpegDecodeAccelerator.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAJDA.VppFailure" enum="VAJDAFailure"
-    expires_after="2021-01-31">
-  <obsolete>
-    Replaced by Media.VaapiMjpegDecodeAccelerator.Vpp.VAAPIError as of 08/2020.
-  </obsolete>
-  <owner>kamesan@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Count of VAAPI errors that occur inside the VaapiWrapper due to VPP
-    functionality needed by the VaapiMjpegDecodeAccelerator.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAJDAWorker.DecoderFailure"
-    enum="VAJDAWorkerDecoderFailure" expires_after="2020-05-01">
-  <obsolete>
-    Replaced by Media.VaapiImageDecodeAcceleratorWorker.VAAPIError as of
-    08/2020.
-  </obsolete>
-  <owner>andrescj@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Count of VAAPI errors that occur inside the VaapiWrapper due to
-    functionality needed by the VaapiJpegDecodeAcceleratorWorker.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAJEA.VppFailure" enum="VAJEAEncoderResult"
-    expires_after="M87">
-  <obsolete>
-    Replaced by Media.VaapiJpegEncodeAccelerator.Vpp.VAAPIError as of 08/2020.
-  </obsolete>
-  <owner>wtlee@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Count of VAAPI errors that occur inside the VaapiWrapper due to VPP
-    functionality needed by the VaapiJpegEncodeAccelerator.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAVDA.DecoderFailure" enum="VAVDADecoderFailure"
-    expires_after="M87">
-  <obsolete>
-    Replaced by Media.VaapiVideoDecodeAccelerator.VAAPIError as of 08/2020.
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <owner>posciak@chromium.org</owner>
-  <owner>chromeos-gfx@chromium.org</owner>
-  <summary>
-    Error codes reported by video decode using VA-API hardware video decoder.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAVDAH264.DecoderFailure" enum="VAVDAH264DecoderFailure"
-    expires_after="2015-04-11">
-  <obsolete>
-    Removed as of 4/2015, partially replaced by Media.VAVDA.DecoderFailure.
-  </obsolete>
-  <owner>posciak@chromium.org</owner>
-  <summary>
-    Error codes reported by video decode using VA-API hardware video decoder.
-  </summary>
-</histogram>
-
-<histogram name="Media.VAVEA.EncoderFailure" enum="VAVEAEncoderFailure"
-    expires_after="M78">
-  <obsolete>
-    Replaced by Media.VaapiVideoEncodeAccelerator.VAAPIError as of 08/2020.
-  </obsolete>
-  <owner>posciak@chromium.org</owner>
-  <summary>
-    Error codes reported by video encode using VA-API hardware video encoder.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.Autoplay.Attribute.WaitTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records time from load starts until video starts based on autoplay
-    attribute.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.Autoplay.Muted.Attribute.OffscreenDuration"
-    units="ms" expires_after="2017-03-08">
-  <obsolete>
-    Removed as autoplay muted video by attributed is paused when going offscreen
-    since https://crbug.com/683141.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the offscreen playing duration of a muted video autoplaying from
-    autoplay attribute.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.Autoplay.Muted.Blocked"
-    enum="AutoplayBlockedReason" expires_after="M85">
-  <obsolete>
-    Removed as of M80, autoplaying muted videos can no longer be blocked.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the reason why autoplay of muted videos was blocked.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.Autoplay.PlayMethod.WaitTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records time from load starts until video starts based on play method.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.FullscreenOrientationLock.AutoRotateEnabled"
-    enum="BooleanEnabled" expires_after="M82">
-  <obsolete>
-    Removed from code as of 02/2020.
-  </obsolete>
-  <owner>mlamouri@google.com</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Whether auto rotation of screen orientation is enabled by the user (if so
-    the user has not locked the screen orientation at the OS level, though the
-    orientation may still be locked by apps). Recorded each time
-    MediaControlsOrientationLockDelegate locks the screen orientation in
-    response to a video going fullscreen (or loading metadata whilst
-    fullscreen).
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.FullscreenOrientationLock.LockResult"
-    enum="VideoFullscreenOrientationLockResult" expires_after="M77">
-  <obsolete>
-    Removed from code as of 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Result of the orientation lock attempt when a video enters fullscreen.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.FullscreenOrientationLock.MetadataAvailability"
-    enum="VideoFullscreenOrientationLockMetadataAvailability"
-    expires_after="M85">
-  <obsolete>
-    Removed from code as of 06/2020.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Status of the metadata when attempting to lock the screen orientation for a
-    fullscreen video.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.KeyFrameDistance" units="ms"
-    expires_after="2018-11-07">
-  <obsolete>
-    Removed as of 11/2018 -- no longer used and expensive to monitor.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the time distance between consequent keyframes in a video. The new
-    value is recorded for each video key frame decoded.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.TimeFromForegroundToFirstFrame" units="ms"
-    expires_after="2017-01-19">
-  <obsolete>
-    Removed as of 01/18/2017 in issue 670150. Replaced by
-    Media.Video.TimeFromForegroundToFirstFrame.DisableTrack and
-    Media.Video.TimeFromForegroundToFirstFrame.Paused.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the time between the moment when the video element is brought to the
-    foreground and when the video frame compositor outputs the next frame.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.TimeFromForegroundToFirstFrame.DisableTrack"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019 -- no longer used after background track disable has
-    launched.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the time between the moment when the video element that had video
-    track disabled in the background is brought to the foreground and when the
-    video frame compositor outputs the next frame. Recorded even if disabling
-    video track in the background is turned off to collect data for the control
-    group.
-  </summary>
-</histogram>
-
-<histogram name="Media.Video.TimeFromForegroundToFirstFrame.Paused" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019 -- no longer used after background track disable has
-    launched.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the time between the moment when the video element that was paused
-    in the background is brought to the foreground and when the video frame
-    compositor outputs the next frame. Recorded even if disabling pausing video
-    in the background is turned off to collect data for the control group.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoCapture.FramesReceived" enum="BooleanReceived"
-    expires_after="2015-06-08">
-  <obsolete>
-    Removed as of 10/2014 in issue 422822. Replaced by
-    Media.VideoCaptureManager.Event and the two new values 3 and 4 in the enum
-    VideoCaptureEvent.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <owner>mcasas@chromium.org</owner>
-  <summary>
-    Whether any frames were received during a video capture session. This metric
-    is recorded when a video source is stopped.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoCapture.PixelFormat" enum="CapturePixelFormat"
-    expires_after="2014-10-20">
-  <obsolete>
-    Removed 10/2014 in Issue 660493002.
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <summary>
-    Pixel format provided by a Video Capture Device. The collection is made in
-    the VideoCaptureController upon reception of the first frame.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoCaptureApi.Mac" enum="CaptureApiMac"
-    expires_after="M80">
-  <obsolete>
-    Removed July 30th. This is no longer used.
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <summary>
-    Video Capture and device enumeration/monitoring API used for Mac OS Lion or
-    later. Collection is made only once when the flags are parsed and the
-    appropriate library selected and/or loaded, successfully or not.
-  </summary>
-</histogram>
-
-<histogram
-    name="Media.VideoCaptureService.DurationFromLastConnectToClosingConnection"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2017 in favor of the more differentiated durations.
-  </obsolete>
-  <owner>chfremer@chromium.org</owner>
-  <summary>
-    Measures the duration from the time the Browser connected to the video
-    capture service to the time it closed the connection.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoCaptureService.DurationUntilReconnect" units="ms"
-    expires_after="2017-07-20">
-  <obsolete>
-    Removed 07/2017 in favor of the more differentiated durations.
-  </obsolete>
-  <owner>chfremer@chromium.org</owner>
-  <summary>
-    Measures the duration from the time the Browser last closed or lost
-    connection to the video capture service to the time it reconnects.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoCodecProfile" enum="VideoCodecProfile"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053030. We have this in UKM.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Video codec profile used in HTML5 media.</summary>
-</histogram>
-
-<histogram name="Media.VideoCodedAspectRatio" units="%"
-    expires_after="2016-11-15">
-  <obsolete>
-    Removed 11/2016 in issue 2506533002.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>Coded aspect ratio of HTML5 video.</summary>
-</histogram>
-
-<histogram name="Media.VideoCodedWidth" units="units"
-    expires_after="2016-11-15">
-  <obsolete>
-    Removed 11/2016 in issue 2506533002.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>Coded width of HTML5 video.</summary>
-</histogram>
-
-<histogram name="Media.VideoColorRange" enum="FFmpegColorRanges"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053030.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Pixel format color range of HTML5 video. Emitted on video load.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoFormat" enum="VideoFormat"
-    expires_after="2015-05-29">
-  <obsolete>
-    Replaced by Media.VideoFramePixelFormat 05/2015.
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <summary>Pixel format used in HTML5 video. Emitted on video load.</summary>
-</histogram>
-
-<histogram name="Media.VideoFrame.ColorSpace" enum="VideoFrameColorSpaceUMA"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053032.
-  </obsolete>
-  <owner>hubbe@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>Video frame color space. Emitted for each video frame.</summary>
-</histogram>
-
-<histogram name="Media.VideoFramePixelFormat" enum="VideoFramePixelFormat"
-    expires_after="2015-09-01">
-  <obsolete>
-    Replaced by Media.VideoPixelFormatUnion 08/2015.
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <owner>watk@chromium.org</owner>
-  <summary>Pixel format used in HTML5 video. Emitted on video load.</summary>
-</histogram>
-
-<histogram name="Media.VideoPixelFormat" enum="VideoPixelFormat"
-    expires_after="2015-05-22">
-  <obsolete>
-    Replaced by Media.VideoFormat 05/2015.
-  </obsolete>
-  <owner>scherkus@chromium.org</owner>
-  <summary>Pixel format used in HTML5 video. Emitted on video load.</summary>
-</histogram>
-
-<histogram name="Media.VideoPixelFormatUnion" enum="VideoPixelFormatUnion"
-    expires_after="M77">
-  <obsolete>
-    Pixel format has been removed from demuxers. 06/2019
-  </obsolete>
-  <owner>mcasas@chromium.org</owner>
-  <owner>emircan@chromium.org</owner>
-  <summary>
-    Pixel format used in capture and HTML5 video. Emitted on video load.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoTrackAdapter.FramesReceived" enum="BooleanReceived"
-    expires_after="2014-09-05">
-  <obsolete>
-    Replaced by Media.VideoCapture.FramesReceived 09/2014.
-  </obsolete>
-  <owner>grunell@chromium.org</owner>
-  <owner>mcasas@chromium.org</owner>
-  <summary>
-    If any frames were received during a video capture session. It's recorded
-    when a video source is stopped.
-  </summary>
-</histogram>
-
-<histogram name="Media.VideoVisibleAspectRatio" units="%" expires_after="M79">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053030.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Visible aspect ratio of HTML5 video.</summary>
-</histogram>
-
-<histogram name="Media.VideoVisibleWidth" units="units" expires_after="M82">
-  <obsolete>
-    Removed 03/2020 in https://crbug.com/1053030.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Visible width of HTML5 video.</summary>
-</histogram>
-
-<histogram name="Media.Vpx.VideoDecoderBuffersInUseByDecoder" units="units"
-    expires_after="2016-05-25">
-  <obsolete>
-    Removed 05/2016.
-  </obsolete>
-  <owner>dcastagna@chromium.org</owner>
-  <summary>Number of frame buffers used by Vpx decoder.</summary>
-</histogram>
-
-<histogram name="Media.Vpx.VideoDecoderBuffersInUseByDecoderAndVideoFrame"
-    units="units" expires_after="2016-05-25">
-  <obsolete>
-    Removed 05/2016.
-  </obsolete>
-  <owner>dcastagna@chromium.org</owner>
-  <summary>
-    Number of frame buffers currently in use by both Vpx decoder and a
-    VideoFrame.
-  </summary>
-</histogram>
-
-<histogram name="Media.VpxVideoDecoder.Vp9DecodeTime" units="ms"
-    expires_after="2018-11-07">
-  <obsolete>
-    Removed 11/2018 -- shows nothing interesting; it's been static for years.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>Amount of time taken to decode one VP9 frame.</summary>
-</histogram>
-
-<histogram name="Media.WebAudioSourceProvider.SinkStatus"
-    enum="OutputDeviceStatus" expires_after="2018-11-30">
-  <obsolete>
-    Replaced by Media.AudioRendererImpl.SinkStatus in Nov 2018.
-  </obsolete>
-  <owner>olka@chromium.org</owner>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Status of audio sink provided to WebMediaPlayer. If not OK, null sink will
-    be used for audio output instead.
-  </summary>
-</histogram>
-
-<histogram name="Media.WebMediaPlayerImpl.HLS.WouldTaintOrigin" enum="Boolean"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed because an overwhelming majority of pages do not set the crossorigin
-    attribute and as a result most HLS content is counted. Superseded by
-    Media.WebMediaPlayerImpl.HLS.HasAccessControl.
-  </obsolete>
-  <owner>sandersd@chromium.org</owner>
-  <owner>tguilbert@chromium.org</owner>
-  <summary>
-    When an HLS manifest is found during loading (on Android only), records
-    whether the request was CORS cross-origin or redirected between origins.
-    These are cases that may or may not be able to be implemented using fetch(),
-    depending on details of the redirection and the setting of the crossorigin
-    attribute. Note: subresources referenced by the manifest are not considered;
-    they may have different origins or CORS configurations.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Media.WebMediaPlayerImpl.Memory" units="KB"
-    expires_after="2020-08-09">
-  <obsolete>
-    Removed in March 2020.
-  </obsolete>
-  <owner>wolenetz@chromium.org</owner>
-  <summary>
-    Amount of memory used by the WebMediaPlayerImpl and its components.
-  </summary>
-</histogram>
-
-<histogram name="Media.WebView.UnsupportedContainer"
-    enum="UnsupportedContainers" expires_after="2018-09-22">
-  <obsolete>
-    Removed 09/2018 since support for these containers has been deprecated.
-  </obsolete>
-  <owner>dalecurtis@chromium.org</owner>
-  <summary>
-    Media container extensions seen by WebView that are not supported by the
-    standard HTML5 playback path. This value is recorded every time a
-    WebMediaPlayer is created with one of the unsupported containers.
-  </summary>
-</histogram>
-
-<histogram name="Media.WindowsCoreAudioInput" enum="BooleanSuccess"
-    expires_after="2017-01-26">
-  <obsolete>
-    Removed 01/2017 as Windows Core Audio is now the only audio input
-    implementation on Windows.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Whether Chrome is using Windows Core Audio for audio input or not. Updated
-    on Windows only when a low-latency audio input stream is created.
-  </summary>
-</histogram>
-
-<histogram name="Media.YouTube.DelayedAndDroppedFramesPer5Sec"
-    units="frames/5s" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average number of delayed and dropped frames for the YouTube
-    application. Reported every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.YouTube.DisplayedFramesPerSecond" units="frames/s"
-    expires_after="2015-07-15">
-  <obsolete>
-    Removed 07/2015 in issue 508534.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    The average number of displayed frames for the YouTube application. Reported
-    every 5 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Media.YouTube.TimeToBufferAvAfterAbort" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time needed to buffer A/V data after an abort for the YouTube application.
-  </summary>
-</histogram>
-
-<histogram name="MediaRouter.Provider.RouteControllerCreationOutcome"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed in M77. Route controller is specific to the old WebUI Cast dialog,
-    and the new Views dialog does not have it.
-  </obsolete>
-  <owner>takumif@chromium.org</owner>
-  <owner>openscreen-eng@google.com</owner>
-  <summary>
-    Records whether the Media Route Provider succeeded or failed to create a
-    controller for a media route.
-  </summary>
-</histogram>
-
-<histogram name="MediaRouter.Sink.SearchOutcome" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Sink search is specific to the old WebUI Cast dialog, and
-    the new Views dialog does not have it.
-  </obsolete>
-  <owner>takumif@chromium.org</owner>
-  <owner>openscreen-eng@google.com</owner>
-  <summary>
-    The outcome of querying Media Route Providers for a sink by ID.
-    &quot;Success&quot; indicates that a sink was found. This is recorded when
-    the user attempts to cast to a sink with a manually entered ID.
-  </summary>
-</histogram>
-
-<histogram name="MediaRouter.Ui.Dialog.LoadedWebUiRouteController" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Route controller is specific to the old WebUI Cast dialog,
-    and the new Views dialog does not have it.
-  </obsolete>
-  <owner>takumif@chromium.org</owner>
-  <owner>openscreen-eng@google.com</owner>
-  <summary>
-    Duration in milliseconds it takes the WebUI route controls in the route
-    details view to be populated after the view is opened.
-  </summary>
-</histogram>
-
-<histogram name="MediaRouter.Ui.InitialState" enum="MediaRouterInitialViews"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. This histogram was for tracking whether the old WebUI Cast
-    dialog opened in sink list view or route details view.
-  </obsolete>
-  <owner>takumif@chromium.org</owner>
-  <owner>openscreen-eng@google.com</owner>
-  <summary>
-    The view that was shown when the Media Router dialog is initially opened.
-  </summary>
-</histogram>
-
-<histogram name="MemCache.WriteResult" enum="MemCacheWriteResult"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>The outcome of Entry::WriteData in the memory cache.</summary>
-</histogram>
-
-<histogram name="Memory.Browser" units="KB" expires_after="2016-10-03">
-  <obsolete>
-    Removed 06/2016 Replaced with Memory.Browser.Large2.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by the browser process. Recorded once per UMA
-    ping. Note the existence of Memory.Browser.Large, which doesn't have
-    overflow issues. TODO(rkaplow): This should be replaced with
-    Memory.Browser.Large2 in M54.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Browser.Committed" units="MB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The total committed memory used by the browser process. Recorded once per
-    UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Browser.Large" units="MB" expires_after="2016-07-19">
-  <obsolete>
-    Removed 07/2016 as it reports wrong numbers. crbug.com/629354. Replaced with
-    Memory.Browser.Large2
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The private working set used by the browser process. Recorded once per UMA
-    ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Browser.Large2" units="MB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017 Replaced with Memory.Browser.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by the browser process. Recorded once per UMA
-    ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Chrome" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement, but
-    Memory.Renderer.PrivateMemoryFootprint is similar.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each chrome:// renderer process. Each
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.ChromeProcessCount" units="processes"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of active chrome:// renderer processes. Recorded once per UMA
-    ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.CompressibleStringCount"
-    enum="CompressibleStringCountType" expires_after="2016-08-10">
-  <obsolete>
-    Removed as of Aug 2016. CompressibleString has been reverted once at
-    https://crrev.com/2227933002.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <summary>
-    This records the frequency with which JavaScript source strings are
-    compressed and decompressed in foreground and background tabs. Compressing
-    runs 10 seconds after the tab goes background and decompressing runs when
-    JavaScript source string is required (e.g. V8 starts to compile). This
-    measurement is a preparation to introduce CompressibleString class for
-    JavaScript source strings to reduce Blink memory usage.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.FreeMemoryUntilCritical" units="MB"
-    expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Available free memory until the system will be in a critical state. Critical
-    is as defined by the OS (swapping will occur, or physical memory will run
-    out, etc).
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.StateDuration" units="seconds"
-    expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>Time elapsed between the global state changes.</summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.StateOnCriticalNotificationReceived"
-    enum="MemoryState" expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The global state of memory coordinator when a critical pressure notification
-    is received.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.StateOnModerateNotificationReceived"
-    enum="MemoryState" expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The global state of memory coordinator when a moderate pressure notification
-    is received.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.TotalPrivate" units="MB"
-    expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The total private working set memory used by the browser and renderer
-    processes when the memory coordinator changes the global memory state.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.TrimMemoryLevel.Normal"
-    enum="TrimMemoryLevel" expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Android: Records trim memory level when the global state is NORMAL.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.TrimMemoryLevel.Suspended"
-    enum="TrimMemoryLevel" expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Android: Records trim memory level when the global state is SUSPENDED.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Coordinator.TrimMemoryLevel.Throttled"
-    enum="TrimMemoryLevel" expires_after="2017-02-27">
-  <obsolete>
-    Obsolete as of 2/2017
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Android: Records trim memory level when the global state is THROTTLED.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Browser.PrivateMemoryFootprint.MacOS"
-    units="MB" expires_after="2018-01-03">
-  <obsolete>
-    Removed 12/2017. Replaced by Memory.Browser.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    A rough estimate of the private memory footprint of the browser process.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Browser.PurgedMemory" units="MB"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed 03/2018.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Amount of reclaimed memory (in terms of the private working set size) after
-    a purge request on the browser process. Recorded 2 seconds after the purge
-    request.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.CompressedPagesPerSecond" units="pages/s"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The number of pages compressed per second. Recorded every 60 seconds. Only
-    recorded on macOS.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.DecompressedPagesPerSecond"
-    units="pages/s" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The number of pages decompressed per second. Recorded every 60 seconds. Only
-    recorded on macOS.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Extension.PrivateMemoryFootprint.MacOS"
-    units="MB" expires_after="2018-01-03">
-  <obsolete>
-    Removed 12/2017. Replaced by Memory.Extension.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    A rough estimate of the private memory footprint of an extension process.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Gpu.PrivateMemoryFootprint.MacOS"
-    units="MB" expires_after="2018-01-03">
-  <obsolete>
-    Removed 12/2017. Replaced by Memory.Gpu.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    A rough estimate of the private memory footprint of the GPU process.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.NewMemoryPressureMonitor.SessionDurations.CriticalPressure"
-    units="ms" expires_after="2019-12-31">
-  <obsolete>
-    Removed 12/2019.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    The amount of time spent in the critical memory pressure state. Recorded
-    every time the level changes and at shutdown.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.NewMemoryPressureMonitor.SessionDurations.NoPressure"
-    units="ms" expires_after="2019-12-31">
-  <obsolete>
-    Removed 12/2019.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    The amount of time spent in the no memory pressure state. Recorded every
-    time the level changes and at shutdown.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.BrowserMonitorStatus"
-    enum="OomInterventionBrowserMonitorStatus" expires_after="2018-08-29">
-  <obsolete>
-    Removed 08/2018. Made a decision in issue 871507 that we no longer need this
-    data.
-  </obsolete>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    Records the status of OOM intervention if the feature is turned on, with
-    various reasons for failure, in the browser process. Recorded once at
-    browser startup.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.InterventionStateOnCrash"
-    enum="OomInterventionUserDecision" expires_after="M85">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Records state of the intervention (accepted or declined) when the foreground
-    renderer is crashed after near-OOM intervention is triggered.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.NavigationAfterDetectionTime"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Records the time elapsed between a near-OOM detection and when a navigation
-    is started.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.NearOomDetectionEndReason"
-    enum="NearOomDetectionEndReason" expires_after="M82">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Records the reason for stopping near-OOM detection. This isn't recorded when
-    a near-OOM situation was detected.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.OomProtectedCrashAfterDetectionTime"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Records the time elapsed between a near-OOM detection and when an OOM
-    protected renderer was crashed.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedBlinkUsageAfter10secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of blink usage after 10 seconds of intervention. This reports
-    negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedBlinkUsageAfter20secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of blink usage after 20 seconds of intervention. This reports
-    negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedBlinkUsageAfter30secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of blink usage after 30 seconds of intervention. This reports
-    negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedRendererPMFAfter10secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of renderer pmf after 10 seconds of intervention. This
-    reports negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedRendererPMFAfter20secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of renderer pmf after 20 seconds of intervention. This
-    reports negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs"
-    units="MB" expires_after="2019-5-31">
-  <obsolete>
-    Replaced by ReducedRendererPMFAfter30secs2 in 03/2019.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Reduced amount of renderer pmf after 30 seconds of intervention. This
-    reports negative numbers when reduced.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.RendererEnabledStatus"
-    enum="OomInterventionRendererStatus" expires_after="2018-08-29">
-  <obsolete>
-    Removed 08/2018. Made a decision in issue 871507 that we no longer need this
-    data.
-  </obsolete>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    Records the status of OOM intervention in renderer process if the feature is
-    turned on, with various reasons for failure. Recorded at each navigation or
-    reload.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.RendererGoneAfterDetectionTime"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Records the time elapsed between a near-OOM detection and when a foreground
-    renderer process was gone. This histogram does not contain OOM protected
-    crashes.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.OomIntervention.RendererTimeSinceLastNavigationAtIntervention"
-    units="seconds" expires_after="M80">
-  <obsolete>
-    Removed 1/2019 because RendererTimeSinceLastNavigationAtDetection replaced
-    this metric by expanding coverage to include detection-only mode.
-  </obsolete>
-  <owner>yuzus@chromium.org</owner>
-  <summary>
-    Records the time since last main frame navigation start on the renderer
-    process when intervention is triggered. Record only when navigation happened
-    at least once.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.RendererVmSizeAtOOM"
-    units="MB" expires_after="2018-06-12">
-  <obsolete>
-    Replaced by Memory.Experimental.OomIntervention.RendererVmSizeAtOOMLarge.
-  </obsolete>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    The renderer process' virtual memory usage, when a foreground OOM occurs.
-    This was last recorded metric by renderer a few seconds before getting
-    killed.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.OomIntervention.UserDecision"
-    enum="OomInterventionUserDecision" expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>Records user decisions on near-OOM intervention.</summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Renderer.LocalFrameRootPurgeSignal"
-    enum="LocalFrameRootPurgeSignal" expires_after="M82">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Recorded after every memory purge signal received by a foreground local
-    frame root with accelerated compositing enabled. Records whether or not the
-    signal was the first received by the local frame root.
-
-    This metric has changed over time and it is important to consider these
-    changes when analyzing historical data.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Renderer.PrivateMemoryFootprint.MacOS"
-    units="MB" expires_after="2018-01-03">
-  <obsolete>
-    Removed 12/2017. Replaced by Memory.Renderer.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    A rough estimate of the private memory footprint of a renderer process.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.Renderer.PurgedMemory" units="MB"
-    expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    Amount of reclaimed memory (in terms of
-    Memory.Experimental.Renderer.TotalAllocated) after a purge request on a
-    renderer process. Recorded 2 seconds after the purge request.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.SwapInPerSecond" units="swaps/s"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The number of swap-ins per second. Recorded every 60 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.SwapOutPerSecond" units="swaps/s"
-    expires_after="M80">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>
-    The number of swap-outs per second. Recorded every 60 seconds.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.SwapThrashingLevel"
-    enum="SwapThrashingLevel" expires_after="M85">
-  <obsolete>
-    Obsolete as of 07/2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The swap thrashing level, which is recorded periodically. This shows the
-    cumulative number of seconds that systems spend in each of the swap
-    thrashing states. Only available on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.SwapThrashingLevelChanges"
-    enum="SwapThrashingLevelChanges" expires_after="M85">
-  <obsolete>
-    Obsolete as of 07/2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The number of swap-thrashing level state changes for each possible pairwise
-    state change. Only available on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.WMIRefresher.Init.AddEnumDuration"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Removed 03/2019. Replaced by
-    Memory.Experimental.WMIRefresher.Init.AddEnumDuration2.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes for the call to |AddEnum| to complete during the
-    initialization of the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.WMIRefresher.Init.AddEnumDuration2"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes for the call to |AddEnum| to complete during the
-    initialization of the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.WMIRefresher.Init.CoCreateInstanceDuration"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes for the call to |CoCreateInstance| to complete during the
-    initialization of the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.WMIRefresher.Init.CreateLocalWmiConnectionDuration"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes for the call to |CreateLocalWmiConnection| to complete
-    during the initialization of the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.WMIRefresher.InitDiskIdleTimeConfigStatus"
-    enum="WMIRefresherInitStatus" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 09/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of configuring the WMIRefresher to read the disk idle time
-    values.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.WMIRefresher.InitializeDiskIdleTimeConfigDuration"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Removed 03/2019. Replaced by
-    Memory.Experimental.WMIRefresher.InitializeDiskIdleTimeConfigDuration2.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes to initialize the disk idle config in the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram
-    name="Memory.Experimental.WMIRefresher.InitializeDiskIdleTimeConfigDuration2"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes to initialize the disk idle config in the WMI Refresher.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.WMIRefresher.RefreshDiskIdleTimeDuration"
-    units="ms" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The time it takes to do a refresh of the disk idle time value in the WMI
-    Refresher.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Experimental.WMIRefresher.RefreshDiskIdleTimeStatus"
-    enum="WMIRefresherRefreshStatus" expires_after="2019-09-30">
-  <obsolete>
-    Obsolete as of 08/2019
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of refreshing the disk idle time value in the WMIRefresher.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Extension" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. Replaced by Memory.Extension.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each extension process. Each process
-    provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.ExtensionProcessCount" units="processes"
-    expires_after="M82">
-  <obsolete>
-    Removed 06/2020. No direct replacement. For similar histograms see
-    Memory.RenderProcessHost.Count.*, Memory.RendererProcessCount and
-    Memory.ProcessCount. Old data has been preserved at (Google-internal)
-    https://docs.google.com/document/d/1QleZ5KhAbFZkv0In61sw7e2rWCaJ05dUCdV9DncJZ2E
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The count of active extension processes. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Gpu" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. Replaced by Memory.Gpu.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>jamescook@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by the GPU process. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.IPCChannelReader.ReceivedMessageSize" units="bytes"
-    expires_after="2015-10-29">
-  <obsolete>
-    Obsolete as of 11/2015
-  </obsolete>
-  <owner>ssid@chromium.org</owner>
-  <summary>Size of messages received by IPC::ChannelReader.</summary>
-</histogram>
-
-<histogram name="Memory.MovableStringParkingAction" enum="ParkingAction"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Recorded each time a Movable String is (un)parked, with the context:
-    foreground/background.
-  </summary>
-</histogram>
-
-<histogram name="Memory.MovableStringsCount" units="count" expires_after="M77">
-  <obsolete>
-    Removed 7/2019. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    This records the number of movable Javascript source string resources in a
-    given renderer, at the time page is backgrounded. Recorded alongside
-    Memory.MovableStringsTotalSizeKb.
-  </summary>
-</histogram>
-
-<histogram name="Memory.MovableStringsTotalSizeKb" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Removed 7/2019. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    This records the total size of movable Javascript source string resources in
-    a given renderer, at the time page is backgrounded. Recorded alongside
-    Memory.MovableStringsCount.
-  </summary>
-</histogram>
-
-<histogram name="Memory.NativeClient" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each Native Client loader process. Each
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.NativeClientBroker" units="KB"
-    expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each Native Client broker process. Each
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.NativeLibrary.MappedAndResidentMemoryFootprint"
-    units="KB" expires_after="2019-07-01">
-  <obsolete>
-    Removed 03/2019. Replaced by
-    Memory.NativeLibrary.MappedAndResidentMemoryFootprint2 to add more precision
-    to buckets.
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    The size of the resident memory for the native library code across all
-    processes. This metric is computed by parsing proc/self/pagemap and counting
-    native library pages that are mapped and present in RAM for at least one
-    Chrome process. Recorded once per UMA ping. Available only on Android.
-  </summary>
-</histogram>
-
-<histogram name="Memory.NativeLibrary.MappedAndResidentMemoryFootprint2"
-    units="KB" expires_after="2021-02-14">
-  <obsolete>
-    Removed 09/2020. Replaced by
-    Memory.NativeLibrary.MappedAndResidentMemoryFootprint3 to increase device
-    coverage.
-  </obsolete>
-  <owner>msalama@google.com</owner>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    The size of the resident memory for the native library code across all
-    processes. This metric is computed by parsing proc/self/pagemap and counting
-    native library pages that are mapped and present in RAM for at least one
-    Chrome process.
-
-    Recorded at Poisson sampled time intervals with a mean of 5 minutes on
-    Android and 30 minutes on other platforms.
-  </summary>
-</histogram>
-
-<histogram name="Memory.OtherProcessCount" units="processes"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of other various utility processes (nacl, gpu, sandbox, zygote,
-    utility). Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.ParkableString.CompressionRatio" units="%"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Average compression ratio, 100 * compressed_size / initial_size, for all
-    compressed ParkableStrings. Recorded at the same time as
-    &quot;Memory.ParkableString.TotalSizeKb&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Memory.ParkableString.TotalSizeKb" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Total size of ParkableStrings assuming no compression, in KB. Recorded 30s
-    after compression was triggered, provided that the renderer stayed
-    backgrounded.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PartitionAlloc.MainThreadTime.5min" units="ms"
-    expires_after="M87">
-  <obsolete>
-    Deprecated and removed from the code 06/2020.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Total main thread time used by PartitionAlloc's decommit logic over the
-    first 5 minutes of a renderer lifetime. Starting time is renderer
-    initialization.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PepperFlashPlugin" units="KB"
-    expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The private working set used by each Pepper Flash plugin process. Each
-    plugin process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PepperPlugin" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each Pepper plugin process. Each plugin
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PepperPluginBroker" units="KB"
-    expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each Pepper plugin broker process. Each
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PepperPluginBrokerProcessCount" units="processes"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of Pepper plugin broker processes, recorded once per metrics
-    services (UMA) update. See MetricsReportingScheduler for details.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PepperPluginProcessCount" units="processes"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of active Pepper plugin processes. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Plugin" units="KB" expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each plugin process. Each plugin process
-    provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.PluginProcessCount" units="processes"
-    expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of active plugin processes. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.ProcessLimit" units="units" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>The current process limit. Recorded once per UMA ping.</summary>
-</histogram>
-
-<histogram name="Memory.Renderer" units="KB" expires_after="2016-10-03">
-  <obsolete>
-    Removed 06/2016 Replaced with Memory.Renderer.Large2.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each renderer process. Each renderer process
-    provides one sample. Recorded once per UMA ping. TODO(rkaplow): This should
-    be replaced with Memory.Renderer.Large2 in M54.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Renderer.Committed" units="MB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The total committed memory used by each renderer process. Each renderer
-    process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Renderer.Large2" units="MB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. Replaced by Memory.Renderer.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each renderer process. Each renderer process
-    provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.RendererAll" units="MB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement, although
-    Memory.Total.PrivateMemoryFootprint is similar.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>tasak@chromium.org</owner>
-  <summary>
-    The private working set used by each renderer process, including all
-    renderer types, i.e. this includes Chrome renderer, extensions renderer, as
-    well as regular renderer processes. Each renderer process provides one
-    sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.RendererAll.Committed" units="MB"
-    expires_after="2018-01-15">
-  <obsolete>
-    Removed 01/2018. No direct replacement, although
-    Memory.Total.PrivateMemoryFootprint is similar.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>tasak@chromium.org</owner>
-  <summary>
-    The total committed memory used by each renderer process, including all
-    renderer types, i.e. this includes Chrome renderer, extensions renderer, as
-    well as regular renderer processes. Each renderer process provides one
-    sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.RendererGrowthIn30Min" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Growth speed of the private working set used by each renderer process per 30
-    minutes. The usage and growth speed is recorded at most every 30 minutes,
-    not every exact 30 minutes. If the interval is longer than 30 minutes, it is
-    normalized to a speed KB per 30 minutes. Each renderer process provides one
-    sample. Recorded once per UMA log unless this is the first time the UMA log
-    is recorded after startup of the renderer, 30 minutes have not passed from
-    the last recording of the renderer or the usage goes down. If the usage goes
-    down, the amount of the shrink will be recorded in the
-    Memory.RendererShrinkIn30Min histogram.
-  </summary>
-</histogram>
-
-<histogram name="Memory.RendererShrinkIn30Min" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Shrink speed of the private working set used by each renderer process per 30
-    minutes. The usage and shrink speed is recorded at most every 30 minutes,
-    not every exact 30 minutes. If the interval is longer than 30 minutes, it is
-    normalized to a speed KB per 30 minutes. Each renderer process provides one
-    sample. Recorded once per UMA log unless this is the first time the UMA log
-    is recorded after startup of the renderer, 30 minutes have not passed from
-    the last recording of the renderer or the usage goes up. If the usage goes
-    up, the amount of the growth will be recorded in the
-    Memory.RendererGrowthIn30Min histogram.
-  </summary>
-</histogram>
-
-<histogram name="Memory.SandboxHelper" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each sandbox helper process. Each sandbox
-    helper process provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailPageFile" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.AvailPageFile2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the maximum amount of memory the current
-    process can commit. This value is equal to or smaller than the system-wide
-    available commit value.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailPageFile2" units="MB"
-    expires_after="M80">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the maximum amount of memory the current
-    process can commit. This value is equal to or smaller than the system-wide
-    available commit value.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailPhys" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.AvailPhys2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of physical memory currently
-    available. This is the amount of physical memory that can be immediately
-    reused without having to write its contents to disk first. It is the sum of
-    the size of the standby, free, and zero lists.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailPhys2" units="MB" expires_after="M77">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of physical memory currently
-    available. This is the amount of physical memory that can be immediately
-    reused without having to write its contents to disk first. It is the sum of
-    the size of the standby, free, and zero lists.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailVirtual" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.AvailVirtual2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of unreserved and uncommitted
-    memory currently in the user-mode portion of the virtual address space of
-    the calling process.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.AvailVirtual2" units="MB" expires_after="M77">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of unreserved and uncommitted
-    memory currently in the user-mode portion of the virtual address space of
-    the calling process.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.MemoryLoad" units="%" expires_after="M77">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the approximate percentage of physical
-    memory that was in use (0 indicates no memory use and 100 indicates full
-    memory use).
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalPageFile" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.TotalPageFile2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the current committed memory limit for
-    the system or the current process, whichever is smaller.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalPageFile2" units="MB"
-    expires_after="M77">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the current committed memory limit for
-    the system or the current process, whichever is smaller.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalPhys" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.TotalPhys2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of actual physical memory.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalPhys2" units="MB" expires_after="M80">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the amount of actual physical memory.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalVirtual" units="MB"
-    expires_after="2016-03-17">
-  <obsolete>
-    Removed in 595320 and replaced with Memory.Stats.Win.TotalVirtual2.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the size of the user-mode portion of the
-    virtual address space of the calling process. This value depends on the type
-    of process, the type of processor, and the configuration of the operating
-    system. For example, this value is approximately 2 GB for most 32-bit
-    processes on an x86 processor and approximately 3 GB for 32-bit processes
-    that are large address aware running on a system with 4-gigabyte tuning
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Stats.Win.TotalVirtual2" units="MB" expires_after="M80">
-  <obsolete>
-    Removed in 05/2019
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Windows-only metric that represents the size of the user-mode portion of the
-    virtual address space of the calling process. This value depends on the type
-    of process, the type of processor, and the configuration of the operating
-    system. For example, this value is approximately 2 GB for most 32-bit
-    processes on an x86 processor and approximately 3 GB for 32-bit processes
-    that are large address aware running on a system with 4-gigabyte tuning
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Browser" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by the browser process. Recorded once per UMA ping if the
-    system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Chrome" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each chrome:// renderer process. Each process provides one
-    sample. Recorded once per process per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.CompressedDataSize" units="MB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The amount of memory that swap was compressed into. Recorded once per UMA
-    ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.CompressionRatio" units="units"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The ratio of swapped data original size to compressed size. Recorded once
-    per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Extension" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each extension process. Each process provides one sample.
-    Recorded once per process per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Gpu" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by the GPU process. Recorded once per UMA ping if the system
-    has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.HaveSwapped" enum="BooleanSuccess"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Indicates that the system has swapped memory out at least once since boot.
-    Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.MemUsedTotal" units="MB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The amount of memory that is used by swap, including bookkeeping. Recorded
-    once per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.NativeClient" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each Native Client loader process. Each process provides
-    one sample. Recorded once per process per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.NativeClientBroker" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each Native Client broker process. Each process provides
-    one sample. Recorded once per process per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.NumReads" units="units" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The number of reads from swap. Recorded once per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.NumWrites" units="units"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The number of writes to swap. Recorded once per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.OriginalDataSize" units="MB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The amount of memory that was swapped out. Recorded once per UMA ping if the
-    system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.PepperPlugin" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each Pepper plugin process. Each plugin process provides
-    one sample. Recorded once per process per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.PepperPluginBroker" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each Pepper plugin broker process. Each process provides
-    one sample. Recorded once per process per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Plugin" units="KB" expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each plugin process. Each plugin process provides one
-    sample. Recorded once per process per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Renderer" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each renderer process. Each renderer process provides one
-    sample. Recorded once per process per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.SandboxHelper" units="KB"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each sandbox helper process. Each sandbox helper process
-    provides one sample. Recorded once per process per UMA ping if the system
-    has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Total" units="MB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The sum of all processes' swap. Recorded once per UMA ping if the system has
-    swapped. See Memory.Swap.Total2 for the same metric with higher precision
-    bucketing.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Total2" units="MiB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The sum of all processes' swap. Recorded once per UMA ping if the system has
-    swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Utility" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by each utility process. Each utility process provides one
-    sample. Recorded once per process per UMA ping if the system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Swap.Zygote" units="KB" expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The swap used by the zygote process. Recorded once per UMA ping if the
-    system has swapped.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Total" units="MB" expires_after="2020-04-05">
-  <obsolete>
-    Removed 09/2016. Replaced by Memory.Total2.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The sum of all processes. This is not aware of shared memory so it is just a
-    rough estimate. Recorded once per UMA ping. See Memory.Total2 for the same
-    metric with higher precision bucketing.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Total2" units="MiB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. Replaced by Memory.Total.PrivateMemoryFootprint.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The sum of all processes. This is not aware of shared memory so it is just a
-    rough estimate. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Utility" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by each utility process. Each utility process
-    provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.WorkerProcessCount" units="processes"
-    expires_after="2018-03-09">
-  <obsolete>
-    Removed 03/2018. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The count of active worker processes. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="Memory.Zygote" units="KB" expires_after="2017-11-10">
-  <obsolete>
-    Removed 11/2017. No direct replacement.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    The private working set used by the zygote process. Each zygote process
-    provides one sample. Recorded once per process per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="MemoryAndroid.LowMemoryTimeBetween" units="ms"
-    expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Time between two consecutive LowMemory notification in one foreground
-    session.
-  </summary>
-</histogram>
-
-<histogram name="MemoryAndroid.NotificationBackground"
-    enum="AndroidMemoryNotificationBackground" expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/2018 in favor of Android.MemoryPressureNotification.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Memory notifications delivered through system callbacks to Chrome while in
-    the background.
-  </summary>
-</histogram>
-
-<histogram name="MemoryAndroid.NotificationForeground"
-    enum="AndroidMemoryNotificationForeground" expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/2018 in favor of Android.MemoryPressureNotification.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Memory notifications delivered through system callbacks to Chrome while in
-    the foreground - we count LowMemory notification vs particular levels of
-    TrimMemory foreground notification.
-  </summary>
-</histogram>
-
-<histogram name="MemoryPurgeController.ReclaimedPartitionAllocInactiveTab"
-    units="KB" expires_after="M85">
-  <obsolete>
-    Obsolete as of 06/2020.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <summary>The amount of reclaimed memory after a tab became inactive.</summary>
-</histogram>
-
-<histogram name="MemoryWarning.EvictedTabTimeSinceActive" units="ms"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    [iOS] When the OS sends a memory warning and the app evicts a tab, this
-    histogram records the time since the evicted tab was active.
-  </summary>
-</histogram>
-
-<histogram name="MemoryWarning.ProtectedTabTimeSinceActive" units="ms"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    [iOS] When the OS sends a memory warning and the app protects a tab, this
-    histogram records the time since the protected tab was active.
-  </summary>
-</histogram>
-
-<histogram name="MessageLoop.DelayedTaskQueue.PendingTasksCountOnIdle"
-    units="units" expires_after="2018-07-24">
-  <obsolete>
-    Removed as of 07/2018.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The size of the delayed task queue when the loop becomes idle. Diagnosis
-    metric for https://crbug.com/850450#c4.
-  </summary>
-</histogram>
-
-<histogram name="MessageLoop.DelayedTaskQueue.PostedDelay" units="ms"
-    expires_after="2018-07-24">
-  <obsolete>
-    Removed as of 07/2018.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Reports the delay of a delayed task posted to a MessageLoop. Reported once
-    per delayed task. Diagnosis metric for https://crbug.com/850450#c4.
-  </summary>
-</histogram>
-
-<histogram name="MessageLoop.DelayedTaskQueueForUI.PendingTasksCountOnIdle"
-    units="units" expires_after="2018-11-14">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The size of the delayed task queue when the loop becomes idle on a UI
-    thread. Diagnosis metric for https://crbug.com/850450#c4. Note: this metric
-    is a bit broken on Mac OSX as CFRunLoop doesn't deterministically invoke
-    MessageLoop::DoIdleWork().
-  </summary>
-</histogram>
-
-<histogram name="MessageLoop.ScheduledSleep.Completed" units="ms"
-    expires_after="2018-07-24">
-  <obsolete>
-    Removed as of 07/2018.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Reports the delay for which the MessageLoop successfully slept until an
-    upcoming delayed task. Reported each time a MessageLoop successfully sleeps
-    until the next delayed task.
-  </summary>
-</histogram>
-
-<histogram name="MessageLoop.ScheduledSleep.Interrupted" units="ms"
-    expires_after="2018-07-24">
-  <obsolete>
-    Removed as of 07/2018.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Reports the delay for which the MessageLoop had planned to sleep (next
-    delayed task) before it was woken up early. Reported each time a MessageLoop
-    is woken up early.
-  </summary>
-</histogram>
-
-<histogram name="MixedAutoupgrade.Navigation.OptedOut" enum="BooleanOptedOut"
-    expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>carlosil@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Whether a navigation opted out or not of Mixed Content autoupgrades.
-    Recorded every navigation.
-  </summary>
-</histogram>
-
-<histogram name="MixedAutoupgrade.Websocket.Status"
-    enum="MixedContentAutoupgradeStatus" expires_after="M85">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>carlosil@chromium.org</owner>
-  <summary>
-    The status of a mixed content websocket that was autoupgraded to WSS.
-  </summary>
-</histogram>
-
-<histogram name="Mobile.Splash.HideSplashWhenFinishing" enum="Boolean"
-    expires_after="M86">
-  <obsolete>
-    Removed in 07/2020 because it is no longer needed for analysis.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Records the cases when the splash screen is hidden when the activity is
-    finishing. Only &quot;true&quot; is recorded. The purpose is to help
-    determine cause of http://crbug.com/1096171
-  </summary>
-</histogram>
-
-<histogram name="Mobile.Splash.TranslucencyRemovalFailed" enum="Boolean"
-    expires_after="M88">
-  <obsolete>
-    Removed in 06/2020 because it is no longer needed for analysis.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Records the cases when removing a Trusted Web Activity's or WebAPK's
-    translucency via a reflective call fails. Only &quot;true&quot; is recorded.
-  </summary>
-</histogram>
-
-<histogram name="Mobile.SystemNotification.CreationFailure"
-    enum="SystemNotificationType" expires_after="2020-06-07">
-  <obsolete>
-    Removed in 04/2020.
-  </obsolete>
-  <owner>xingliu@chromium.org</owner>
-  <summary>
-    Android: Represents the number of system notifications failed to be created
-    by the Android API.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.BytesDownloaded" units="KB" expires_after="M82">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the total data downloaded by completion status.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileDownload.BytesWasted.ChromeNetworkStack"
-    units="KB" expires_after="2020-06-07">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the total data wasted during download due to resumptions.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.CancelledDownloadRemovedFromHistory"
-    units="downloads" expires_after="M72">
-  <obsolete>
-    Removed 09/2019, replaced by Download.CancelledDownloadRemovedFromHistory.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Android: Records the number of cancelled download that are cleaned up from
-    the history, after loading all the downloads from the history DB on startup.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.CancelReason" enum="MobileDownloadCancelReason"
-    expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>Android: Records the reason that a download is canceled.</summary>
-</histogram>
-
-<histogram name="MobileDownload.DownloadResumption"
-    enum="MobileDownloadResumption" expires_after="2020-04-05">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records user interaction on the download resumption button.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.DownloadTime" units="ms"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the total time for a download by completion status.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.DuplicateInfobar"
-    enum="MobileDownloadDuplicateInfobar" expires_after="M77">
-  <obsolete>
-    Removed in 07/2019.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records various counts related to the duplicate download infobar.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.FirstBackground.InterruptionCount"
-    units="interruptions" expires_after="2020-04-05">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>hnakashima@chromium.org</owner>
-  <owner>hanxi@chromium.org</owner>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the number of interruptions for the first download started
-    in background after it reaches a terminal state.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.FirstBackground.Reason" enum="InterruptReason"
-    expires_after="2020-06-07">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>hnakashima@chromium.org</owner>
-  <owner>hanxi@chromium.org</owner>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records all the interrupt reasons for the first download started in
-    background after every browser process launch. We only record the first
-    download so that we can compare the difference between service manager only
-    mode and full browser process mode.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.FirstBackground.StartedReason"
-    enum="InterruptReason" expires_after="2020-04-05">
-  <obsolete>
-    Removed in 02/2020.
-  </obsolete>
-  <owner>hnakashima@chromium.org</owner>
-  <owner>hanxi@chromium.org</owner>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: After every browser process launch, records the interrupt reason of
-    the first background download when it is started. This interrupt reason
-    allows us to know whether download was interrupted due to browser process
-    crash in an earlier attempt.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.InterceptFailureReason"
-    enum="MobileDownloadInterceptFailureReason" expires_after="2016-09-21">
-  <obsolete>
-    Removed 09/2016 in Issue 647755 with all downloads going through Chrome.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the reason that Chrome fails to intercept a download and
-    pass it to the Android DownloadManager.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.InterruptedDownloadsRemovedFromHistory"
-    units="downloads" expires_after="M73">
-  <obsolete>
-    Removed 09/2019, replaced by
-    Download.InterruptedDownloadsRemovedFromHistory.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Android: Records the number of interrupted download that are cleaned up from
-    the history, after loading all the downloads from the history DB on startup.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.InterruptionsCount" units="units"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <summary>
-    Android: Records the total interruptions for a download by completion
-    status.
-  </summary>
-</histogram>
-
-<histogram name="MobileDownload.Notification.FixingSummaryLeak"
-    enum="BooleanForegroundNotification" expires_after="2017-10-27">
-  <obsolete>
-    Removed 10/2017 in Issue 722320 with the removal of
-    DownloadNotificationService.hideDanglingSummaryNotification.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Android: Records the situation where we try to fix a standalone downloads
-    summary notification, which shouldn't be visible to the user. True if the
-    notification was a foreground notification, in which case we can't dismiss
-    it and need to attempt a more drastic workaround. False if it was a normal
-    notification and we can dismiss it easily (this is okay and expected
-    behavior in some scenarios).
-  </summary>
-</histogram>
-
-<histogram name="MobileFre.PrivacyLinkTappedStatus"
-    enum="MobileFreLinkTappedStatus" expires_after="M82">
-  <obsolete>
-    Removed 04/2020 because the Privacy Notice is removed from FRE. (See
-    crbug.com/1065912)
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <summary>
-    iOS: Records the status of the privacy page after user taps on the privacy
-    link on the first run welcome view. This metric is only recorded if and
-    after the TOS are accepted. This metric is specific to iOS.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.ColdStartupIntent" enum="MobileStartupIntent"
-    expires_after="2020-04-05">
-  <obsolete>
-    Removed from the code 03/2020
-  </obsolete>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    For cold starts of Chrome (native not initialized at the time of intent),
-    record in ChromeTabbedActivity whether the intent had the effect of opening
-    a new page or was a restore of last session.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.LoadedHomepageOnColdStart" enum="BooleanIsNtp"
-    expires_after="M75">
-  <obsolete>
-    Deprecated and removed from the code 02/2020
-  </obsolete>
-  <owner>tedchoc@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Android: Tracks whether a homepage was loaded on startup of
-    ChromeTabbedActivity. Launching a homepage is conditional on a homepage
-    being configured on the device and the absence of any existing tabs, so it
-    will only happen on a subsets of cold starts. The metric splits out whether
-    the homepage was the NTP or some other URL.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.MainIntentAction" enum="MobileStartingAction"
-    expires_after="2018-05-22">
-  <obsolete>
-    Removed and removed from the code 05/2018
-  </obsolete>
-  <owner>mariakhomenko@chromium.org</owner>
-  <summary>
-    Android: Records the first action the user does within 10s of starting
-    Chrome. Recorded in DocumentActivity and ChromeTabbedActivity only when the
-    starting intent is of type MAIN.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.MobileMultiWindowInstances" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Android: Number of instances of Chrome currently open during a MultiWindow
-    session. Emitted every time Chrome is paused. Only emitted on Android
-    MultiWindow devices.
-
-    A MultiWindow session is any period of time that Chrome was not used in a
-    full screen mode but together with another Activity that is visible at the
-    same time. This is only supported in a few Android models.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.MobileMultiWindowSession" units="%"
-    expires_after="M80">
-  <obsolete>
-    Removed 7/2019. No longer tracked.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>tedchoc@chromium.org</owner>
-  <summary>
-    Android: percent of the screen available for Chrome during a multi-window
-    session. Emitted every time chrome is paused. Only emitted on Android
-    MultiWindow devices.
-
-    A multiwindow session is any period of time that Chrome was not used in full
-    screen mode but together with some other application that is visible at the
-    same time. This is only supported in a few Android models.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.NonMainIntentAction" enum="MobileStartingAction"
-    expires_after="2018-05-22">
-  <obsolete>
-    Removed and removed from the code 05/2018
-  </obsolete>
-  <owner>mariakhomenko@chromium.org</owner>
-  <summary>
-    Android: Records the first action the user does within 10s of starting
-    Chrome. Recorded in DocumentActivity and ChromeTabbedActivity only when the
-    starting intent is not of type MAIN, e.g. VIEW, etc.
-  </summary>
-</histogram>
-
-<histogram name="MobileStartup.TimeSinceLastUse" units="minutes"
-    expires_after="2018-05-22">
-  <obsolete>
-    Removed and removed from the code 05/2018
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The time since last use until Chrome is launched from the home
-    screen. This is measured from the time the last tab is closed until a Main
-    intent is received. Has a minute level precision for first 10 minutes
-    increasing exponentially till 30 days.
-
-    Note: this metric is broken in M63 and below and only reliable in M64+.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileStartup.ToolbarFirstDrawTime" units="ms"
-    expires_after="2018-06-28">
-  <obsolete>
-    Removed and renamed to MobileStartup.ToolbarFirstDrawTime2 due to double
-    reporting bug (see https://crbug.com/857508).
-  </obsolete>
-  <owner>yusufo@chromium.org</owner>
-  <summary>
-    Android: The time it takes from launch to the completion of first draw for
-    Toolbar. This excludes activity creation time spent in framework.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileStartup.ToolbarFirstDrawTime2" units="ms"
-    expires_after="2020-04-05">
-  <obsolete>
-    No longer useful, deprecated in M82.
-  </obsolete>
-  <owner>yusufo@chromium.org</owner>
-  <summary>
-    Android: The time it takes from launch to the completion of first draw for
-    Toolbar. This excludes activity creation time spent in framework.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileStartup.ToolbarFirstFocusStartupState"
-    enum="MobileStartupToolbarFirstFocusStartupState" expires_after="M82">
-  <obsolete>
-    No longer useful, deprecated in M82 (see https://crbug.com/1053190).
-  </obsolete>
-  <owner>mheikal@chromium.org</owner>
-  <summary>
-    Android: The state of chrome startup at the first time the user focuses the
-    omnibox, if the user does so within the first 30s of the launch (excluding
-    activity creation time spent in the framework).
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileStartup.ToolbarFirstFocusTime" units="ms"
-    expires_after="2018-06-28">
-  <obsolete>
-    Removed and renamed to MobileStartup.ToolbarFirstFocusTime2 due to double
-    reporting bug (see https://crbug.com/857508).
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Android: The time it takes from launch to the first time the user focuses
-    the omnibox if the user does so within first 30s of the launch. This
-    excludes activity creation time spent in framework.
-  </summary>
-</histogram>
-
-<histogram base="true" name="MobileStartup.ToolbarFirstFocusTime2" units="ms"
-    expires_after="M82">
-  <obsolete>
-    No longer useful, deprecated in M82.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Android: The time it takes from launch to the first time the user focuses
-    the omnibox if the user does so within first 30s of the launch. This
-    excludes activity creation time spent in framework.
-  </summary>
-</histogram>
-
-<histogram name="ModuleIntegrityVerification.Difference" units="bytes"
-    expires_after="2015-05-19">
-  <obsolete>
-    Removed and removed from code as of 05/2015.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <summary>
-    Represents the difference in bytes deemed modified by the two
-    ModuleIntegrityVerifier code paths. The suffix indicates which path had a
-    higher value. Logged when the ModuleIntegrityVerifier determines that a
-    module is different on disk and in memory after being triggered by an
-    incident and the reported byte count for both methods is different.
-  </summary>
-</histogram>
-
-<histogram name="ModuleIntegrityVerification.RelocationsUnorderedModuleIndex"
-    units="units" expires_after="2015-04-15">
-  <obsolete>
-    Removed 04/2015; replaced by
-    ModuleIntegrityVerification.RelocationsUnordered.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <summary>
-    Logged when the relocations in a module are not ordered causing the module
-    verification to abort. The value is the index of the affected module.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.MachPortRelay.BrokerError"
-    enum="MojoMachPortRelayBrokerError" expires_after="M77">
-  <obsolete>
-    The MachPortRelay was deleted in July 2019.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    Errors that the broker process encounters while trying to send or receive
-    Mach ports from a child process.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.MachPortRelay.ChildError"
-    enum="MojoMachPortRelayChildError" expires_after="M77">
-  <obsolete>
-    The MachPortRelay was deleted in July 2019.
-  </obsolete>
-  <owner>amistry@chromium.org</owner>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    Errors that a child process encounters while trying to receive Mach ports
-    from the broker process.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.Shell.ChildConnectionTime" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed 2/2018. Has not actually been collected for some time.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Measures the time it takes for a new child process to receive an
-    initialization request from the Mojo shell. This is precisely the duration
-    of the MojoShellConnectionImpl::BindToMessagePipe() call in ChildThreadImpl.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.System.GetParentPlatformHandleSyncTime" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed 2/2018. Data no longer useful.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Measures the time it takes for a child to receive its parent platform handle
-    synchronously from the broker on startup. This only applies to the subset of
-    platforms on which the sync broker is used.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.System.MessagesAcceptedPerEvent" units="units"
-    expires_after="2017-06-07">
-  <obsolete>
-    Removed as of 6/2017.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Number of internal Mojo system messages processed synchronously during a
-    single execution of NodeController::AcceptIncomingMessages(). This is called
-    any time an event requires internal Mojo system messages to be pumped.
-    Values below 4 are no longer logged.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.System.Node.ConnectedPeers" units="units"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed 2/2018. Data no longer useful.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Number of connected peer nodes tracked by a node. This is emitted any time a
-    peer is added to or dropped from a node.
-  </summary>
-</histogram>
-
-<histogram name="Mojo.System.Node.PendingChildren" units="units"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed 2/2018. Data no longer useful.
-  </obsolete>
-  <owner>rockot@chromium.org</owner>
-  <summary>
-    Number of connected pending child node connections tracked by a node. This
-    is emitted any time a parent-child node connection is initiated or dropped.
-  </summary>
-</histogram>
-
-<histogram name="MojoLevelDBEnv.IOError.BFE" enum="PlatformFileError"
-    expires_after="M82">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Errors (base::File::Error) encountered by a single leveldb method in
-    leveldb's Mojo environment.
-  </summary>
-</histogram>
-
-<histogram name="MojoLevelDBEnv.RetryRecoveredFromErrorIn"
-    enum="PlatformFileError" expires_after="M82">
-  <obsolete>
-    Removed April, 2020.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    When Mojo LevelDBEnv successfully retries an operation that had failed,
-    record the error from the most recent failed attempt.
-  </summary>
-</histogram>
-
-<histogram name="MojoLevelDBEnv.TimeUntilSuccessFor" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Removed in 2020-04.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Time Mojo LevelDBEnv slept before successfully completing this operation. 0
-    means success on the first try, as LevelDBEnv only sleeps when retries are
-    needed.
-  </summary>
-</histogram>
-
-<histogram name="Mouse.Sensitivity.Changed" enum="PointerSensitivity"
-    expires_after="2013-07-02">
-  <obsolete>
-    Removed as of 6/2013, replaced by Mouse.PointerSensitivity.Changed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Tracks mouse sensitivity setting.</summary>
-</histogram>
-
-<histogram name="Mouse.Sensitivity.Started" enum="PointerSensitivity"
-    expires_after="2013-07-02">
-  <obsolete>
-    Removed as of 6/2013, replaced by Mouse.PointerSensitivity.Started.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Tracks mouse sensitivity setting on startup.</summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseDownDuration_Click" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user mousedown-ed a link and when
-    the user clicked a link.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseDownFollowedByClick"
-    enum="MouseEventFollowedByClick" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For each click handled by an HTML anchor tag link, whether Blink saw a
-    mousedown event preceding it. This is only measured for clicks handled by
-    the anchor tag's default click event handler.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseDowns" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of mousedown events detected at HTML anchor-tag links' default
-    event handler.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseOverDuration_Click" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user mouseover-ed a link and when
-    the user clicked a link.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseOverDuration_NoClick" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user mouseover-ed a link and when
-    the user mouseout-ed a link without click.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.MouseOvers" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of mouseover events detected at HTML anchor-tag links' default
-    event handler.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.PreTapEventsFollowedByClick"
-    enum="PreTapEvents" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The tap gesture events detected before click at HTML anchor-tag links'
-    default event handler.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.TapDownDuration_Click" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time elapsed between when the user tapdown-ed a link and when
-    the user clicked a link.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.TapDowns" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of gesturetapdown events detected at HTML anchor-tag links'
-    default event handler.
-  </summary>
-</histogram>
-
-<histogram name="MouseEventPrefetch.TapUnconfirmeds" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of gesturetapunconfirmed events detected at HTML anchor-tag
-    links' default event handler.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.IIR_InputEventDelta" units="ms"
-    expires_after="2016-08-29">
-  <obsolete>
-    Removed 08/2016 due to lack of use (Histogram Eraser).
-  </obsolete>
-  <owner>lassey@google.com</owner>
-  <summary>
-    The time spent waiting for the renderer to acknowledge an input event.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RendererLaunchFirst" units="units"
-    expires_after="2014-08-13">
-  <obsolete>
-    Removed 2/2013, renamed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time it takes to spawn the first renderer subprocess (including sandbox
-    init).
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RendererLaunchSubsequent" units="units"
-    expires_after="2014-08-13">
-  <obsolete>
-    Removed 2/2013, renamed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time it takes to spawn renderer sub processes not counting the first
-    one.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RWH_HangMonitorUnresponsive" units="ms"
-    expires_after="2017-12-14">
-  <obsolete>
-    Removed 12/2017 due to lack of usage.
-  </obsolete>
-  <owner>amaralp@chromium.org</owner>
-  <summary>
-    The length of time the renderer is unresponsive according to the hang
-    monitor. Recorded when the renderer regains responsiveness.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RWH_InputEventDelta" units="ms"
-    expires_after="2014-09-02">
-  <obsolete>
-    renamed MPArch.IIR_InputEventDelta.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time spent waiting for the renderer to acknowledge an input event.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RWH_OnMsgPaintRect" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time spent inside RenderWidgetHost::OnMsgPaintRect.</summary>
-</histogram>
-
-<histogram name="MPArch.RWH_OnMsgResizeOrRepaintACK" units="units"
-    expires_after="2018-10-16">
-  <obsolete>
-    Removed 09/2018 as message no longer exists.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    The time delta for processing a paint message. On platforms that don't
-    support asynchronous painting, this is equivalent to
-    MPArch.RWH_TotalPaintTime.
-  </summary>
-</histogram>
-
-<histogram name="MPArch.RWH_OnMsgScrollRect" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time spent inside RenderWidgetHost::OnMsgScrollRect.</summary>
-</histogram>
-
-<histogram name="MPArch.RWH_OnMsgUpdateRect" units="units"
-    expires_after="2017-10-03">
-  <obsolete>
-    Removed 10/2017. Replaced with MPArch.RWH_OnMsgResizeOrRepaintACK.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="MPArch.RWHH_WhiteoutDuration" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time that the user sees a blank white page after switching to a
-    different tab, while the RenderWidgetHost receives data to paint from the
-    renderer process.
-  </summary>
-</histogram>
-
-<histogram name="MultiProfile.DiscardedTabsPerUser" units="units"
-    expires_after="2017-11-22">
-  <obsolete>
-    Removed 11/2017. Analysis confirms that the number of discards increases
-    with the number of logged in users. No action will be taken based on this
-    information.
-  </obsolete>
-  <owner>skuhne@chromium.org</owner>
-  <summary>
-    The relation of discarded tabs vs. the amount of simultaneous users. The
-    counts are the number of discards and the buckets are the number of users.
-    Since the count values are absolute numbers, they need to be normalized
-    before use - so divide the counts by the percentage of users per session
-    found under 'MultiProfile.UsersPerSessionIncremental'.
-  </summary>
-</histogram>
-
-<histogram name="MultiProfile.SessionMode" enum="MultiProfileSessionMode"
-    expires_after="2018-05-01">
-  <obsolete>
-    Removed 09/2017 when side-by-side multi-profile mode was removed. There is
-    now only one multi-profile mode (separate desktop). See the metric
-    'MultiProfile.UsersPerSessionIncremental' for overall usage of the
-    multi-profile feature on Chrome OS.
-  </obsolete>
-  <owner>skuhne@chromium.org</owner>
-  <summary>
-    The session counter for different multi profile modes which gets stored once
-    per session at the beginning of the session.
-  </summary>
-</histogram>
-
-<histogram name="MultiProfile.SigninUserUIPath"
-    enum="MultiProfileSigninUserAction" expires_after="2020-08-23">
-  <obsolete>
-    Retired in M86.
-  </obsolete>
-  <owner>skuhne@chromium.org</owner>
-  <summary>
-    Count the number of times each UI path is taken for signing into a new
-    account in a Chrome OS multiprofile session. UI paths include the system
-    tray and the user account switcher on the browser frame.
-  </summary>
-</histogram>
-
-<histogram name="MultiProfile.TeleportWindow"
-    enum="MultiProfileTeleportWindowAction" expires_after="2018-05-01">
-  <obsolete>
-    Removed 04/2018. Was not being maintained - some cases leading to teleport
-    were not captured. See counts of 'MultiProfile.TeleportWindowType' to assess
-    the usage of the teleport window feature.
-  </obsolete>
-  <owner>skuhne@chromium.org</owner>
-  <summary>
-    Counts the number of window teleportations when using separated desktop
-    mode.
-  </summary>
-</histogram>
-
-<histogram name="MultiProfile.UsersPerSession" units="units"
-    expires_after="2014-03-09">
-  <obsolete>
-    Removed 3/2014, renamed to MultiProfile.UsersPerSessionIncremental.
-  </obsolete>
-  <owner>skuhne@chromium.org</owner>
-  <summary>
-    The number of users simultaneously signed into a multiprofile session on
-    Chrome OS. This is recorded upon session end.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.ManifestDownloadTime" units="ms"
-    expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The time it took to download the manifset file for a Native Client module.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.NexeDownloadTime" units="ms" expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The time it took to download the main .nexe for a Native Client module.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.NexeSize" units="KB" expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The size of the main .nexe file downloaded for a Native Client module.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.NexeStartupTime" units="ms" expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The time it took between the Native Client plugin initialization and when
-    proxied execution of the NaCl module begins. This is the general startup
-    overhead of running as a NaCl module vs a trusted PPAPI plugin.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.NexeStartupTimePerMB" units="milliseconds/MB"
-    expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The time it took between the Native Client plugin initialization and when
-    proxied execution of the NaCl module begins. This is the general startup
-    overhead of running as a NaCl module vs a trusted PPAPI plugin.
-  </summary>
-</histogram>
-
-<histogram name="NaCl.OSArch" enum="NaClOSArchEnum" expires_after="2014-02-21">
-  <obsolete>
-    Removed 6/2011, renamed.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>The OS/Architecture of a nexe that was loaded.</summary>
-</histogram>
-
-<histogram name="NaCl.Startups" enum="NaClStartupEnum"
-    expires_after="2014-02-21">
-  <obsolete>
-    Removed 5/2011, data is duplicated by NaCl.NexeStartupTime, and normalizing
-    to 'tab opens' is unusual.
-  </obsolete>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    The number of times that Native Client has been started by loading a .nexe
-    compared to the number of times that a tab has been opened.
-  </summary>
-</histogram>
-
-<histogram name="NativeAppLauncher.InstallationDetected"
-    enum="BooleanInstalled" expires_after="2019-12-31">
-  <obsolete>
-    Removed in M77. This metric is not sufficiently used.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    The number of times that Chrome detected that a request to download and
-    install another Google iOS app completed successfully.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.BackForward.IsSameProcess"
-    enum="NavigationIsSameProcess" expires_after="2018-02-17">
-  <obsolete>
-    Removed 2018-02, replaced by Navigation.IsSameProcess.BackForward.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Whether the back-forward navigation lead to a change of process or not.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.BackForward.ReadyToCommitUntilCommit" units="ms"
-    expires_after="2018-02-17">
-  <obsolete>
-    Removed 2018-02, replaced by
-    Navigation.ReadyToCommitUntilCommit.BackForward.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    The time needed to commit a back forward-navigation once it is ready to
-    commit. This is the time between ReadyToCommit and DidFinishNavigation (for
-    a navigation that commits).
-  </summary>
-</histogram>
-
-<histogram name="Navigation.BackForward.TimeToReadyToCommit" units="ms"
-    expires_after="2018-02-17">
-  <obsolete>
-    Removed 2018-02, replaced by Navigation.TimeToReadyToCommit.BackForward.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    The time delta between the start of a back-forward navigation and the time
-    it was ready to commit.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.ClientRedirectCycle.RedirectToReferrer"
-    enum="Boolean" expires_after="M79">
-  <obsolete>
-    Removed 11/2019 in favor of
-    Previews.DeferAllScript.RedirectLoopDetectedUsingCache.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records when a client redirect cycle that is directly back to the referrer
-    is detected.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.DeferredDocumentLoading.StatesV1"
-    enum="DocumentStateForDeferredLoading" expires_after="2016-10-21">
-  <obsolete>
-    Removed 10/2016 in favor of Navigation.DeferredDocumentLoading.StatesV2.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Why and if cross-origin documents would be loaded in a world where we defer
-    loading until they are visible.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.DeferredDocumentLoading.StatesV2"
-    enum="DocumentStateForDeferredLoadingV2" expires_after="2016-10-27">
-  <obsolete>
-    Removed 10/2016 in favor of Navigation.DeferredDocumentLoading.StatesV3.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Why and if cross-origin documents would be loaded if we were to defer
-    loading as long as possible.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.DeferredDocumentLoading.StatesV3"
-    enum="DocumentStateForDeferredLoadingV3" expires_after="2017-02-28">
-  <obsolete>
-    Removed 3/2017 in favor of Navigation.DeferredDocumentLoading.StatesV4.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Why and if cross-origin documents would be loaded if we were to defer
-    loading as long as possible. Difference from V2: frames positioned both
-    above and to the left of the page have their own bucket and are no longer
-    counted in the &quot;above&quot; bucket.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.DeferredDocumentLoading.StatesV4"
-    enum="DocumentStateForDeferredLoadingV4" expires_after="2018-11-01">
-  <obsolete>
-    Removed 11/2018 because LazyLoading has real stats now.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Why and if cross-origin documents would be loaded if we were to defer
-    loading as long as possible. Changes from V3: replace detailed reasons with
-    summaries for four strategies. E.g. any document that would load under a
-    strategy of loading when a frame is two screens away is logged to the
-    WouldLoad2Screens AND WouldLoad3Screens bucket. We only record documents
-    below the current viewport, not to the right of it.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.DownloadPolicy" enum="NavigationDownloadPolicy"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed 03/2019 in favor of
-    Navigation.DownloadPolicy.LogArbitraryPolicyPerDownload and
-    Navigation.DownloadPolicy.LogPerPolicyApplied.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    When a navigation results in a download, logs the download policy applied to
-    that navigation.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.FrameHasEmbeddedCredentials" enum="Boolean"
-    expires_after="2017-03-24">
-  <obsolete>
-    Removed 03/2017 in Issue 703460.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    Whether the navigation was to a URL that had embedded credentials.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Intercept.Ignored" enum="Boolean"
-    expires_after="M80">
-  <obsolete>
-    Removed May 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Records whether the InterceptNavigationThrottle ignored the navigation. This
-    is recorded at the end of every navigation the throttle observes.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Intercept.WillStart" units="microseconds"
-    expires_after="M80">
-  <obsolete>
-    Removed May 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The microseconds it takes for the InterceptNavigationThrottle to determine
-    if the navigation should be ignored, at WillStartRequest time.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.IOSWKWebViewSlowFastBackForward"
-    enum="BackForwardNavigationType" expires_after="M84">
-  <obsolete>
-    Removed from code April 2020.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    Counts slow/fast back/forward WKWebView navigations on iOS. Fast navigation
-    is a back/forward navigation done with WKBackForwardList.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.IsMobileOptimized" enum="BooleanIsMobileOptimized"
-    expires_after="2018-03-05">
-  <obsolete>
-    Removed from code March 2018.
-  </obsolete>
-  <owner>cjhopman@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    Signifies whether a succesfully finished page load for the main frame
-    content width fits within the device width and/or has a fixed page scale.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameHasEmbeddedCredentials" enum="Boolean"
-    expires_after="2017-03-24">
-  <obsolete>
-    Removed 03/2017 in Issue 703460.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    Whether the main-frame navigation was to a URL that had embedded
-    credentials.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameHasRTLDomain" enum="Boolean"
-    expires_after="M88">
-  <obsolete>
-    Removed from code June 2020. Replaced with
-    Navigation.MainFrameHasRTLDomain2. Navigation.MainFrameHasRTLDomain was
-    logged differently for iOS and Navigation.MainFrameHasRTLDomain2 does not
-    have this discrepancy.
-  </obsolete>
-  <owner>cthomp@chromium.org</owner>
-  <owner>security-enamel@chromium.org</owner>
-  <summary>
-    Whether the main-frame navigation was to a URL with an RTL domain name. This
-    is only recorded for finished navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameHasRTLDomainDifferentPage" enum="Boolean"
-    expires_after="M88">
-  <obsolete>
-    Removed from code June 2020. Replaced with
-    Navigation.MainFrameHasRTLDomainDifferentPage2.
-    Navigation.MainFrameHasRTLDomainDifferentPage was logged differently for iOS
-    and Navigation.MainFrameHasRTLDomainDifferentPage2 does not have this
-    discrepancy.
-  </obsolete>
-  <owner>cthomp@chromium.org</owner>
-  <owner>security-enamel@chromium.org</owner>
-  <summary>
-    Whether the main-frame navigation was to a URL with an RTL domain name,
-    recorded for each main-frame avigation that replaces a document object. This
-    is not reported for reference fragment navigations, pushState/replaceState
-    or same page history navigation. This is only recorded for finished
-    navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameProfileType" enum="BrowserProfileType"
-    expires_after="2021-06-01">
-  <obsolete>
-    Removed from code June 2020. Replaced with Navigation.MainFrameProfileType2.
-    Navigation.MainFrameProfileType was logged differently for iOS and
-    Navigation.MainFrameProfileType2 does not have this discrepancy.
-  </obsolete>
-  <owner>rhalavati@chromium.org</owner>
-  <owner>chrome-privacy-core@google.com</owner>
-  <summary>
-    The browser profile type for each main-frame navigation, recorded after
-    navigation completion, including NTP.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameScheme" enum="NavigationScheme"
-    expires_after="M85">
-  <obsolete>
-    Removed from code June 2020. Replaced with Navigation.MainFrameScheme2.
-    Navigation.MainFrameScheme was logged differently for iOS and
-    Navigation.MainFrameScheme2 does not have this discrepancy.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The scheme of the URL for each main-frame navigation. This is only recorded
-    for finished navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameScheme.DataUrl.MimeType"
-    enum="DataUrlMimeType" expires_after="2017-10-06">
-  <obsolete>
-    Removed from code October 2017.
-  </obsolete>
-  <owner>meacer@chromium.org</owner>
-  <summary>
-    The mime type of the data: URL for each main-frame navigation. This only
-    contains mime types that can run scripts. This is only recorded for finished
-    navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameSchemeDifferentPage"
-    enum="NavigationScheme" expires_after="M85">
-  <obsolete>
-    Removed from code June 2020. Replaced with
-    Navigation.MainFrameSchemeDifferentPage2.
-    Navigation.MainFrameSchemeDifferentPage was logged differently for iOS and
-    Navigation.MainFrameSchemeDifferentPage2 does not have this discrepancy.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The scheme of the URL for each main-frame navigation that replaces a
-    document object. This is not reported for reference fragment navigations,
-    pushState/replaceState or same page history navigation. This is only
-    recorded for finished navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameSchemeDifferentPageOTR"
-    enum="NavigationScheme" expires_after="M85">
-  <obsolete>
-    Removed from code June 2020. Replaced with
-    Navigation.MainFrameSchemeDifferentPageOTR2.
-    Navigation.MainFrameSchemeDifferentPageOTR was logged differently for iOS
-    and Navigation.MainFrameSchemeDifferentPageOTR2 does not have this
-    discrepancy.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The scheme of the URL for each main-frame navigation that replaces a
-    document object while in incognito. This is not reported for reference
-    fragment navigations, pushState/replaceState or same page history
-    navigation. This is only recorded for finished navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.MainFrameSchemeOTR" enum="NavigationScheme"
-    expires_after="M85">
-  <obsolete>
-    Removed from code June 2020. Replaced with Navigation.MainFrameSchemeOTR2.
-    Navigation.MainFrameSchemeOTR was logged differently for iOS and
-    Navigation.MainFrameSchemeOTR2 does not have this discrepancy.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The scheme of the URL for each main-frame navigation while in incognito.
-    This is only recorded for finished navigations and not attempts.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.ReadyToCommitUntilCommit" units="ms"
-    expires_after="2019-01-04">
-  <obsolete>
-    Removed 2019-01 (M73), replaced by Navigation.ReadyToCommitUntilCommit2
-    (same histogram, different bucketing).
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The time needed to commit a navigation once it is ready to commit. This is
-    the time between ReadyToCommit and DidFinishNavigation (for a navigation
-    that commits).
-  </summary>
-</histogram>
-
-<histogram name="Navigation.RedirectChainSize" units="characters"
-    expires_after="2019-01-14">
-  <obsolete>
-    Removed January 2019 because it wasn't used.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <summary>
-    Total length of the redirect URL strings in navigation entry. Logged when
-    entry is committed.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Reload.ReloadMainResourceToReloadDuration"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Reported when a user triggers reload without any other navigations after the
-    previous reload in the same page, and the previous reload variant was
-    RELOAD_MAIN_RESOURCE. Duration time between two reloads is reported.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Reload.ReloadToReloadDuration" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Reported when a user triggers reload without any other navigations after the
-    previous reload in the same page. Duration time between two reloads is
-    reported.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Renderer.ReadyToCommitUntilCommit" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed October 2019
-  </obsolete>
-  <owner>arthursonzogni@chromium.org</owner>
-  <owner>clamy@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The time needed in the renderer process between receiving the message to
-    commit the navigation until the navigation has committed.
-  </summary>
-</histogram>
-
-<histogram
-    name="Navigation.ResourceHandler.ProceedWithResponseUntilFirstReadCompleted"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Obsolete as of 06/2018.
-  </obsolete>
-  <owner>arthursonzogni@chromium.org</owner>
-  <owner>clamy@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The time delta between when the ResourceHandler is allowed to read the
-    response's body and when it has completed its first read.
-  </summary>
-</histogram>
-
-<histogram
-    name="Navigation.ResourceHandler.ResponseStartedUntilProceedWithResponse"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Obsolete as of 06/2018.
-  </obsolete>
-  <owner>arthursonzogni@chromium.org</owner>
-  <owner>clamy@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The time delta between when the ResourceHandler started receiving the
-    response and when it is allowed to read the response's body.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.SandboxFrameBackForwardStaysWithinSubtree"
-    enum="BooleanWithinSubtree" expires_after="M78">
-  <obsolete>
-    Removed as of 09/2019.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    Counts session history navigations in sandboxed iframes that disallow top
-    level navigation, for cases that only stay within the iframe's subtree vs
-    those that affect other frames instead or as well.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Scheduled.MaybeCausedAbort"
-    enum="ScheduledNavigationType" expires_after="2018-08-30">
-  <obsolete>
-    Removed August 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    window.location and other scheduled navigation changes can cause the current
-    provisional load to be aborted. Many times these are initiated without user
-    gesture. This histogram logs counts of the various aborters.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Scheduled.MaybeCausedAbort.Time" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed August 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    window.location and other scheduled navigation changes can cause the current
-    provisional load to be aborted. Many times these are initiated without user
-    gesture. This histogram logs the time between the aborted navigation start
-    and the scheduled navigation start, if the aborted navigation has a non-zero
-    navigationStart value.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.SchemePerUniqueOrigin" enum="NavigationScheme"
-    expires_after="2017-04-19">
-  <obsolete>
-    Removed 4/2017 in Issue 712843.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The scheme of the URL for the first main-frame navigation per origin per
-    non-OffTheRecord session.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.SchemePerUniqueOriginOTR" enum="NavigationScheme"
-    expires_after="2017-04-19">
-  <obsolete>
-    Removed 4/2017 in Issue 712843.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The scheme of the URL for the first main-frame navigation per origin per
-    OffTheRecord session.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Start.RendererBrowserDifference.Negative"
-    units="ms" expires_after="2016-12-22">
-  <obsolete>
-    Data collected and posted on issue 675833.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The difference between Now() in the renderer and browser_navigation_start
-    for browser-initiated navigations if the difference is negative. This value
-    should ideally only reflect the IPC time between the browser process and
-    renderer process, but in practice could be skewed by inter-process timing
-    errors. If the clocks used for TimeTicks are monotonic across processes, all
-    samples should fall into the Positive bucket.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.Start.RendererBrowserDifference.Positive"
-    units="ms" expires_after="2016-12-22">
-  <obsolete>
-    Data collected and posted on issue 675833.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The difference between Now() in the renderer and browser_navigation_start
-    for browser-initiated navigations if the difference is positive. This value
-    should ideally only reflect the IPC time between the browser process and
-    renderer process, but in practice could be skewed by inter-process timing
-    errors. If the clocks used for TimeTicks are monotonic across processes, all
-    samples should fall into the Positive bucket.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.TimeToCommit" units="ms" expires_after="2018-03-30">
-  <obsolete>
-    Removed March 2018 in favor of Navigation.StartToCommit variants. Removed
-    from code in November 2020 (M89).
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <summary>
-    Time between the start of a browser-started navigation request in and its
-    commit.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.TimeToReadyToCommit" units="ms"
-    expires_after="2019-01-04">
-  <obsolete>
-    Removed 2019-01 (M73), replaced by Navigation.TimeToReadyToCommit2 (same
-    histogram, different bucketing).
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    The time delta between the start of a navigation and the time it is ready to
-    commit.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.UI_OnCommitProvisionalLoad.Intent" units="ms"
-    expires_after="2018-06-19">
-  <obsolete>
-    Removed 06/2018 in favor of PageLoad metrics.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Obsolete. Time between receiving an Android Intent and the navigation
-    commit.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.UI_OnCommitProvisionalLoad.Link" units="ms"
-    expires_after="2018-06-19">
-  <obsolete>
-    Removed 06/2018 in favor of PageLoad metrics.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Obsolete. Time between clicking on a link and the navigation commit.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.UI_OnLoadComplete.Intent" units="ms"
-    expires_after="2018-06-19">
-  <obsolete>
-    Removed 06/2018 in favor of PageLoad metrics.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Obsolete. Time between receiving an Android intent and the document load
-    complete event for a navigation in the main frame.
-  </summary>
-</histogram>
-
-<histogram name="Navigation.UI_OnLoadComplete.Link" units="ms"
-    expires_after="2018-06-19">
-  <obsolete>
-    Removed 06/2018 in favor of PageLoad metrics.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Obsolete. Time between clicking on a link and the document load complete
-    event for a navigation in the main frame.
-  </summary>
-</histogram>
-
-<histogram base="true" name="NavigationPredictor.AccuracyActionTaken"
-    enum="NavigationPredictorAccuracyActionTaken" expires_after="M80">
-  <obsolete>
-    Removed 10/2019 Milestone 80.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Tracks the accuracy of the action taken by navigation predictor. Recorded at
-    the time of page click.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOn2G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on a 2G connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOn3G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on a 3G connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOn4G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on a 4G connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOnBluetooth" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on a Bluetooth
-    connection, before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOnEthernet" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on an Ethernet
-    connection, before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOnNone" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen while the
-    NetworkChangeNotifier thought there was no network connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOnUnknown" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on an unknown connection
-    type, before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FastestRTTOnWifi" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time seen on a Wifi connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOn2G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to a 2G connection and receiving the first network
-    data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOn3G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to a 3G connection and receiving the first network
-    data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOn4G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to a 4G connection and receiving the first network
-    data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOnBluetooth" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to a Bluetooth connection and receiving the first
-    network data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOnEthernet" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to an Ethernet connection and receiving the first
-    network data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOnNone" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between disconnecting and receiving the first network data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOnUnknown" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to an unknown connection type and receiving the first
-    network data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.FirstReadOnWifi" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between switching to a Wifi connection and receiving the first network
-    data.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOn2G" units="KB" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via a 2G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOn3G" units="KB" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via a 3G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOn4G" units="KB" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via a 4G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOnBluetooth" units="KB"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via a Bluetooth connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOnEthernet" units="KB"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via an Ethernet connection,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOnNone" units="KB"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while the NetworkChangeNotifier thought there
-    was no network connection, before the NetworkChangeNotifier detected a
-    connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOnUnknown" units="KB"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via an unknown connection type,
-    before the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.KBTransferedOnWifi" units="KB"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How much data was transfered while connected via a Wifi connection, before
-    the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOn2G" units="Kbps" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on a 2G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOn3G" units="Kbps" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on a 3G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOn4G" units="Kbps" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on a 4G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOnBluetooth" units="Kbps"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on a Bluetooth connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOnEthernet" units="Kbps"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on an Ethernet connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOnNone" units="Kbps" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen while the NetworkChangeNotifier
-    thought there was no network connection, before the NetworkChangeNotifier
-    detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOnUnknown" units="Kbps"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on an unknown connection type, before
-    the NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.PeakKbpsOnWifi" units="Kbps" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Rough estimate of peak throughput seen on a Wifi connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOn2G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via a 2G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOn3G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via a 3G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOn4G" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via a 4G connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOnBluetooth" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via a Bluetooth connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOnEthernet" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via an Ethernet connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOnNone" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent disconnected, before the NetworkChangeNotifier detected a
-    connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOnUnknown" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via an unknown connection type, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.CM.TimeOnWifi" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long was spent connected via a Wifi connection, before the
-    NetworkChangeNotifier detected a connectivity change.
-
-    This metric is recorded when the NetworkChangeNotifier detects a
-    connectivity change. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NCN.ConnectionTypeChangeToIPAddressChange" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time from ConnectionTypeChanged message until IPAddressChanged message.
-  </summary>
-</histogram>
-
-<histogram name="NCN.DNSConfigChange" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Time between DNS configuration change messages.</summary>
-</histogram>
-
-<histogram name="NCN.GetActiveNetworkInfoResult"
-    enum="NCNGetActiveNetworkInfoResult" expires_after="2017-05-11">
-  <obsolete>
-    Removed 05/2017 in Issue 677365.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the result of querying the network info of the current active
-    network. Useful for investigating how frequently the current network was
-    unblocked, and why it was not unblocked. See http://crbug.com/677365.
-  </summary>
-</histogram>
-
-<histogram name="NCN.GetConnectionTypeTime" units="ms" expires_after="M85">
-  <obsolete>
-    Code removed long ago.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long does each call to NetworkChangeNotifier::GetConnectionType() take.
-  </summary>
-</histogram>
-
-<histogram name="NCN.getNetInfo1stSuccess"
-    enum="BooleanAvoidedNullPointerException" expires_after="2017-05-12">
-  <obsolete>
-    Removed 5/2017 for Issue 592131.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    True if the first call to ConnectivityManager.getNetworkInfo(Network) did
-    not throw NullPointerException, false if it did. Useful for investigating
-    and avoiding unexpected exceptions, see http://crbug.com/592131.
-  </summary>
-</histogram>
-
-<histogram name="NCN.getNetInfo2ndSuccess"
-    enum="BooleanAvoidedNullPointerException" expires_after="2017-05-12">
-  <obsolete>
-    Removed 5/2017 for Issue 592131.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Recorded after the first call to ConnectivityManager.getNetworkInfo(Network)
-    threw a NullPointerException. True if the second call to
-    ConnectivityManager.getNetworkInfo(Network) did not throw
-    NullPointerException, false if it did. Useful for investigating and avoiding
-    unexpected exceptions, see http://crbug.com/592131.
-  </summary>
-</histogram>
-
-<histogram name="NCN.getWifiInfo1stSuccess"
-    enum="BooleanAvoidedNullPointerException" expires_after="2017-05-12">
-  <obsolete>
-    Removed 5/2017 for Issue 592131.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    True if the first call to WifiManager.getConnectionInfo() did not throw
-    NullPointerException, false if it did. Useful for investigating and avoiding
-    unexpected exceptions, see http://crbug.com/592131.
-  </summary>
-</histogram>
-
-<histogram name="NCN.getWifiInfo2ndSuccess"
-    enum="BooleanAvoidedNullPointerException" expires_after="2017-05-12">
-  <obsolete>
-    Removed 5/2017 for Issue 592131.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Recorded after the first call to WifiManager.getConnectionInfo() threw a
-    NullPointerException. True if the second call to
-    ConnectivityManager.getNetworkInfo(Network) did not throw
-    NullPointerException, false if it did. Useful for investigating and avoiding
-    unexpected exceptions, see http://crbug.com/592131.
-  </summary>
-</histogram>
-
-<histogram name="NCN.IPAddressChange" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Time between IP address change messages.</summary>
-</histogram>
-
-<histogram name="NCN.IPAddressChangeToConnectionTypeChange" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time from IPAddressChanged message until ConnectionTypeChanged message.
-  </summary>
-</histogram>
-
-<histogram name="NCN.NetworkOfflineChange" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between going online until we go offline change messages, using new
-    filtered signal.
-  </summary>
-</histogram>
-
-<histogram name="NCN.NetworkOnlineChange" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between going offline until we go online change messages, using new
-    filtered signal.
-  </summary>
-</histogram>
-
-<histogram name="NCN.OfflineChange" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between going online until we go offline change messages.
-  </summary>
-</histogram>
-
-<histogram name="NCN.OfflineDataRecv" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between when we thought we went offline and when we received some
-    network data (a URLRequest read completed).
-  </summary>
-</histogram>
-
-<histogram name="NCN.OfflineDataRecvAny5sBeforeOnline" units="units"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Count of how many times we received network data (a URLRequest read
-    completed) while offline when some data was received at most five seconds
-    before going online.
-  </summary>
-</histogram>
-
-<histogram name="NCN.OfflineDataRecvUntilOnline" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between when we received the last network data (a URLRequest read
-    completed) while offline and when we thought we went online.
-  </summary>
-</histogram>
-
-<histogram name="NCN.OfflinePolls" units="units" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Count of how many times we polled the online/offline status before detecting
-    an offline to online transition.
-  </summary>
-</histogram>
-
-<histogram name="NCN.OnlineChange" units="ms" expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between going offline until we go online change messages.
-  </summary>
-</histogram>
-
-<histogram name="NCN.PollingOfflineDataRecv" units="ms"
-    expires_after="2018-06-27">
-  <obsolete>
-    Removed 6/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Time between when we thought we went offline and when we received some
-    network data (a URLRequest read completed), while polling
-    NetworkChangeNotifier::GetConnectionType() still told us we were offline.
-  </summary>
-</histogram>
-
-<histogram name="Net.AlternateProtocolUsage.1000Truncated"
-    enum="AlternateProtocolUsage" expires_after="2014-10-24">
-  <obsolete>
-    Removed 10/2014.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Breakdown of how requests which could potentially make use of an alternate
-    protocol use or don't use the protocol. Loaded data for 1000 servers and we
-    have persisted 1000 MRU servers.
-  </summary>
-</histogram>
-
-<histogram name="Net.AlternateProtocolUsage.200Truncated"
-    enum="AlternateProtocolUsage" expires_after="2014-10-24">
-  <obsolete>
-    Removed 10/2014.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Breakdown of how requests which could potentially make use of an alternate
-    protocol use or don't use the protocol. Loaded data for 200 servers and we
-    have persisted 1000 MRU servers.
-  </summary>
-</histogram>
-
-<histogram name="Net.AlternativeProxyFailed" enum="NetErrorCodes"
-    expires_after="M82">
-  <obsolete>
-    Obsoleted in April 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Positive net error codes that failed alternative proxy requests end with.
-    Recorded when an alternative job fails, whether or not the main job
-    succeeds.
-
-    As of M66 this superceded DataReductionProxy.Quic.OnAlternativeProxyBroken.
-  </summary>
-</histogram>
-
-<histogram name="Net.AlternativeServiceServers.MoreOrEqualCacheEntries"
-    units="units" expires_after="2018-08-30">
-  <obsolete>
-    Removed 2019/8.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The difference between the size of alternative service mappings in cache and
-    preferences. This tracks zero or negative values (when the difference
-    between preferences size is less than or equal to memory cache size).
-    Positive values are tracked by
-    Net.AlternativeServiceServers.MorePrefsEntries.
-  </summary>
-</histogram>
-
-<histogram name="Net.AlternativeServiceServers.MorePrefsEntries" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019/8.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The difference between the size of alternative service mappings in
-    preferences and cache. This tracks positive values (when the difference
-    between preferences size is greater than memory cache size). Non positive
-    values are tracked by Net.AlternativeServiceServers.MoreOrEqualCacheEntries.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_PendingDataCount" units="units"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of unacknowledged ResourceMsg_DataReceived messages. This message
-    is sent once per chunk of data read from the network.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_PendingDataCount_WhenFull"
-    units="units" expires_after="2015-03-24">
-  <obsolete>
-    Removed 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of unacknowledged ResourceMsg_DataReceived messages at the point
-    where we pause network loading.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_RedirectHopTime" units="ms"
-    expires_after="2015-03-31">
-  <obsolete>
-    Data collection finished on 2015-03-31.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The time between the call of AsyncResourceHandler::OnRequestRedirected and
-    the FollowRedirect IPC message from ResourceHost, that is, the length of the
-    redirect browser-renderer-browser hop.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_SharedIOBuffer_Alloc" units="bytes"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The size of a SharedIOBuffer allocation.</summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_SharedIOBuffer_Used" units="bytes"
-    expires_after="2015-03-24">
-  <obsolete>
-    Removed 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of bytes copied into a SharedIOBuffer.</summary>
-</histogram>
-
-<histogram name="Net.AsyncResourceHandler_SharedIOBuffer_UsedPercentage"
-    units="%" expires_after="2015-03-24">
-  <obsolete>
-    Removed 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The percentage of a SharedIOBuffer allocation that is actually used.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncRevalidation.ReadError" enum="NetErrorCodes"
-    expires_after="2018-08-06">
-  <obsolete>
-    Removed in March 2017. See https://crbug.com/700568.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Counts of error codes received while reading the body of an async
-    revalidation before getting a response. Only async revalidations that had a
-    read error are counted.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncRevalidation.ResponseError" enum="NetErrorCodes"
-    expires_after="2018-08-06">
-  <obsolete>
-    Removed in March 2017. See https://crbug.com/700568.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Counts of error codes received while performing an async revalidation before
-    getting a response. Only async revalidations that had in a response error
-    are counted.
-  </summary>
-</histogram>
-
-<histogram name="Net.AsyncRevalidation.Result" enum="AsyncRevalidationResult"
-    expires_after="2018-08-06">
-  <obsolete>
-    Removed in March 2017. See https://crbug.com/700568.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    The result of an async revalidation resulting from application of the
-    Cache-Control: stale-while-revalidate directive. All async revalidations are
-    counted.
-  </summary>
-</histogram>
-
-<histogram name="Net.AuthGenerateToken_basic" units="ms"
-    expires_after="2014-09-09">
-  <obsolete>
-    Removed 01/2011 in https://crrev.com/70740
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time to generate a Basic HTTP authentication token.</summary>
-</histogram>
-
-<histogram name="Net.AuthGenerateToken_digest" units="ms"
-    expires_after="2014-09-09">
-  <obsolete>
-    Removed 01/2011 in https://crrev.com/70740
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time to generate a Digest HTTP authentication token.</summary>
-</histogram>
-
-<histogram name="Net.AuthGenerateToken_negotiate" units="ms"
-    expires_after="2014-09-09">
-  <obsolete>
-    Removed 01/2011 in https://crrev.com/70740
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time to generate a Negotiate (or SPNEGO) HTTP authentication token.
-  </summary>
-</histogram>
-
-<histogram name="Net.AuthGenerateToken_ntlm" units="ms"
-    expires_after="2014-09-09">
-  <obsolete>
-    Removed 01/2011 in https://crrev.com/70740
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time to generate an NTLM HTTP authentication token.</summary>
-</histogram>
-
-<histogram name="Net.AutoReload.CountAtStop" units="units" expires_after="M77">
-  <obsolete>
-    Removed and removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Number of times auto-reload has been attempted before auto-reload stopped
-    without succeeding, either because the stop button was pressed or because
-    the renderer was destroyed.
-  </summary>
-</histogram>
-
-<histogram name="Net.AutoReload.CountAtSuccess" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed and removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Number of times auto-reload had to attempt to reload a page before
-    succeeding.
-  </summary>
-</histogram>
-
-<histogram name="Net.AutoReload.ErrorAtFirstSuccess" enum="NetErrorCodes"
-    expires_after="M80">
-  <obsolete>
-    Removed and removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Original error code that started an auto-reload which then succeeded on the
-    first attempt.
-  </summary>
-</histogram>
-
-<histogram name="Net.AutoReload.ErrorAtStop" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed and removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Error code, if any, when auto-reload stopped without succeeding, either
-    because the stop button was pressed or because the renderer was destroyed.
-  </summary>
-</histogram>
-
-<histogram name="Net.AutoReload.ErrorAtSuccess" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed and removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Original error code that started an auto-reload which then eventually
-    succeeded.
-  </summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.ReceivedBytes" units="bytes"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Number of bytes received over this stream.</summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.SentBytes" units="bytes"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Number of bytes sent over this stream.</summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.TimeToReadEnd" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long it takes from starting the request to reading the end of the
-    response.
-  </summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.TimeToReadStart" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long it takes from starting the request to reading the start of the
-    response.
-  </summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.TimeToSendEnd" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long it takes from starting the request to when the last byte is sent.
-  </summary>
-</histogram>
-
-<histogram name="Net.BidirectionalStream.TimeToSendStart" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2020. Not used in active investigations.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    How long it takes from starting the request to when we can start sending
-    data.
-  </summary>
-</histogram>
-
-<histogram name="Net.CacheState.AllBytes" units="units"
-    expires_after="2016-08-02">
-  <obsolete>
-    Part of a concluded experiment, 2016-08-02.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>Counts of response bytes by cache state.</summary>
-</histogram>
-
-<histogram name="Net.CacheState.AllRequests" enum="NetCacheState"
-    expires_after="2016-10-27">
-  <obsolete>
-    Part of a concluded experiment, 2016-08-02.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    State of the cache for a request, delta-encoding eligible or otherwise.
-  </summary>
-</histogram>
-
-<histogram name="Net.CacheState.EncodeableBytes" units="units"
-    expires_after="2016-10-27">
-  <obsolete>
-    Part of a concluded experiment, 2016-08-02.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    Counts of response bytes by cache state for delta-encoding eligible
-    requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.CacheState.EncodeableRequests" enum="NetCacheState"
-    expires_after="2016-08-02">
-  <obsolete>
-    Part of a concluded experiment, 2016-08-02.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>State of the cache for a delta-encoding eligible request.</summary>
-</histogram>
-
-<histogram name="Net.CertCommonNameFallback" enum="BooleanCommonNameMatch"
-    expires_after="M85">
-  <obsolete>
-    Fallback code removed 2018-01-23.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether the certificate common name was used for matching the hostname,
-    instead of the subjectAlternativeName.
-
-    Measures results for all CAs (internal and publicly-trusted).
-  </summary>
-</histogram>
-
-<histogram name="Net.CertCommonNameFallbackPrivateCA"
-    enum="BooleanCommonNameMatch" expires_after="M85">
-  <obsolete>
-    Fallback code removed 2018-01-23.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether the certificate common name was used for matching the hostname,
-    instead of the subjectAlternativeName.
-
-    Measures results ony for internal (non-publicly-trusted) CAs.
-  </summary>
-</histogram>
-
-<histogram name="Net.Certificate.ClientCertDialogCount.Android" units="dialogs"
-    expires_after="2020-03-14">
-  <obsolete>
-    Removed 03/2020, since the client cert dialog capping logic has been in
-    place for a year now without any problems.
-  </obsolete>
-  <owner>dmcardle@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    As of 03/2019, abusive sites can create a nuisance for Android users by
-    repeatedly displaying client certificate request dialogs. This histogram
-    records how many client certificate request dialogs were displayed to the
-    user. At first, we would like to get a handle on the number of request
-    dialogs displayed by sites in the wild. Once we have sufficient data, we
-    will impose some limits to prevent abuse without breaking legitimate sites.
-
-    This metric is emitted whenever a new main frame navigation commits and
-    whenever a WebContents is destroyed.
-
-    https://crbug.com/817208
-  </summary>
-</histogram>
-
-<histogram name="Net.Certificate.SHA1.MainFrame" enum="SHA1Status"
-    expires_after="2017-06-12">
-  <obsolete>
-    Removed 06/2017 as SHA-1 was successfully disabled in 01/2017.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether or not SHA-1 was present in a resource fetched for the main frame,
-    and if so, what its maximum validity period was.
-  </summary>
-</histogram>
-
-<histogram name="Net.Certificate.SHA1.Subresource" enum="SHA1Status"
-    expires_after="2017-06-12">
-  <obsolete>
-    Removed 06/2017 as SHA-1 was successfully disabled in 01/2017.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether or not SHA-1 was present in a subresource fetch, and if so, what its
-    maximum validity period was.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificatePinSuccess" enum="BooleanSuccess"
-    expires_after="2013-04-09">
-  <obsolete>
-    Renamed to Net.PublicKeyPinSuccess 28 Oct 2011.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    A validated certificate chain may be subject to additional
-    &quot;pinning&quot; requirements on a per-domain basis. This records the
-    fraction of successful matches between a certificate chain and a pin list.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.CanInclusionCheckSCT"
-    enum="SCTCanBeChecked" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether an observed Signed Certificate Timestamp (SCT) can be checked for
-    inclusion. An SCT can be checked for inclusion if the client has a valid
-    Signed Tree Head (STH) and the STH currently known to the client was issued
-    24 hours after the timestamp in the SCT (24 hours being the typical Maximum
-    Merge Delay).
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.ConnectionComplianceStatus.QUIC"
-    enum="CTComplianceStatus" expires_after="2017-11-30">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.ConnectionComplianceStatus2
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The compliance of each QUIC connection with the Certificate Transparency
-    policy, recorded once on connection setup unless CT evaluation has been
-    disabled for that connection or the certificate is invalid. Connections can
-    be compliant, or they can be non-compliant for one of several reasons (not
-    enough Signed Certificate Timestamps [SCTs], not diverse enough SCTs, or the
-    build was old so CT compliance wasn't checked).
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.ConnectionComplianceStatus.SSL"
-    enum="CTComplianceStatus" expires_after="2017-11-30">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.ConnectionComplianceStatus2
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The compliance of each SSL connection with the Certificate Transparency
-    policy, recorded once on connection setup unless CT evaluation has been
-    disabled for that connection or the certificate is invalid. Connections can
-    be compliant, or they can be non-compliant for one of several reasons (not
-    enough Signed Certificate Timestamps [SCTs], not diverse enough SCTs, or the
-    build was old so CT compliance wasn't checked).
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.CertificateTransparency.CTRequiredConnectionComplianceStatus"
-    enum="CTComplianceStatus" expires_after="M80">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The compliance of each QUIC connection with the Certificate Transparency
-    policy, for connections for which CT compliance is required for the
-    connection to succeed. (For example, CT compliance is required for certain
-    Certificate Authorities, or a site can opt in to having CT be required.)
-    Recorded once on connection setup for applicable connections unless CT
-    evaluation has been disabled for that connection or the certificate is
-    otherwise invalid.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.CertificateTransparency.CTRequiredConnectionComplianceStatus.SSL"
-    enum="CTComplianceStatus" expires_after="M80">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The compliance of each SSL connection with the Certificate Transparency
-    policy, for connections for which CT compliance is required for the
-    connection to succeed. (For example, CT compliance is required for certain
-    Certificate Authorities, or a site can opt in to having CT be required.)
-    Recorded once on connection setup for applicable connections unless CT
-    evaluation has been disabled for that connection or the certificate is
-    otherwise invalid. Not recorded for certificates that chain to
-    locally-installed roots.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryAuditProofError"
-    enum="NetErrorCodes" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned by LogDnsClient at the end of an
-    attempt to obtain an inclusion proof for a certificate from a Certificate
-    Transparency log.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryAuditProofRcode"
-    enum="AsyncDNSRcode" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    Counts of specific DNS response codes returned by LogDnsClient at the end of
-    an attempt to obtain an inclusion proof for a certificate from a Certificate
-    Transparency log. The response codes (rcodes) and meanings are listed on
-    https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryDuration" units="ms"
-    expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    The time taken attempting to obtain an inclusion proof from a Certificate
-    Transparency log over DNS. This includes the time taken to obtain the leaf
-    index first. Emitted at the end of an attempt. Includes attempts that fail.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryDuration.Success"
-    units="ms" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    The time taken to successfully obtain an inclusion proof from a Certificate
-    Transparency log over DNS. This includes the time taken to obtain the leaf
-    index first. Emitted at the end of an attempt.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryLeafIndexError"
-    enum="NetErrorCodes" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned by LogDnsClient at the end of an
-    attempt to obtain a leaf index for a certificate from a Certificate
-    Transparency log.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryLeafIndexRcode"
-    enum="AsyncDNSRcode" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    Counts of specific DNS response codes returned by LogDnsClient at the end of
-    an attempt to obtain a leaf index for a certificate from a Certificate
-    Transparency log. The response codes (rcodes) and meanings are listed on
-    https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.DnsQueryStatus"
-    enum="CertificateTransparencyDnsQueryStatus" expires_after="M67">
-  <obsolete>
-    Replaced by Net.CertificateTransparency.DnsQueryError, which provides the
-    full range of net::Error codes rather than summarising them into the limited
-    set used by this histogram.
-  </obsolete>
-  <owner>robpercival@chromium.org</owner>
-  <summary>
-    The status of each attempt to obtain an inclusion proof from a Certificate
-    Transparency log over DNS. This can consist of more than one DNS request.
-    Emitted at the end of an attempt.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.EVCompliance.QUIC"
-    enum="CTComplianceStatus" expires_after="2017-11-30">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.EVCompliance2.QUIC
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The state of compliance with Certificate Transparency presence requirements
-    for each EV certificate. Recorded once on QUIC connection setup when the
-    connection uses an EV certificate unless CT evaluation has been disabled for
-    that connection or the certificate is invalid.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.EVCompliance.SSL"
-    enum="CTComplianceStatus" expires_after="2017-11-30">
-  <obsolete>
-    Removed Nov 2017, replaced with
-    Net.CertificateTransparency.EVCompliance2.SSL
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    The state of compliance with Certificate Transparency presence requirements
-    for each EV certificate. Recorded once on SSL connection setup when the
-    connection uses an EV certificate unless CT evaluation has been disabled for
-    that connection or the certificate is invalid.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.InclusionCheckResult"
-    enum="CTLogEntryInclusionCheckResult" expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    The result of an inclusion check for a Certificate Transparency log entry
-    (composed of a TLS certificate observed together with Signed Certificate
-    Timestamps). Emitted once per (TLS certificate, Signed Certificate
-    Timestamp) pair observed and checked for inclusion (check results are
-    cached).
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.MainFrameValidSCTCount"
-    units="units" expires_after="2018-12-20">
-  <obsolete>
-    Removed 12/2018.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <summary>
-    Number of valid Signed Certificate Timestamps (SCTs) present for the
-    main-frame resource. Emitted every time a main-frame resource is fetched.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.PilotSTHAge" units="ms"
-    expires_after="M76">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Age of Pilot's Signed Tree Head, as observed by the client, in minutes.
-    Measuring the age of a particular log's Signed Tree Head will allow more
-    informed update frequency of the Component Updater component that provides
-    them. Emitted once for every STH update received by the component updater.
-  </summary>
-</histogram>
-
-<histogram name="Net.CertificateTransparency.SCTsPerConnection" units="units"
-    expires_after="2018-12-20">
-  <obsolete>
-    Removed 12/2018.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <summary>
-    The number of Signed Certificate Timestamps (SCTs) that were available for
-    each SSL connection, including SCTs embedded in the certificate. This metric
-    measures how many SSL connections had SCTs available. Emitted during every
-    SSL connection establishment.
-  </summary>
-</histogram>
-
-<histogram name="Net.CoalescePotential" enum="CoalescePotentialPackets"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times we sent N packets, but could have sent N-1 packets.
-  </summary>
-</histogram>
-
-<histogram name="Net.ComodoDNSExperimentFailureTime" units="ms"
-    expires_after="2014-08-11">
-  <obsolete>
-    This experiment has concluded.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time taken before we failed to resolve the Comodo test DNS
-    record. This is an experiment, run in conjuction with Comodo, to test the
-    viability of a DNS based certificate revocation mechanism.
-  </summary>
-</histogram>
-
-<histogram name="Net.ComodoDNSExperimentSuccessTime" units="ms"
-    expires_after="2014-08-11">
-  <obsolete>
-    This experiment has concluded.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time taken to successfully resolve the Comodo test DNS record.
-    This is an experiment, run in conjuction with Comodo, to test the viability
-    of a DNS based certificate revocation mechanism.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.NoProxy.BytesAfterCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was compressed.
-    Only includes requests which did not go through an explicit proxy and did
-    not go over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.NoProxy.BytesBeforeCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The compressed number of bytes received per request that was compressed.
-    Only includes requests which did not go through an explicit proxy and did
-    not go over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.NoProxy.ShouldHaveBeenCompressed" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was not
-    compressed but appears to have been compressible. Only includes requests
-    which did not go through an explicit proxy and did not go over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.Proxy.BytesAfterCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was compressed.
-    Only includes requests sent through a proxy without SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.Proxy.BytesBeforeCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The compressed number of bytes received per request that was compressed.
-    Only includes requests sent through a proxy without SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.Proxy.ShouldHaveBeenCompressed" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was not
-    compressed but appears to have been compressible. Only includes requests
-    sent through a proxy without SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.SSL.BytesAfterCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was compressed.
-    Only includes requests sent over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.SSL.BytesBeforeCompression" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The compressed number of bytes received per request that was compressed.
-    Only includes requests sent over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.Compress.SSL.ShouldHaveBeenCompressed" units="bytes"
-    expires_after="2015-02-10">
-  <obsolete>
-    Removed as of 02/2015
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The uncompressed number of bytes received per request that was not
-    compressed but appears to have been compressible. Only includes requests
-    sent over SSL.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionTypeCount" enum="ConnectionType"
-    expires_after="2013-04-09">
-  <obsolete>
-    The count was inaccurate (it counted transactions rather than connections)
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Each bucket is the number of connections of a particular type that the user
-    has had during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionTypeCount2" enum="ConnectionType"
-    expires_after="2013-04-09">
-  <obsolete>
-    Renamed to match HadConnectionType.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Each bucket is the number of successful connections of a particular type
-    that the user has had during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionTypeCount3" enum="ConnectionType"
-    expires_after="2016-05-20">
-  <obsolete>
-    Removed May 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    Each bucket is the number of successful connections of a particular type
-    that the user has had during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionTypeFailCount2" enum="ConnectionType"
-    expires_after="2013-04-09">
-  <obsolete>
-    No longer collected.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Each bucket is the number of failed connections of a particular type that
-    the user has had during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionUsedSSLDeprecatedCipherFallback"
-    enum="BooleanDeprecatedCiphers" expires_after="2015-05-04">
-  <obsolete>
-    Replaced with Net.ConnectionUsedSSLDeprecatedCipherFallback2 in Chrome 44.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    True if an HTTPS connection was made using the deprecated cipher suite
-    fallback.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionUsedSSLDeprecatedCipherFallback2"
-    enum="BooleanDeprecatedCiphers" expires_after="2017-05-10">
-  <obsolete>
-    Removed May 2017.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each successful HTTPS request, whether it used the deprecated cipher
-    suite fallback.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionUsedSSLv3Fallback" units="units"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.ConnectionUsedSSLVersionFallback in Chrome 21.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    True if the HTTP request was to a server which requires SSLv3 fallback
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionUsedSSLVersionFallback"
-    enum="FallbackSSLVersion" expires_after="2015-05-04">
-  <obsolete>
-    Replaced with Net.ConnectionUsedSSLVersionFallback2 in Chrome 44.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Nonzero if the HTTP request was to a server which requires SSL version
-    fallback. The value indicates the SSL version the request fell back on.
-  </summary>
-</histogram>
-
-<histogram name="Net.ConnectionUsedSSLVersionFallback2"
-    enum="FallbackSSLVersion" expires_after="2016-06-24">
-  <obsolete>
-    Removed June 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each successful HTTPS request, whether it used the SSL version fallback.
-    The value indicates the SSL version the request fell back on
-  </summary>
-</histogram>
-
-<histogram name="Net.ContentDecodingFailed.FilterType" enum="NetFilterType"
-    expires_after="2017-07-22">
-  <obsolete>
-    Obsoleted in favor of Net.ContentDecodingFailed2.FilterType below.
-  </obsolete>
-  <summary>
-    For each CONTENT_DECODING_FAILED, record the filter that failed.
-  </summary>
-</histogram>
-
-<histogram name="Net.ContentDecodingFailed2.FilterType" enum="NetFilterType2"
-    expires_after="2017-07-22">
-  <obsolete>
-    Obsoleted in favor of Net.ContentDecodingFailed2 above.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    For each CONTENT_DECODING_FAILED, record the filter that failed.
-  </summary>
-</histogram>
-
-<histogram name="net.CookieBackingStoreUpdateResults"
-    enum="BackingStoreResults" expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether or not updates to the backing store succeeded or failed, recorded
-    every update.
-  </summary>
-</histogram>
-
-<histogram name="net.CookieBetweenAccessIntervalMinutes" units="minutes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Intervals between access time updates for each cookie.</summary>
-</histogram>
-
-<histogram name="net.CookieCount" units="units" expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of cookies in the store (recorded every 10 minutes of active browsing
-    time)
-  </summary>
-</histogram>
-
-<histogram name="net.CookieDeletionCause" enum="CookieDeletionCause"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For each cookie removed from the store, the reason it was removed.
-  </summary>
-</histogram>
-
-<histogram name="net.CookieDomainCount" units="units"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For each domain, number of cookies in that domain (recorded every 10 minutes
-    of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="net.CookieDomainPerEtldp1Count" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For every top level domain, number of subdomains in that top level domain
-    (recorded every 10 minutes of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="net.CookieEtldp1Count" units="units"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For every top level domain, number of cookies in that domain (recorded every
-    10 minutes of active browsing time).
-  </summary>
-</histogram>
-
-<histogram name="net.CookieEvictedLastAccessMinutes" units="minutes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For each evicted (not expired) cookie, the amount of time since it was last
-    used
-  </summary>
-</histogram>
-
-<histogram name="net.CookieExpirationDurationMinutes" units="minutes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Number of minutes until cookie expires when set.</summary>
-</histogram>
-
-<histogram name="net.CookieTimeGet" units="units" expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time (ms) to get cookies for each URL request.
-  </summary>
-</histogram>
-
-<histogram name="net.CookieTimeLoad" units="units" expires_after="2013-04-09">
-  <obsolete>
-    Initial typo; only here to get results from builds before r59117. See
-    &quot;Cookie.&quot; group.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time (ms) to load the persistent cookie store at browser
-    start.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.ActiveLoaderCount" units="entries"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of active mojom::URLLoader instance counts including
-    network::URLLoader and network::CorsURLLoader in the network service. This
-    reports every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.CompletionStatus" enum="CorsCompletionStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Each CorsURLLoader reports its completion status on finishing each request
-    to analyze how often requests are blocked by CORS checks.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.PreflightCacheEntries" units="entries"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of the number of cache entries in the CORS preflight cache.
-    This counts the cache entries every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.PreflightCacheEntriesPerOrigin" units="entries"
-    expires_after="2019-05-14">
-  <obsolete>
-    Removed 05/2019, related to cache organization changes that does not store
-    entries per origin any more.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of the number of cache entries for each origin in the CORS
-    preflight cache. This counts the cache entries for each origin every 5
-    minutes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.PreflightCacheTotalEntries" units="entries"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of the total number of cache entries that is sum of all
-    CORS preflight cache entries in the network service. This counts the cache
-    entries every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.PreflightCacheTotalMemoryPressureInBytes"
-    units="bytes" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of the total memory presure in bytes for all CORS preflight
-    cache in the network service. This counts the cache entries every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cors.PreflightCacheValueSize" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The distribution of estimated memory pressure caused by each cache entry's
-    content in the CORS preflight cache. This counts each entry size when a new
-    entry is added to the cache.
-  </summary>
-</histogram>
-
-<histogram name="Net.CountOfAlternateProtocolServers" units="servers"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/08.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The total number of servers (HostPortPairs) to which alternative protocol
-    was used. This counts the number of servers persisted to prefs file.
-  </summary>
-</histogram>
-
-<histogram name="Net.CountOfAlternateProtocolServers.Memory" units="servers"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/08.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The total number of servers (HostPortPairs in memory) to which alternative
-    protocol was used.
-  </summary>
-</histogram>
-
-<histogram name="Net.CountOfPipelineCapableServers" units="servers"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total number of servers (HostPortPairs) that support HTTP pipelining.
-    This counts the number of servers persisted to prefs file.
-  </summary>
-</histogram>
-
-<histogram name="Net.CountOfSpdyServers" units="units" expires_after="M77">
-  <obsolete>
-    Removed on 2016-08.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The total number of SPDY server names persisted to prefs file.
-  </summary>
-</histogram>
-
-<histogram name="Net.CountOfSpdySettings" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-11.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The total number of SPDY Settings properties persisted to prefs file.
-  </summary>
-</histogram>
-
-<histogram name="Net.CRLRequestFailedTimeMs" units="ms"
-    expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to block to fetch one or
-    more revocation lists. This measures the amount of time that failures to get
-    CRL information take.
-  </summary>
-</histogram>
-
-<histogram name="Net.CRLRequestSuccess" enum="BooleanSuccess"
-    expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to block to fetch one or
-    more revocation lists. This records the fraction of successful requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.CRLRequestTimeMs" units="ms" expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to block to fetch one or
-    more revocation lists. This measures the amount of time that each fetch
-    takes.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cronet.CertVerifierCache.DeserializeTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2018-06-29 in crrev.com/571588.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Measures time spent to deserialize and populate the
-    net::CachingCertVerifier's cache.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cronet.CertVerifierCache.SerializeTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2018-06-29 in crrev.com/571588.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Measures time spent to serialize the net::CachingCertVerifier's cache.
-  </summary>
-</histogram>
-
-<histogram name="Net.Cronet.PrefsInitTime" units="ms"
-    expires_after="2019-04-23">
-  <obsolete>
-    Removed 2019-04-23.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Measures time spent creating the Cronet PrefService, including loading the
-    prefs from disk synchronously.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength" units="KB" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTP/HTTPS response bodies in the
-    previous calendar day. The metric is reported when the first response in the
-    current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_DataReductionProxyEnabled" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTP/HTTPS response bodies in the
-    previous calendar day while the data reduction proxy setting was enabled.
-    The metric is reported when the first response in the current day is
-    received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_DataReductionProxyEnabled_Https"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTPS response bodies in the previous
-    calendar day while the data reduction proxy setting was enabled. The metric
-    is reported when the first response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_DataReductionProxyEnabled_LongBypass"
-    units="KB" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all long-bypassed HTTP response bodies in
-    the previous calendar day while the data reduction proxy setting was
-    enabled. The metric is reported when the first response in the current day
-    is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_DataReductionProxyEnabled_ShortBypass"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all short-bypassed HTTP response bodies in
-    the previous calendar day while the data reduction proxy setting was
-    enabled. The metric is reported when the first response in the current day
-    is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_DataReductionProxyEnabled_Unknown"
-    units="KB" expires_after="2015-08-18">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTP response bodies for requests that
-    were not served by the enabled data reduction proxy for unknown reasons in
-    the previous calendar day while the data reduction proxy setting was
-    enabled. The metric is reported when the first response in the current day
-    is received.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.DailyContentLength_DataReductionProxyEnabled_UnknownBypass"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTP response bodies for requests that
-    were not served by the enabled data reduction proxy for unknown reasons in
-    the previous calendar day while the data reduction proxy setting was
-    enabled. The metric is reported when the first response in the current day
-    is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentLength_ViaDataReductionProxy" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total content size in KB of all HTTP/HTTPS response bodies in the
-    previous calendar day via the data reduction proxy. The metric is reported
-    when the first response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_DataReductionProxyEnabled" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total HTTP/HTTPS response body size while the data
-    reduction proxy is enabled to total HTTP/HTTPS response body size in the
-    previous calendar day. The metric is reported when the first response in the
-    current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_DataReductionProxyEnabled_Https"
-    units="%" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total HTTPS response body size while the data reduction
-    proxy is enabled to total HTTP/HTTPS response body size in the previous
-    calendar day. The metric is reported when the first response in the current
-    day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_DataReductionProxyEnabled_LongBypass"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total long-bypassed response body size while the data
-    reduction proxy is enabled to total HTTP/HTTPS response body size in the
-    previous calendar day. The metric is reported when the first response in the
-    current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_DataReductionProxyEnabled_ShortBypass"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total short-bypassed response body size while the data
-    reduction proxy is enabled to total HTTP/HTTPS response body size in the
-    previous calendar day. The metric is reported when the first response in the
-    current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_DataReductionProxyEnabled_Unknown"
-    units="%" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total body size of responses that were not served by the
-    data reduction proxy for unknown reason while the data reduction proxy is
-    enabled to total HTTP/HTTPS response body size in the previous calendar day.
-    The metric is reported when the first response in the current day is
-    received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentPercent_ViaDataReductionProxy" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of total HTTP/HTTPS response body size via the data reduction
-    proxy to total HTTP/HTTPS response body size in the previous calendar day.
-    The metric is reported when the first response in the current day is
-    received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentSavingPercent" units="%" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day. A negative
-    saving will be shown as zero. The metric is reported when the first response
-    in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentSavingPercent_DataReductionProxyEnabled"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day while the data
-    reduction proxy was enabled. A negative saving will be shown as zero. This
-    only counts responses while the data reduction proxy is enabled. The metric
-    is reported when the first response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentSavingPercent_DataReductionProxyEnabled_Video"
-    units="%" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day while the data
-    reduction proxy was enabled. A negative saving will be shown as zero. This
-    only counts responses while the data reduction proxy is enabled. The metric
-    is reported when the first response in the current day is received. If no
-    video bytes were received while the data reduction proxy was enabled, the
-    metric will not be reported.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentSavingPercent_ViaDataReductionProxy" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day via the data
-    reduction proxy. A negative saving will be shown as zero. This only counts
-    responses via the data reduction proxy. The metric is reported when the
-    first response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyContentSavingPercent_ViaDataReductionProxy_Video"
-    units="%" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day via the data
-    reduction proxy. A negative saving will be shown as zero. This only counts
-    responses via the data reduction proxy. The metric is reported when the
-    first response in the current day is received. If no video bytes were
-    received via the data reduction proxy, the metric will not be reported.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpContentLengthViaDataReductionProxy" units="KB"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Total size in KB of all response bodies in the previous calendar day that
-    were received through the data reduction proxy.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpContentLengthWithDataReductionProxyEnabled"
-    units="KB" expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Total size in KB of all response bodies in the previous calendar day that
-    were received when the data reduction proxy was enabled.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpContentSavings" units="%"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day. A negative
-    saving will be shown as zero.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpContentSavings_DataReductionProxy" units="%"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    The percentage of data saving in the previous calendar day when the data
-    reduction proxy was enabled for at least some responses during the day. A
-    negative saving will be shown as zero.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpOriginalContentLength" units="KB"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed- see Net.DailyOriginalContentLength.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Total size in KB specified in the X-Original-Content-Length headers of all
-    responses in the previous calendar day. If the header is not present in a
-    response, the size of the response body is used.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyHttpReceivedContentLength" units="KB"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed- see Net.DailyContentLength.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Total size in KB of all response bodies in the previous calendar day.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyOriginalContentLength" units="KB" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total size in KB specified in the X-Original-Content-Length headers of
-    all HTTP/HTTPS response bodies in the previous calendar day. If the header
-    is not present in a response, the size of the response body is used. The
-    metric is reported when the first response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyOriginalContentLength_DataReductionProxyEnabled"
-    units="KB" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total size in KB specified in the X-Original-Content-Length headers of
-    all HTTP/HTTPS response bodies in the previous calendar day while the data
-    reduction proxy is enabled. If the header is not present in a response, the
-    size of the response body is used. The metric is reported when the first
-    response in the current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyOriginalContentLength_ViaDataReductionProxy"
-    units="KB" expires_after="M77">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total size in KB specified in the X-Original-Content-Length headers of
-    all HTTP/HTTPS response bodies in the previous calendar day via the data
-    reduction proxy. If the header is not present in a response, the size of the
-    response body is used. The metric is reported when the first response in the
-    current day is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyReceivedContentViaDataReductionProxy" units="%"
-    expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    The percentage of Net.DailyHttpContentLengthViaDataReductionProxy in
-    Net.DailyHttpReceivedContentLength.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyReceivedContentWithDataReductionProxyEnabled"
-    units="%" expires_after="2013-09-24">
-  <obsolete>
-    Removed; refer to Experimental.Bytes.Network
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    The percentage of Net.DailyHttpContentLengthWithDataReductionProxyEnabled in
-    Net.DailyHttpReceivedContentLength.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyUserVisibleSavingsPercent_DataReductionProxyEnabled"
-    units="%" expires_after="2016-12-22">
-  <obsolete>
-    Removed in Chrome 57.
-  </obsolete>
-  <owner>kundaji@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The percentage of data savings in past
-    |DataReductionProxy::kNumDaysInHistorySummary| days. This number is
-    displayed to users as their data savings.
-  </summary>
-</histogram>
-
-<histogram name="Net.DailyUserVisibleSavingsSize_DataReductionProxyEnabled"
-    units="KB" expires_after="2016-12-22">
-  <obsolete>
-    Removed in Chrome 57.
-  </obsolete>
-  <owner>kundaji@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total data saved in KB in past
-    |DataReductionProxy::kNumDaysInHistorySummary| days. This number is used to
-    compute the data savings displayed to the user.
-  </summary>
-</histogram>
-
-<histogram name="Net.DetachableResourceHandler.Duration" units="ms"
-    expires_after="2017-11-13">
-  <obsolete>
-    Removed in Chrome 64.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    Duration of time that a request associated with DetachableResourceHandler
-    takes.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadCancelTime" units="ms" expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures time from initiating a fetch of a PAC file from DHCP WPAD to
-    cancellation of the fetch. For a given fetch, only one of the cancellation
-    or completion histograms will be added to.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadCompletionTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures time from initiating a fetch of a PAC file from DHCP WPAD to
-    completion of the fetch. For a given fetch, only one of the cancellation or
-    completion histograms will be added to.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadFetchError" enum="NetErrorCodes"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Tracks the net error codes received when the DHCP WPAD fetch fails to
-    retrieve a PAC file (including PAC_NOT_IN_DHCP, which is not really an error
-    but an indication that a PAC URL was not configured in DHCP).
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadGetAdaptersAddressesError"
-    enum="ErrorCodesGetAdaptersAddresses" expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Tracks the frequency of each of the different known error codes of calling
-    the GetAdaptersAddresses Win32 API.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadGetAdaptersAddressesTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Measures the time taken to call the GetAdaptersAddresses Win32 API, to
-    validate our understanding that it should complete quickly enough to call
-    synchronously from the network thread.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadNumAdaptersAtWaitTimer" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Total number of adapters enabled for DHCP as seen when the wait timer in the
-    DHCP WPAD code hits. This timer fires after a timeout from when we get some
-    information from the first adapter to finish.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadNumPendingAdaptersAtWaitTimer" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Number of adapters enabled for DHCP that we have not completed retrieving
-    information for, as seen when the wait timer in the DHCP WPAD code hits.
-    This timer fires after a timeout from when we get some information from the
-    first adapter to finish.
-  </summary>
-</histogram>
-
-<histogram name="Net.DhcpWpadUnhandledDhcpError" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Counts the number of errors from the DhcpRequestParams API that we do not
-    have specific handling for, so that we can see if there is an abnormally
-    high rate.
-  </summary>
-</histogram>
-
-<histogram name="Net.DiskCache.Size" units="MB" expires_after="2017-12-18">
-  <obsolete>
-    Removed in Chrome 65.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The sum of the size of all files in the HTTP cache directory.
-
-    This is recorded on startup, and then every 24 hours afterwards. However, it
-    is only recorded for 0.1% of profiles, to reduce overhead for most users.
-    This is meant to be a temporary metric to help debug a potential HTTP cache
-    leak. We do not yet know which milestone we expect it to be removed in.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.Android.AutoDohPrivate" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed 8/2019.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    For devices using Android private DNS, are their DNS servers known to
-    support DNS-over-HTTPS.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.Android.AutoDohPublic" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed 8/2019.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    For devices not using Android private DNS, are their DNS servers known to
-    support DNS-over-HTTPS, thus potential candidates for automatic upgrading
-    from regular DNS to DNS-over-HTTPS.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.Android.DotExplicit" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed 8/2019.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    For devices using Android private DNS, was their DNS-over-TLS server
-    specified explicitly in their Android settings. When false, they were
-    automatically upgraded from the standard DNS protocol to DNS-over-TLS via
-    auto-detection.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.DnsTask.FailureTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 9/2019.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time taken by DnsTask in resolutions that failed. Excludes time
-    spent in the subsequent fallback.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.DNS.DnsTransaction.EsniTask.EsniTransactionEndToEndElapsed"
-    units="ms" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    Total time elapsed from the beginning of ESNI-type DnsTasks to the
-    completion of ESNI-type DnsTransactions executed during these tasks.
-    Recorded only for DnsTasks specifically with DnsQueryType::ESNI, i.e. *not*
-    for those made during the normal built-in resolver flow.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.DnsTransaction.EsniUnspecTask.EsniMinusNonEsni"
-    units="ms" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    For an UNSPECIFIED-type DnsTask, the total end-to-end elapsed time from the
-    beginning of the task to the completion of its final ESNI-type
-    DnsTransaction, minus the total end-to-end elapsed time to the completion of
-    the task's final non-ESNI-type transaction. Recorded only when the built-in
-    resolver is configured to make ESNI queries alongside A and AAAA queries,
-    and only when the task's ESNI transaction finishes after its final non-ESNI
-    transaction.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.DNS.DnsTransaction.EsniUnspecTask.EsniTransactionEndToEndElapsed"
-    units="ms" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    Total time elapsed from the beginning of a DnsTask to the completion of an
-    ESNI transaction. Recorded only when the built-in resolver is configured to
-    make ESNI queries alongside A and AAAA queries.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.DnsTransaction.EsniUnspecTask.NonEsniEndToEndElapsed"
-    units="ms" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    Total time elapsed from the beginning of an UNSPECIFIED-type DnsTask to the
-    completion of its final non-ESNI-type DnsTransaction. Recorded only when the
-    built-in resolver is configured to make ESNI queries alongside A and AAAA
-    queries.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.DnsTransaction.EsniUnspecTask.NonEsniMinusEsni"
-    units="ms" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    For an UNSPECIFIED-type DnsTask, the total end-to-end elapsed time from the
-    beginning of the task to the completion of its final non-ESNI-type
-    DnsTransaction, minus the total end-to-end elapsed time to the completion of
-    the task's final ESNI-type transaction. Recorded only when the built-in
-    resolver is configured to make ESNI queries alongside A and AAAA queries,
-    and only when the task's final non-ESNI transaction finishes no earlier than
-    its ESNI transaction.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.DnsTransaction.EsniUnspecTask.SuccessOrTimeout"
-    enum="SuccessTimeoutStarted" expires_after="M82">
-  <obsolete>
-    As of 02/2020, no longer necessary because the ESNI record fetching
-    implementation has been superseded by the new HTTPSSVC DNS record type.
-  </obsolete>
-  <owner>davidvc@chromium.org</owner>
-  <owner>ericorth@chromium.org</owner>
-  <summary>
-    Records successful completions and DnsTask-level timeout cancellations of
-    ESNI (TLS 1.3 Encrypted Server Name Indication, Draft 4)-type DNS
-    transactions. Recorded only when the built-in resolver is configured to make
-    ESNI queries alongside A and AAAA queries.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.JobQueueTime" units="ms" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Time elapsed between the time the HostResolverImpl::Job was created and the
-    time the Job was started.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.JobQueueTimeAfterChange" units="ms"
-    expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Time elapsed between the last time the priority of a HostResolverImpl::Job
-    changed (when a Request was attached or detached) and the time the Job was
-    started.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.RecordParser.DomainNameLength" units="octets"
-    expires_after="M80">
-  <obsolete>
-    Removed 8/2019.
-  </obsolete>
-  <owner>dmcardle@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    Length of domain name parsed by DnsRecordParser::ReadName().
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.ResultAfterMalformedResponse"
-    enum="MalformedResponseResult" expires_after="2018-07-30">
-  <obsolete>
-    Removed July 2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    When DnsUDPAttempt gets a malformed response, it returns an error but
-    continues running. This histogram records all attempt outcomes that are
-    returned to the transaction once a malformed response has been received,
-    including the original malformed response.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.SecureDnsMode.Automatic.TotalTime" units="ms"
-    expires_after="M84">
-  <obsolete>
-    Replaced 2020-06 by Net.DNS.SecureDnsMode.Automatic.ResolveTime
-  </obsolete>
-  <owner>dalyk@google.com</owner>
-  <owner>doh-core@google.com</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted for requests issued in AUTOMATIC mode. Excludes cancled,
-    evicted, and aborted requests. Includes cache hits (recorded as 0). Excludes
-    speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.SecureDnsMode.Off.TotalTime" units="ms"
-    expires_after="M84">
-  <obsolete>
-    Replaced 2020-06 by Net.DNS.SecureDnsMode.Off.ResolveTime
-  </obsolete>
-  <owner>dalyk@google.com</owner>
-  <owner>doh-core@google.com</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted for requests issued in OFF mode. Excludes cancled, evicted,
-    and aborted requests. Includes cache hits (recorded as 0). Excludes
-    speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.SecureDnsMode.Secure.TotalTime" units="ms"
-    expires_after="M84">
-  <obsolete>
-    Replaced 2020-06 by Net.DNS.SecureDnsMode.Secure.ResolveTime
-  </obsolete>
-  <owner>dalyk@google.com</owner>
-  <owner>doh-core@google.com</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted for requests issued in SECURE mode. Excludes cancled,
-    evicted, and aborted requests. Includes cache hits (recorded as 0). Excludes
-    speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.TotalTime" units="ms" expires_after="M84">
-  <obsolete>
-    Replaced 2020-06 by Net.DNS.Request.TotalTime
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Excludes speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS.TotalTimeNotCached" units="ms" expires_after="M84">
-  <obsolete>
-    Replaced 2020-06 by Net.DNS.Request.TotalTimeAsync
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <owner>mef@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests and
-    requests that returned synchronously (such as cache hits). Excludes
-    speculative requests.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Net.DNS.TotalTimeTyped" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 9/2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes
-     name="DnsTotalTimeType" -->
-
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Duration of time since a HostResolverImpl::Resolve request to the time a
-    result is posted. Excludes canceled, evicted, and aborted requests. Includes
-    cache hits (recorded as 0). Excludes speculative requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.DNS_Resolution_And_TCP_Connection_Latency" units="units"
-    expires_after="2013-05-10">
-  <obsolete>
-    Removed- see Net.DNS_Resolution_And_TCP_Connection_Latency2
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-</histogram>
-
-<histogram name="Net.Dns_Resolution_And_TCP_Connection_Latency" units="units"
-    expires_after="2013-04-09">
-  <obsolete>
-    Removed- see Net.DNS_Resolution_And_TCP_Connection_Latency2
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-</histogram>
-
-<histogram name="Net.Dns_Resolution_And_TCP_Connection_Latency2" units="units"
-    expires_after="2013-05-10">
-  <obsolete>
-    Removed- see Net.DNS_Resolution_And_TCP_Connection_Latency2
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-</histogram>
-
-<histogram name="Net.DNSNameCompliantIfValid" enum="Boolean"
-    expires_after="2017-07-19">
-  <obsolete>
-    Removed 07/2017, not necessary to determine deprecation for invalid DNS
-    names.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    True if |net::IsCanonicalizedHostCompliant| returns true. Used to see if
-    IsCanonicalizedHostCompliant() runs afoul of real websites. This histogram
-    is recorded when converting dotted DNS names into DNS query form, in
-    preparation for issuing a DNS request. This histogram is only recorded if
-    Net.ValidDNSName is true.
-  </summary>
-</histogram>
-
-<histogram name="Net.DoubleGetExperiment_InitialResponseMethod"
-    enum="DoubleGetExperimentMethods" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of HTTP request responses with MS Office Docs MIME types. The
-    responses are classified based on their method type and cacheability (POST,
-    cacheable GET and non-cacheable GET). The histogram is used in Double GET
-    Experiment, where successful non-cacheable GET requests are intercepted
-    after initial response and repeated in order to determine how much reissuing
-    non-cacheable GET requests influences their error rate. The histogram tracks
-    only initial requests (not the repeated ones).
-  </summary>
-</histogram>
-
-<histogram name="Net.DoubleGetExperiment_ResponseCode" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The response codes encountered for GET request repeated in Double GET
-    Experiment. In the experiment successful non-cacheable GET requests are
-    intercepted after initial response and repeated. The goal of the experiment
-    is to measure how much reissuing non-cacheable GET requests influences their
-    error rate.
-  </summary>
-</histogram>
-
-<histogram name="Net.DownloadBandwidth" units="units"
-    expires_after="2015-03-31">
-  <obsolete>
-    Removed as of 03/2015. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Kbps on download streams exceeding 25KB. Measures from the beginning of the
-    first byte received until the end of flowing data.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrAborted.CountPerUpload" units="aborts"
-    expires_after="2017-06-14">
-  <obsolete>
-    Removed in favor of Net.ErrAborted.CountPerUpload2 which has a higher upper
-    bound
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The count of the ABORTED bucket in Net.ErrorCodesForMainFrame3 at the time
-    histograms are being uploaded.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrAborted.ReceivedBytes" units="bytes"
-    expires_after="2018-07-02">
-  <obsolete>
-    Removed from Chromium as of 2018/7/2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The TotalReceivedBytes() at the time the request finishes with ERR_ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrAborted.SentBytes" units="bytes"
-    expires_after="2018-07-02">
-  <obsolete>
-    Removed from Chromium as of 2018/7/2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The TotalSentBytes() at the time the request finishes with ERR_ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForHTTPSGoogleMainFrame" enum="NetErrorCodes"
-    expires_after="2015-11-09">
-  <obsolete>
-    Removed as of 2012/5/16, replaced by Net.ErrorCodesForHTTPSGoogleMainFrame2,
-    which measures the same data but includes ERR_ABORT and OK.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Errors resulting from loading pages from https://www.google.com. Note that
-    this only counts the errors in &quot;main frames&quot;, so it is a measure
-    of the error pages that users actually see (it does not for example count
-    the error codes for subresoures on a page). This is a temporary histogram,
-    added in order to debug query loss from the SSL Search launch.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForHTTPSGoogleMainFrame2" enum="NetErrorCodes"
-    expires_after="2018-07-06">
-  <obsolete>
-    Removed as of 7/2018, replaced by Net.ErrorCodesForHTTPSGoogleMainFrame3.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Positive net error codes that requests for pages end with, including net::OK
-    and net::ERR_ABORTED. This only counts loads in &quot;main frames&quot; for
-    https://www.google.com. Subresources or main frame navigations to other
-    origins are not included.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForImages" enum="NetErrorCodes"
-    expires_after="2018-07-06">
-  <obsolete>
-    Removed as of 7/2018, replaced by Net.ErrorCodesForImages2, which is
-    recorded in a net-service friendly way.
-  </obsolete>
-  <owner>skonig@chromium.org</owner>
-  <owner>hbengali@chromium.org</owner>
-  <summary>
-    Net error codes that requests for images end with, including net::OK and
-    net:ERR_ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForMainFrame" enum="NetErrorCodes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Removed as of 2011/5/24, replaced by Net.ErrorCodesForMainFrame2, which
-    measures the same data but uses a different bucket structure (adds guard
-    buckets).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Positive net error code that a page failed with. Note that this only counts
-    the errors in &quot;main frames&quot;, so it is a measure of the error pages
-    that users actually see (it does not for example count the error codes for
-    subresoures on a page).
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForMainFrame2" enum="NetErrorCodes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Removed as of 2012/5/16, replaced by Net.ErrorCodesForMainFrame3, which
-    measures the same data but includes ERR_ABORTED and OK.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Positive net error code that a page failed with. Note that this only counts
-    the errors in &quot;main frames&quot;, so it is a measure of the error pages
-    that users actually see (it does not for example count the error codes for
-    subresoures on a page).
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForMainFrame3" enum="NetErrorCodes"
-    expires_after="2018-07-06">
-  <obsolete>
-    Removed as of 7/2018, replaced by Net.ErrorCodesForMainFrame4, which is
-    recorded in a net-service friendly way.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Positive net error codes that requests for pages end with, including net::OK
-    and net::ERR_ABORTED. This only counts loads in &quot;main frames&quot; (it
-    does not for example count the error codes for subresoures on a page).
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForSubresources" enum="NetErrorCodes"
-    expires_after="2013-04-09">
-  <obsolete>
-    Removed as of 2012/5/16, replaced by Net.ErrorCodesForSubresources2, which
-    measures the same data but includes ERR_ABORT and OK.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Positive net error code that a page failed with. Note that this only counts
-    the errors in &quot;subresources&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForSubresources2" enum="NetErrorCodes"
-    expires_after="2018-07-06">
-  <obsolete>
-    Removed as of 7/2018, replaced by Net.ErrorCodesForSubresources3, which is
-    recorded in a net-service friendly way.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Net error codes that requests for &quot;subresources&quot; end with,
-    including net::OK and net::ERR_ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorCodesForTLS13ExperimentMainFrame"
-    enum="NetErrorCodes" expires_after="2018-07-06">
-  <obsolete>
-    Removed as of 7/2018, replaced by
-    Net.ErrorCodesForTLS13ExperimentMainFrame2, which is recorded in a
-    net-service friendly way.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    Positive net error codes that requests for pages end with, including net::OK
-    and net::ERR_ABORTED. This only counts loads in &quot;main frames&quot; for
-    endpoints used in the initial TLS 1.3 deployment. Subresources or main frame
-    navigations to other origins are not included.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorPageButtonPressedWhileInUnexpectedState"
-    enum="ErrorPageButton" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 2015/8/21
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Temporary histogram to investigate http://crbug.com/500556. Records which
-    button on the network error page was pushed when either the URL Blink
-    reports for the page is not the internal error page URL or the
-    NetErrorHelper core has no error information for the current page (or both).
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorPageButtonPressUnexpectedStates"
-    enum="ErrorPageUnexpectedStates" expires_after="2015-08-26">
-  <obsolete>
-    Removed as of 2015/8/21
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Temporary histogram to investigate http://crbug.com/500556. Records whether,
-    when the handler for a button press on the network error page runs, which of
-    the following are or are not true: The URL Blink reports for the page is not
-    the internal error page URL or the NetErrorHelper core has no error
-    information for the current page.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorPageCounts.NavigationCorrectionLinksShown"
-    enum="NetErrorNavigationCorrectionTypes" expires_after="2021-06-01">
-  <obsolete>
-    Removed as of 2020/07
-  </obsolete>
-  <owner>edwardjung@chromium.org</owner>
-  <owner>security-enamel@chromium.org</owner>
-  <summary>
-    Counts of the type of navigation correction suggestions shown on the network
-    error page. Multiple suggestions can be shown at the same time.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorPageCounts.NavigationCorrectionLinksUsed"
-    enum="NetErrorNavigationCorrectionTypes" expires_after="2021-06-01">
-  <obsolete>
-    Removed as of 2020/07
-  </obsolete>
-  <owner>edwardjung@chromium.org</owner>
-  <owner>security-enamel@chromium.org</owner>
-  <summary>
-    Usage of navigation correction suggestions shown on the network error page.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorResponseHasContentMainFrame" enum="BooleanSuccess"
-    expires_after="2016-10-13">
-  <obsolete>
-    Removed 10/2016.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    The number of main frame 4xx/5xx responses that have content, to determine
-    if it's worth hooking up an error page for those that don't. Intended to be
-    removed from the binary soon.
-  </summary>
-</histogram>
-
-<histogram name="Net.ErrorResponseHasContentNonMainFrame" enum="BooleanSuccess"
-    expires_after="2016-10-13">
-  <obsolete>
-    Removed 10/2016.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    The number of non-main frame 4xx/5xx responses that have content, to
-    determine if it's worth hooking up an error page for those that don't.
-    Intended to be removed from the binary soon.
-  </summary>
-</histogram>
-
-<histogram name="Net.ExpectCTHeaderResult" enum="ExpectCTHeaderResult"
-    expires_after="2017-04-26">
-  <obsolete>
-    Removed 04/2017.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Sites can send an Expect-CT header to Chrome to indicate that they want a
-    report to be sent when the connection does not comply with Certificate
-    Transparency policy. This histogram is recorded whenever Chrome receives an
-    Expect-CT header, and it records the result of processing the header, such
-    as whether it was ignored due to a bad value.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_Flush" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file Flush failed with. The code is OS dependent,
-    so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_GetSize" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file GetSize failed with. The code is OS dependent,
-    so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_Open" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file Open failed with. The code is OS dependent, so
-    when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_Read" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file Read failed with. The code is OS dependent, so
-    when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_Seek" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file Seek failed with. The code is OS dependent, so
-    when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_SetEof" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file SetEof failed with. The code is OS dependent,
-    so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileError_Write" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code that a file Write failed with. The code is OS dependent,
-    so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_Flush" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file Flush failed with. Any value other than
-    0 indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_Flush. The code is OS
-    dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_GetSize" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file GetSize failed with. Any value other
-    than 0 indicates that we have received errors in a range outside of the one
-    in which we recorded the specific errors in Net.FileError_GetSize. The code
-    is OS dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_Open" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file Open failed with. Any value other than 0
-    indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_Open. The code is OS
-    dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_Read" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file Read failed with. Any value other than 0
-    indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_Read. The code is OS
-    dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_Seek" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file Seek failed with. Any value other than 0
-    indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_Seek. The code is OS
-    dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_SetEof" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file SetEof failed with. Any value other than
-    0 indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_SetEof. The code is
-    OS dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileErrorRange_Write" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    System error code range that a file Write failed with. Any value other than
-    0 indicates that we have received errors in a range outside of the one in
-    which we recorded the specific errors in Net.FileError_Write. The code is OS
-    dependent, so when looking at the histogram don't mix OSes.
-  </summary>
-</histogram>
-
-<histogram name="Net.FileSVGZLoadCount" enum="BooleanAttempted"
-    expires_after="2019-03-12">
-  <obsolete>
-    Removed 2020-04 (M84).
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    A compressed SVG file was loaded from the file scheme. This is a temporary
-    counter to determine how often (if at all) this feature is used. Recorded
-    during creation of file-request for .svgz resource. See
-    http://crbug.com/857117 for more information.
-  </summary>
-</histogram>
-
-<histogram name="Net.ForceAlternativeService" enum="BooleanForced"
-    expires_after="2015-03-30">
-  <obsolete>
-    Data collection ended, corresponding feature removed.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Track usage of alternative services forced by the force-alt-protocols
-    command line flag. Triggered each time alternative services are queried for
-    a given origin and the command line flag would make a difference (that is,
-    there is no advertised alternative service for that origin).
-  </summary>
-</histogram>
-
-<histogram name="Net.FoundSystemTrustRootsAndroid" enum="BooleanFound"
-    expires_after="M77">
-  <obsolete>
-    Underlying implementation changed to no longer depend on OS. Removed in
-    Chrome 77.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether or not system installed trust anchors could be distinguished from
-    user installed trust anchors. Recorded on first certificate verification on
-    Android 4.2 and later.
-  </summary>
-</histogram>
-
-<histogram name="Net.FtpDataConnectionErrorCount" enum="FtpDataConnectionError"
-    expires_after="2019-04-23">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>The number of times each FTP Error was observed.</summary>
-</histogram>
-
-<histogram name="Net.FtpDataConnectionErrorHappened"
-    enum="FtpDataConnectionError" expires_after="2019-04-23">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>
-    The number of Chrome sessions which encountered the indicates FTP Error.
-    This prevents allowing a user that retried a connection many times (getting
-    an error each time) from biasing the tallies.
-  </summary>
-</histogram>
-
-<histogram name="Net.FtpServerTypeCount" enum="FtpServerType"
-    expires_after="2014-06-20">
-  <obsolete>
-    Replaced by Net.FtpServerTypeCount2 on 2012-11-03.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>
-    Each bucket is the number of times the FTP server type was encountered.
-  </summary>
-</histogram>
-
-<histogram name="Net.FtpServerTypeCount2" enum="FtpServerType2"
-    expires_after="2019-04-23">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>
-    Each bucket is the number of times the FTP server type was encountered.
-  </summary>
-</histogram>
-
-<histogram name="Net.GetProxyForUrl_FAIL" units="ms" expires_after="2014-09-16">
-  <obsolete>
-    Removed at some time before 2014/09/15.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time spent waiting for WinHttpGetProxyForUrl to return with error.
-  </summary>
-</histogram>
-
-<histogram name="Net.GetProxyForUrl_OK" units="ms" expires_after="2014-09-16">
-  <obsolete>
-    Removed at some time before 2014/09/15.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time spent waiting for WinHttpGetProxyForUrl to return with success.
-  </summary>
-</histogram>
-
-<histogram name="Net.GoogleConnectionInappropriateFallback"
-    enum="BooleanInappropriateFallback" expires_after="2016-06-24">
-  <obsolete>
-    Removed June 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    Records a sample for each HTTPS request to a Google server that either
-    succeeded or received an inappropriate_fallback alert. This is used to
-    estimate how frequently the fallback is used to recover from a spurious
-    network failure.
-  </summary>
-</histogram>
-
-<histogram name="Net.GoogleConnectionUsedSSLVersionFallback"
-    enum="FallbackSSLVersion" expires_after="2015-05-04">
-  <obsolete>
-    Replaced with Net.GoogleConnectionUsedSSLVersionFallback2 in Chrome 44.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Nonzero if the HTTP request was to a Google server which required SSL
-    version fallback. The value indicates the SSL version the request fell back
-    on. Since Google servers support TLS 1.2, any fallback is an indication of
-    network middleware problems.
-  </summary>
-</histogram>
-
-<histogram name="Net.GoogleConnectionUsedSSLVersionFallback2"
-    enum="FallbackSSLVersion" expires_after="2016-06-24">
-  <obsolete>
-    Removed June 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each successful HTTPS request to a Google server, whether it used the
-    SSL version fallback. The value indicates the SSL version the request fell
-    back on. Since Google servers support TLS 1.2 and FALLBACK_SCSV, any
-    fallback is an indication of a broken local SSL MITM proxy.
-  </summary>
-</histogram>
-
-<histogram name="Net.GzipEncodingFixupResult" enum="GzipEncodingFixupResult"
-    expires_after="2015-03-23">
-  <obsolete>
-    Removed around 2015/03/18. The code which implemented Gzip encoding fixup
-    was removed.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Resources are sometimes transferred with an incorrect encoding type of gzip.
-    net::Filter::FixupEncodingTypes() attempts to correct for these situations
-    by applying a set of heuristics. This histogram counts the frequency of
-    usage of these heuristics in the wild.
-  </summary>
-</histogram>
-
-<histogram name="Net.HadConnectionType" enum="ConnectionType"
-    expires_after="2013-04-09">
-  <obsolete>
-    The count was inaccurate (it counted transactions rather than connections).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Each bucket is a boolean (0 or 1) indicating whether the user has had a
-    connection of that type during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.HadConnectionType2" enum="ConnectionType"
-    expires_after="2013-04-09">
-  <obsolete>
-    This statistic measures successful and failed connections, the new one only
-    measures successful ones.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Each bucket is a boolean (0 or 1) indicating whether the user has had a
-    connection of that type during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.HadConnectionType3" enum="ConnectionType"
-    expires_after="2016-05-20">
-  <obsolete>
-    Removed May 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    Each bucket is a boolean (0 or 1) indicating whether the user has had a
-    successful connection of that type during the session.
-  </summary>
-</histogram>
-
-<histogram name="Net.HadFtpServerType" enum="FtpServerType"
-    expires_after="2014-06-20">
-  <obsolete>
-    Replaced by Net.HadFtpServerType2 on 2012-11-13.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>
-    Each bucket is the number of sessions that encountered a given FTP server
-    type. Each session reports a given server type at most once.
-  </summary>
-</histogram>
-
-<histogram name="Net.HadFtpServerType2" enum="FtpServerType2"
-    expires_after="2019-04-23">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>phajdan.jr@chromium.org</owner>
-  <summary>
-    Each bucket is the number of sessions that encountered a given FTP server
-    type. Each session reports a given server type at most once.
-  </summary>
-</histogram>
-
-<histogram name="Net.HstsInfo" enum="HstsInfo" expires_after="2020-05-31">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Recorded for each host where we query the HSTS state, details on whether the
-    implementation matched the specification. See https://crbug.com/821811.
-  </summary>
-</histogram>
-
-<histogram name="Net.Http2ResponseStatusHeader" enum="StatusHeader"
-    expires_after="2017-03-29">
-  <obsolete>
-    Removed in 2017 March.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>Format of :status header value in HTTP/2 response.</summary>
-</histogram>
-
-<histogram name="Net.Http2SSLCipherSuite" enum="SSLCipherSuite"
-    expires_after="2017-02-13">
-  <obsolete>
-    Removed 2017-02.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    The SSL/TLS cipher suite that was negotiated, recorded for each successful
-    HTTP/2 connection.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheAddEvicted" enum="BooleanDidEvict"
-    expires_after="M77">
-  <obsolete>
-    Removed in Chrome 77.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Whether adding an entry to the HTTP auth cache evicted another entry.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheAddEvictedCreation" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed in Chrome 77.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    When an HTTP auth cache entry is evicted, the time since it was created.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheAddEvictedLastUse" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed in Chrome 77.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    When an HTTP auth cache entry is evicted, the time since it was last used.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheAddPathEvicted" enum="BooleanDidEvict"
-    expires_after="M77">
-  <obsolete>
-    Removed in Chrome 77.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    Whether adding a path to an entry in the HTTP auth cache evicted another
-    path.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheEntriesExaminedWhenNoMatch" units="units"
-    expires_after="2018-10-12">
-  <obsolete>
-    Removed 10/2018 when changing the cache implementation such that the number
-    of entries examined no longer applies.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <summary>
-    The number of entries examined (equal to the cache size) when attempting to
-    look up an HTTP auth cache entry (either by path or realm) and finding no
-    matching entries. This is recorded whenever the lookup fails (i.e., value 0
-    in Net.HttpAuthCacheLookupPosition and
-    Net.HttpAuthCacheLookupByPathPosition).
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheLookupByPathPosition" units="units"
-    expires_after="2018-10-12">
-  <obsolete>
-    Removed 10/2018 when changing the cache implementation such that the lookup
-    position no longer applies.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    When looking up an HTTP auth cache entry by path, the position (1-indexed)
-    of the entry on a hit, or 0 on a miss.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthCacheLookupPosition" units="units"
-    expires_after="2018-10-12">
-  <obsolete>
-    Removed 10/2018 when changing the cache implementation such that the lookup
-    position no longer applies.
-  </obsolete>
-  <owner>asanka@chromium.org</owner>
-  <summary>
-    When looking up an HTTP auth cache entry by realm, the position (1-indexed)
-    of the entry on a hit, or 0 on a miss.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpAuthResource" enum="HttpAuthResource"
-    expires_after="2014-09-09">
-  <obsolete>
-    Removed in https://crrev.com/209100
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Count of authentication requests for top level pages vs. sub-resources, such
-    as images or iframes.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpConnectionLatency" units="ms"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time between the HttpNetworkTransaction requesting a connection and the time
-    it connected.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLength" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Replaced by Net.HttpContentLengthV2
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body. This is the actual number of bytes received,
-    which usually agrees with but is not necessarily the same as the size
-    specified by the Content-Length header.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLengthCacheable" units="bytes"
-    expires_after="2018-04-04">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body if it is cacheable. This is the actual number of
-    bytes received, which usually agrees with but is not necessarily the same as
-    the size specified by the Content-Length header.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLengthCacheable24Hours" units="bytes"
-    expires_after="2018-04-04">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body if it is cacheable for at least 24 hours. This is
-    the actual number of bytes received, which usually agrees with but is not
-    necessarily the same as the size specified by the Content-Length header.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLengthCacheable4Hours" units="bytes"
-    expires_after="2018-04-04">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body if it is cacheable for at least 4 hours. This is
-    the actual number of bytes received, which usually agrees with but is not
-    necessarily the same as the size specified by the Content-Length header.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLengthDifference" units="bytes"
-    expires_after="2018-06-04">
-  <obsolete>
-    Removed 06/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The difference between the size specified in the X-Original-Content-Length
-    header and the size of the response body. This is zero if the
-    X-Original-Content-Length header is not present in the response.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpContentLengthWithValidOCL" units="bytes"
-    expires_after="2018-04-04">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size of the response body. Only includes resources that have the
-    X-Original-Content-Length header.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpHeaderParserEvent" enum="HttpHeaderParserEvent"
-    expires_after="2016-12-08">
-  <obsolete>
-    Removed as of 12/2016.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Records the frequency with which a number of hacky HTTP header parsing rules
-    are invoked. This histogram should be removed after we have enough data to
-    know if we can remove the hacks.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpOriginalContentLength" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Replaced by Net.HttpOriginalContentLengthV2.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Size specified in the X-Original-Content-Length header. If this header is
-    not present in the response, the size of the response body is used.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpProxySocketRequestTime" units="ms"
-    expires_after="2016-10-13">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>Time it takes to request a new (unused) HTTP proxy socket.</summary>
-</histogram>
-
-<histogram name="Net.HttpRequest.ContainsInvalidHeaderValuesInRFC7230"
-    enum="Boolean" expires_after="2016-06-28">
-  <obsolete>
-    Removed 06/2016 because this is not continuously tracked.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    Whether a request contains invalid request header values in RFC 7230. This
-    is counted once for every redirect leg. https://crbug.com/455099.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpRequestCompletionErrorCodes" enum="NetErrorCodes"
-    expires_after="M80">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The network error code that the HTTP request completes with, including OK
-    and ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpRequestCompletionErrorCodes.MainFrame"
-    enum="NetErrorCodes" expires_after="M77">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The network error code that the HTTP main frame resource request completes
-    with, including OK and ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpResponse.ContainsInvalidHeaderValuesInRFC7230"
-    enum="Boolean" expires_after="2016-06-28">
-  <obsolete>
-    Removed 06/2016 because this is not continuously tracked.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <summary>
-    Whether a response contains invalid response header values in RFC 7230. This
-    is counted once for every redirect leg. https://crbug.com/455099.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpResponseCode_Nxx_MainFrame" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019. Net.HttpResponseCode has similar information, but for
-    all resources, not just the main frame, and includes the full response code.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    The count of HTTP Response codes encountered, in response to MAIN_FRAME
-    requests only; saving only the hundreds digit, e.g. 100-&gt;1, 300-&gt;3.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpResponseInfo.ConnectionInfo" enum="ConnectionInfo"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed as of 06/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Application protocol used in HTTP response. Recorded every time a URLRequest
-    completes.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpResponseInfo.ConnectionInfo.MainFrame"
-    enum="ConnectionInfo" expires_after="2018-07-03">
-  <obsolete>
-    Removed as of July 2018.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Application protocol used in HTTP responses to requests for main frames.
-    Only includes requests that went over the network.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpResponseInfo.ConnectionInfo.SubResource"
-    enum="ConnectionInfo" expires_after="2018-07-03">
-  <obsolete>
-    Removed as of July 2018.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Application protocol used in HTTP responses to requests for resources other
-    than main frames. Does not include internal Chrome requests. Only includes
-    requests that went over the network.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpServerProperties.UpdatePrefs"
-    enum="HttpServerPropertiesUpdatePrefsLocation" expires_after="2018-08-30">
-  <obsolete>
-    Removed as of July 2019.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The location in http_server_properties_manager.cc where UpdatePrefs was
-    called.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpSocketType" enum="HttpSocketType"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The counts of the type of sockets (all HTTP sockets, regardless of any proxy
-    used) used for HTTP[s].
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpStatusLineStatus" enum="HttpStatusLineStatus"
-    expires_after="2016-12-08">
-  <obsolete>
-    Removed as of 12/2016.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    Records how often violations of RFC 7230's header parsing rules are
-    observed.
-  </summary>
-</histogram>
-
-<histogram name="Net.HttpStreamFactoryJob.Alt.NextState"
-    enum="HttpStreamFactoryJobState" expires_after="2018-01-04">
-  <obsolete>
-    Removed as of 1/2018.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Reports the next state that the Alternative Job is in.</summary>
-</histogram>
-
-<histogram name="Net.HttpStreamFactoryJob.Alt.State"
-    enum="HttpStreamFactoryJobState" expires_after="2018-01-04">
-  <obsolete>
-    Removed as of 1/2018.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Reports the state that the Alternative Job is in.</summary>
-</histogram>
-
-<histogram name="Net.HttpStreamFactoryJob.Main.NextState"
-    enum="HttpStreamFactoryJobState" expires_after="2018-01-04">
-  <obsolete>
-    Removed as of 1/2018.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Reports the next state that the Main Job is in.</summary>
-</histogram>
-
-<histogram name="Net.HttpStreamFactoryJob.Main.State"
-    enum="HttpStreamFactoryJobState" expires_after="2018-01-04">
-  <obsolete>
-    Removed as of 1/2018.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>Reports the state that the Main Job is in.</summary>
-</histogram>
-
-<histogram name="Net.HttpStreamFactoryJob.StreamReadyCallbackTime" units="ms"
-    expires_after="2017-08-07">
-  <obsolete>
-    Removed 08/2017. No longer tracked.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>Time it takes for OnStreamReadyCallback to be called.</summary>
-</histogram>
-
-<histogram name="Net.HttpTimeToFirstByte.LargeUpload" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Time from when an HTTP request is issued to when the first byte is
-    processed, for requests with an upload that is &gt; 1 MiB. Excludes chunked
-    uploads.
-  </summary>
-</histogram>
-
-<histogram name="Net.IOError_SocketReuseType" enum="HttpSocketType"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of handleable socket errors (connection abort/close/reset) per
-    socket reuse type.
-  </summary>
-</histogram>
-
-<histogram name="Net.IOError_SocketReuseType_disable_late_binding"
-    enum="HttpSocketType" expires_after="2013-04-09">
-  <obsolete>
-    Late bindings are on by default now.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of handleable socket errors (connection abort/close/reset) per
-    socket reuse type. Socket late binding is disabled.
-  </summary>
-</histogram>
-
-<histogram name="Net.IOError_SocketReuseType_enable_late_binding"
-    enum="HttpSocketType" expires_after="2013-04-09">
-  <obsolete>
-    Late bindings are on by default now.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of handleable socket errors (connection abort/close/reset) per
-    socket reuse type. Socket late binding is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Net.IOThreadCreationToHttpRequestStart" units="ms"
-    expires_after="2014-11-13">
-  <obsolete>
-    Removed 11/2014. No longer tracked.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Time from when the IOThread is created to when the first URL request is
-    started. Only requests that are created for a profile while Chrome is
-    starting up are considered.
-  </summary>
-</histogram>
-
-<histogram name="Net.IPv6ConnectDuration" units="ms" expires_after="2015-01-06">
-  <obsolete>
-    Removed 1/2015. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Duration of time spent during the UDP-connect IPv6 probe.</summary>
-</histogram>
-
-<histogram name="Net.IPv6ConnectFailureMatch" enum="BooleanSuccess"
-    expires_after="2015-03-30">
-  <obsolete>
-    Removed 03/2015. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether the interface-enumeration IPv6 probe method failed given that the
-    UDP-connect IPV6 probe failed.
-  </summary>
-</histogram>
-
-<histogram name="Net.IPv6ConnectSuccessMatch" enum="BooleanSuccess"
-    expires_after="2015-03-30">
-  <obsolete>
-    Removed 03/2015. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether the interface-enumeration IPv6 probe method was successful given
-    that the UDP-connect IPV6 probe was successful.
-  </summary>
-</histogram>
-
-<histogram name="Net.IPv6Status" enum="IPV6ProbeResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The probe results when a test for IPv6 support is done.</summary>
-</histogram>
-
-<histogram name="Net.IPv6Status_retest" enum="IPV6ProbeResult"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The probe results when a test for IPv6 support is done, after a network
-    change event.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfJobController"
-    units="job_controllers" expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of all the job controllers that are still alive if the
-    count is a multiple of 100: 100, 200, 300, etc.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.JobControllerSet.CountOfJobController.NonPreconnect.PendingRequest"
-    units="job_controllers" expires_after="M80">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of JobControllers that are still alive, not created for
-    preconnect, and still have a HttpStreamFactoryImpl::Request pending.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.JobControllerSet.CountOfJobController.NonPreconnect.RequestGone"
-    units="job_controllers" expires_after="M80">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of job controllers that are still alive, not created for
-    preconnect but HttpStreamFactoryImpl::Request has completed.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfJobController.Preconnect"
-    units="job_controllers" expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of job controllers which are used for preconnect and are
-    still alive.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfJobControllerAtShutDown"
-    units="job_controllers" expires_after="2018-01-11">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of all the job controllers that are still alive.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfNonPreconnectAltJob"
-    units="alt_jobs" expires_after="2017-08-28">
-  <obsolete>
-    Removed 08/2017.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of alternative jobs which are still alive.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfNonPreconnectMainJob"
-    units="main_jobs" expires_after="2017-08-28">
-  <obsolete>
-    Removed 08/2017.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>This counts number of main jobs which are still alive.</summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfPendingRequest" units="requests"
-    expires_after="2017-04-19">
-  <obsolete>
-    Removed 04/2017, replaced by
-    Net.JobController.CountOfJobController.NonPreconnect.PendingRequest.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of HttpStreamFactoryImpl::Request which are still alive.
-  </summary>
-</histogram>
-
-<histogram name="Net.JobControllerSet.CountOfPreconnect"
-    units="job_controllers" expires_after="2017-04-19">
-  <obsolete>
-    Removed 04/2017, replaced by
-    Net.JobController.CountOfJobController.Preconnect.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    This counts number of job controllers which are used for preconnect and are
-    still alive.
-  </summary>
-</histogram>
-
-<histogram name="Net.KeepaliveStatisticsRecorder.PeakInflightRequests"
-    units="requests" expires_after="2018-03-07">
-  <obsolete>
-    Removed 02/2018, replaced by
-    Net.KeepaliveStatisticsRecorder.PeakInflightRequests2
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <summary>
-    The peak number of concurrent outstanding requests with keepalive specified.
-  </summary>
-</histogram>
-
-<histogram name="Net.LoadPrefetch.Pattern" enum="PrefetchStatus"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>mattcary@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The completion status of prefetches that have finished loading.
-
-    Measurement occurs at ResourceLoader::ResponseCompleted so requests canceled
-    before that point are not registered.
-
-    This applies to requests with net::LOAD_PREFETCH, used by various
-    prefetching features such as no-state prefetch and RESOURCE_TYPE_PREFETCH.
-
-    Note that &quot;success from cache&quot; means that the
-    UrlRequest::was_cached() was true and unused_since_prefetch was false.
-    &quot;success from network&quot; means that was_cached() was false.
-    &quot;success already prefetched&quot; means that both was_cached() and
-    unused_since_prefetch were true. Validated results are considered cached,
-    even though a conditional network request is made.
-  </summary>
-</histogram>
-
-<histogram name="Net.MTPR_GetProxyForUrl_Thread_Wait_Time" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time that a (non-cancelled) proxy resolution request was stalled waiting
-    for an execution thread, for MultiThreadedProxyResolver.
-  </summary>
-</histogram>
-
-<histogram name="Net.MTPR_GetProxyForUrl_Time" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that it took for a (non-cancelled) proxy resolution request
-    to complete, for MultiThreadedProxyResolver.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetInternalsUi.Feature" enum="NetInternalsUiFeature"
-    expires_after="2015-04-09">
-  <obsolete>
-    Removed in Chrome 44.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Counts the number of browser launches where chrome://net-internals and
-    chrome://net-internals/#tests are used.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorLogging.HeaderOutcome"
-    enum="NetNetworkErrorLoggingHeaderOutcome" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 for cleanup. https://crbug.com/1089011. Not actively used,
-    large size, and information is not actionable.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <summary>
-    When Network Error Logging receives a &quot;NEL:&quot; header, what happens
-    to it.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorLogging.RequestOutcome"
-    enum="NetNetworkErrorLoggingRequestOutcome" expires_after="M80">
-  <obsolete>
-    Removed 11/2019 for cleanup. https://crbug.com/1007122
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <summary>
-    When Network Error Logging observes a completed request that might generate
-    a report, what happens to it. NEL observes all requests, both successful and
-    unsuccessful. It sends reports for successful and unsuccessful requests at
-    specified sampling rates so that error rates can be calculated. Insecure
-    requests are discarded for having an insecure origin regardless of existence
-    of a policy for the origin.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorsRecovered.MainFrame" enum="NetErrorCodes"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How often automatically retrying to download the main frame of a page in
-    response to specific HTTP network errors succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorsRecovered.Subresource" enum="NetErrorCodes"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How often automatically retrying to download a subresource in response to
-    specific HTTP network errors succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorsUnrecovered.MainFrame" enum="NetErrorCodes"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How often automatically retrying to download the main frame of a page in
-    response to specific HTTP network errors returns another network error.
-    Histogram includes only the error code that triggered the retry.
-  </summary>
-</histogram>
-
-<histogram name="Net.NetworkErrorsUnrecovered.Subresource" enum="NetErrorCodes"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    How often automatically retrying to download a subresource in response to
-    specific HTTP network errors returns another network error. Histogram
-    includes only the error code that triggered the retry.
-  </summary>
-</histogram>
-
-<histogram name="Net.NumDuplicateCookiesInDb" units="units"
-    expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-17 as part of cookie histogram cleanup
-    (https://crbug.com/521135).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of duplicate cookies that were present in the cookie store during
-    startup.
-  </summary>
-</histogram>
-
-<histogram name="Net.OCSPRequestFailedTimeMs" units="ms"
-    expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to make one or more HTTP
-    fetches to OCSP responders in order to get revocation information. This
-    measures the amount of time that failures to get OCSP information take.
-  </summary>
-</histogram>
-
-<histogram name="Net.OCSPRequestSuccess" enum="BooleanSuccess"
-    expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to make one or more HTTP
-    fetches to OCSP responders in order to get revocation information. This
-    records the fraction of successful requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.OCSPRequestTimeMs" units="ms" expires_after="2017-04-21">
-  <obsolete>
-    Removed 2017-04-21 as it was Linux/CrOS only.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When validating an HTTPS certificate we may have to make one or more HTTP
-    fetches to OCSP responders in order to get revocation information. This
-    measures the amount of time that each of those requests takes.
-  </summary>
-</histogram>
-
-<histogram name="Net.OCSPResponseStapled" enum="BooleanSuccess"
-    expires_after="2018-12-20">
-  <obsolete>
-    Removed 12/2018.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    When connecting over HTTPS, a server may include an OCSP response as part of
-    the TLS handshake so that clients do not have to fetch it, provided the
-    client requested the server do so. This measures whether or not a server
-    included an OCSP response when it was requested.
-  </summary>
-</histogram>
-
-<histogram name="Net.OSErrorsForGetAddrinfo" enum="ErrorCodesGetaddrinfo_All"
-    expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Positive error code that was returned by the system library
-    &quot;getaddrinfo()&quot;. This error code is platform specific, so when
-    there is a Windows/Linux conflict, both decodings are shown.
-  </summary>
-</histogram>
-
-<histogram name="Net.OSErrorsForGetAddrinfo_Linux"
-    enum="ErrorCodesGetaddrinfo_Linux" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Positive error code that was returned by the system library
-    &quot;getaddrinfo()&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Net.OSErrorsForGetAddrinfo_Mac"
-    enum="ErrorCodesGetaddrinfo_Mac" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Positive error code that was returned by the system library
-    &quot;getaddrinfo()&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Net.OSErrorsForGetAddrinfo_Win"
-    enum="ErrorCodesGetaddrinfo_Win" expires_after="2018-11-08">
-  <obsolete>
-    Removed 11/2018.
-  </obsolete>
-  <owner>mgersh@chromium.org</owner>
-  <summary>
-    Positive error code that was returned by the system library
-    &quot;getaddrinfo()&quot;.
-  </summary>
-</histogram>
-
-<histogram name="Net.PacResultForStrippedUrl" enum="PacResultForStrippedUrl"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 4/27/2016. No longer tracked.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Proxy Auto Config (PAC) allows specifying an arbitrary javascript program to
-    pick network proxies on a per-request basis (based on the URL). This works
-    by calling the script's FindProxyForURL() function with the target URL as
-    its first argument.
-
-    Traditionally, the URL parameter passed into the script contains the exact
-    URL being loaded, except maybe for having stripped the fragment and embedded
-    identity portions of the URL.
-
-    This histogram records what happens when the URL passed into
-    FindProxyForURL() additionally has had its path component stripped. Does it
-    return the same proxy list as when calling FindProxyForURL() with the
-    original (unmodified) URL?
-
-    This comparison is done only when the URL scheme implies a secure channel
-    (i.e. https:// and wss://), in order to gather data for crbug.com/593759.
-  </summary>
-</histogram>
-
-<histogram name="Net.Ping_ResponseStartedTime" units="ms"
-    expires_after="2014-04-17">
-  <obsolete>
-    Removed 4/16/2014. No longer tracked.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    How long it took for an &lt;a ping&gt; request to receive a response. Only
-    recorded if a response was received.
-  </summary>
-</histogram>
-
-<histogram name="Net.Ping_Result" enum="PingResult" expires_after="2014-04-17">
-  <obsolete>
-    Removed 4/16/2014. No longer tracked.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    The result of an &lt;a ping&gt; request, whether it received a response or
-    timed out or failed for some other reason.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectedLinkNavigations" enum="PreconnectedNavigation"
-    expires_after="2016-03-30">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Indicate whether a link navigation was preceded by a recent pre-connect
-    trigger (within 10 seconds). There is a high chance that loading the page
-    used a preconnected TCP session.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectedNavigation" enum="PreconnectedNavigation"
-    expires_after="2016-03-30">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Indicate whether a URLRequest was preceded by a recent pre-connect trigger
-    (within 10 seconds). There is a high chance that loading the resource used a
-    preconnected TCP session.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectMotivation" enum="PreconnectMotivation"
-    expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    When a preconnection is made, indicate what the motivation was.
-
-    Currently, the most common (only?) motivations are SELF_REFERAL,
-    LEARNED_REFERAL and OMNIBOX. The SELF_REFERAL indicates that we made sure a
-    second connection was available for a resource that either was never before
-    seen, or has historically had no subresources. The LEARNED_REFERAL indicates
-    that we &quot;learned&quot; that a subresource was commonly needed, and that
-    motivated the TCP/IP preconnect. The OMNIBOX motivation happens when a
-    search is being suggested, and we preconnect to the search provider.
-    (WARNING: Prior to version 7.517.*, enums 7, 8, and 9 may be confused, as
-    EARLY_LOAD_MOTIVATED was inserted new 6 value.)
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectProxyStatus" enum="ProxyStatus"
-    expires_after="2016-03-30">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Indicate whether there was a proxy to preclude preconnection.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectSkippedToProxyServers" units="count"
-    expires_after="M80">
-  <obsolete>
-    Removed September 2019
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Indicates number of times a preconnect to proxy server was skipped due to an
-    existing pending preconnection request.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectSubresourceEval"
-    enum="PreconnectSubresourceEval" expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    What did we decide to do about a predicted resource, based on the historical
-    expected number of connection that this subresource will require.
-
-    This is basically the current thresholding of the SubresourceExpectation,
-    relative to current static thresholds, and taking into account whether
-    preconnection is enabled (i.e., if preconnection is disabled, we'll never
-    decide to preconnect).
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectSubresourceExpectation" units="units"
-    expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The expected number of connections, times 100, that we'll make to a given
-    subresource, based on learned history.
-
-    By comparing this to thresholds, we decide if we will preconnect,
-    preresolve, or do nothing. This histogram can be used to select those static
-    thresholds.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectTriggerUsed" enum="PreconnectTriggerUsed"
-    expires_after="2016-03-30">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Indicate whether if a preconnect trigger is followed by a resource request
-    (from link navigations) to the host or not. This is to measure precision of
-    link-based preconnect triggers.
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectUtilization" enum="NetPreconnectUtilization"
-    expires_after="2013-04-09">
-  <obsolete>
-    Sourced data corrected, and replaced by NetPreconnectUtilization2
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Indicate final utilization for each attempted socket connection.
-
-    We also include stats for non-speculative sockets. Some socket connections
-    may never connect, and others may never be used (as the user may abort
-    before then).
-  </summary>
-</histogram>
-
-<histogram name="Net.PreconnectUtilization2" enum="NetPreconnectUtilization"
-    expires_after="2018-05-11">
-  <obsolete>
-    Removed in M68 (May 2018)
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Indicate final utilization for each attempted socket connection.
-
-    We also include stats for non-speculative sockets. Some socket connections
-    may never connect, and others may never be used (as the user may abort
-    before then).
-  </summary>
-</histogram>
-
-<histogram name="Net.Predictor.MRUIndex" units="units"
-    expires_after="2016-07-28">
-  <obsolete>
-    Dev data was collected which was good enough to make a decision on the size
-    of the predictor database.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The index into the predictor's MRU on navigation. This is the size the MRU
-    had to be in order to effectively predict subresources for this navigation.
-  </summary>
-</histogram>
-
-<histogram name="Net.Predictor.Startup.DBSize" units="bytes"
-    expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The approximate size in bytes of the predictor's database on startup.
-  </summary>
-</histogram>
-
-<histogram name="Net.Prefetch.Pattern" enum="PrefetchStatus"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The completion status of prefetches that have finished loading.
-
-    Measurement occurs at ResourceLoader::ResponseCompleted so requests canceled
-    before that point are not registered.
-
-    This applies to requests with RESOURCE_TYPE_PREFETCH.
-
-    Note that &quot;success from cache&quot; means that the
-    UrlRequest::was_cached() was true and unused_since_prefetch was false.
-    &quot;success from network&quot; means that was_cached() was false.
-    &quot;success already prefetched&quot; means that both was_cached() and
-    unused_since_prefetch were true. Validated results are considered cached,
-    even though a conditional network request is made.
-  </summary>
-</histogram>
-
-<histogram name="Net.Prefetch.TimeBeforeCancel" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Time spent on prefetch requests before the request was canceled.
-
-    This applies to requests with RESOURCE_TYPE_PREFETCH.
-  </summary>
-</histogram>
-
-<histogram name="Net.Prefetch.TimeSpentOnPrefetchHit" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Time spent on requests that were served from a cache entry whose
-    unused_since_prefetch bit is true.
-  </summary>
-</histogram>
-
-<histogram name="Net.Prefetch.TimeSpentPrefetchingFromCache" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Time spent on prefetch requests when fetched from cache.
-
-    This applies to requests with RESOURCE_TYPE_PREFETCH.
-  </summary>
-</histogram>
-
-<histogram name="Net.Prefetch.TimeSpentPrefetchingFromNetwork" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Time spent on prefetch requests when fetched from the network, including
-    validation time.
-  </summary>
-</histogram>
-
-<histogram name="Net.PrefProxyConfig.GooglezipProxyRemovalCount" units="units"
-    expires_after="M52">
-  <obsolete>
-    Removed in M52.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <summary>
-    Records how many *.googlezip.net Data Reduction Proxies were removed from
-    the effective proxy configuration when a proxy reconfiguration occurs.
-  </summary>
-</histogram>
-
-<histogram name="Net.Priority_High_Latency" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Priority_High_Latency_b.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the start of the http transaction until the first byte of the
-    response for high priority (currently frame and subframe) requests. Only
-    times under 10 minutes are recorded.
-  </summary>
-</histogram>
-
-<histogram name="Net.Priority_High_Latency_b" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the start of the http transaction until the first byte of the
-    response for high priority (currently frame and subframe) requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.Priority_Low_Latency" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Priority_Low_Latency_b.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the start of the http transaction until the first byte of the
-    response for low priority (non-frame/subframe) requests. Only times under 10
-    minutes are recorded.
-  </summary>
-</histogram>
-
-<histogram name="Net.Priority_Low_Latency_b" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the start of the http transaction until the first byte of the
-    response for low priority (non-frame/subframe) requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.Proxy.RedirectDuringConnect"
-    enum="TunnelRedirectHistogramValue" expires_after="2019-05-19">
-  <obsolete>
-    Removed in Chrome 76.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Counts how often a 302 (redirect) response is observed during CONNECT (proxy
-    tunnel establishment). The counts are bucketed by proxy settings source
-    (auto-detect vs explicit) and load type (subresource vs main frame).
-
-    To interpret this histogram, the most interesting property will be the
-    number of users in each of the buckets, which can be used to approximate
-    what fraction of users would be affected by a policy change that blocked
-    redirects on subresources/non-autodetected proxies.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyAuthRequested.HasConnection" units="units"
-    expires_after="2019-03-01">
-  <obsolete>
-    Removed 2019/02/28, in a proxy auth refactor.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    When a PROXY_AUTH_REQUESTED error code is handled in
-    net::HttpStreamFactoryImpl::Job::RunLoop, this is true if connection_ has an
-    associated value.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyPollConfigurationTime" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed at some time before 2014/09/15.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time in milliseconds spent fetch the system proxy configuration, when
-    polling it for changes.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolutionService.PacUrlScheme" enum="PacUrlScheme"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    The breakdown of URL schemes seen for explicitly configured ProxyAutoConfig
-    (PAC). This metric is emitted once each time the proxy settings change
-    (including initial value). Note that this does not count implicitly inferred
-    PAC URLs (from WPAD).
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.AbandonedExecutionTotalTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total amount of time that was spent executing the proxy script during
-    &quot;tracing&quot; runs (executions of the script which discovered a new
-    DNS dependency and were subsequently abandoned).
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.AbandonedExecutionTotalTime"
-    units="ms" expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total amount of time that was spent executing the proxy script during
-    &quot;tracing&quot; runs (executions of the script which discovered a new
-    DNS dependency and were subsequently abandoned).
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.DnsWaitTotalTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total amount of time that was spent in the non-blocking DNS bindings
-    while executing PAC scripts. This includes the times for abandoned
-    executions.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.ExecutionTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time inside of V8 that the proxy script spent executing for
-    the final pass. This includes the time spent in the javascript bindings.
-    This does not include the time spent in abandoned execution passes.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.NumAlerts" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times that alert() was called in the final execution of the
-    script.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.NumErrors" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of errors that were seen in the final execution of the script.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.NumRestarts" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times that the PAC script execution was restarted.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.TotalTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that the proxy resolution took. This includes all the time
-    spent waiting for DNS, PAC script execution, and restarts.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.TotalTimeDNS" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that proxy resolution spent waiting for DNS. This also
-    includes any queuing delays on the origin thread waiting for the DNS result
-    to be processed.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.BlockingDNSMode.UniqueDNS" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of unique DNS hostnames that the PAC script tried to resolve. The
-    *Ex() versions of the bindings count separately.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.DnsWaitTotalTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total amount of time that was spent in the non-blocking DNS bindings
-    while executing PAC scripts. This includes the times for abandoned
-    executions.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.ExecutionTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time inside of V8 that the proxy script spent executing for
-    the final pass. This includes the time spent in the javascript bindings
-    (which is probably dominated by Net.ProxyResolver.DnsWaitTotalTime). This
-    does not include the time spent in abandoned execution passes.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.NumAlerts" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times that alert() was called in the final execution of the
-    script.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.NumErrors" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of errors that were seen in the final execution of the script.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.NumRestarts" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times that the PAC script execution was restarted.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.OriginThreadLatency" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The amount of time it took upon completion to run the final task posted back
-    to the IO thread.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.TotalTime" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that the proxy resolution took. This includes all the time
-    spent waiting for DNS, PAC script execution, and restarts.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.TotalTimeDNS" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that proxy resolution spent waiting for DNS. This also
-    includes any queuing delays on the origin thread waiting for the DNS result
-    to be processed.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.TotalTimeWorkerThread" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The total time that the proxy resolution took, not including the post back
-    to the origin thread. This includes all the time spent waiting for DNS, PAC
-    script execution, and restarts.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.UniqueDNS" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of unique DNS hostnames that the PAC script tried to resolve. The
-    *Ex() versions of the bindings count separately.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyResolver.URLSize" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed in Chrome 39.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The length of the URL that was passed into the PAC script.</summary>
-</histogram>
-
-<histogram name="Net.ProxyService.GetProxyUsingScriptResult"
-    enum="NetErrorCodes" expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    The network error code of resolving a URL by forwarding the request to the
-    proxy resolver and executing the PAC script.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyService.GetProxyUsingScriptTime"
-    units="100s of microseconds" expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    The time taken to resolve a URL by forwarding the request to the proxy
-    resolver and executing the PAC script. This includes PAC script execution,
-    DNS queries, and internal retries. This does not include retries initiated
-    by the user, such as by calling ProxyService::ReconsiderProxyAfterError().
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyService.ResolvedUsingScript" enum="Boolean"
-    expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Whether proxy resolution occured by forwarding the request to the proxy
-    resolver and executing the PAC script. This histogram records all URLs,
-    regardless of whether a proxy configuration is set. Note that in some cases,
-    the system proxy resolver is used. If so, this histogram indicates whether
-    the request was forwarded to the system resolver. However, on desktop
-    platforms, the number of users using the system resolver should be small
-    since the default is to use V8. Hence, the count of emissions to the 'True'
-    bucket on desktop caused by users of the system resolver should be small.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyService.ResolveProxyTime"
-    units="100s of microseconds" expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    The total time taken to resolve a URL. This includes PAC script execution,
-    DNS queries, and internal retries. This does not include retries initiated
-    by the user, such as by calling ProxyService::ReconsiderProxyAfterError().
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyService.ScriptTerminated" enum="BooleanTerminated"
-    expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Whether a proxy resolution resulted in the PAC script terminating
-    unexpectedly. This does not include terminations that occured during
-    initialization of a new proxy resolver. This only happens when the resolver
-    process crashes when using out-of-process PAC.
-  </summary>
-</histogram>
-
-<histogram name="Net.ProxyService.ScriptTerminatedOnInit"
-    enum="BooleanTerminated" expires_after="2017-06-30">
-  <obsolete>
-    Removed as of Chrome 61.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Whether the creation of a new proxy resolver resulted in the PAC script
-    terminating unexpectedly. This only happens when the resolver process
-    crashes when using out-of-process PAC.
-  </summary>
-</histogram>
-
-<histogram name="Net.PublicKeyPinFailureDomain" enum="PublicKeyPinFailedDomain"
-    expires_after="2016-11-01">
-  <obsolete>
-    Removed as of November 2016 because of disuse. Historical data is likely
-    inaccurate due to changes in the data structure that calculated domain IDs
-    for this histogram.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Second-level domains for which we have observed public key pinning failures.
-  </summary>
-</histogram>
-
-<histogram name="Net.PublicKeyPinReportSendingFailure" enum="NetErrorCodes"
-    expires_after="2016-07-20">
-  <obsolete>
-    Removed as of 07/2016. Replaced with Net.PublicKeyPinReportSendingFailure2.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    A validated certificate chain may be subject to additional pinning
-    requirements on a per-domain basis. When pinning requirements are violated,
-    Chrome attempts to send a report about the incident. This records the net
-    error code when sending a pinning violation report fails.
-  </summary>
-</histogram>
-
-<histogram name="Net.PushedStreamAlreadyHasResponseHeaders" enum="Boolean"
-    expires_after="2017-11-17">
-  <obsolete>
-    Removed 11/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Records whether HTTP/2 response headers have already arrived on a pushed
-    stream at the time the stream is matched up with a request. See
-    https://crbug.com/554220.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicAlternativeProxy.Usage"
-    enum="QuicAlternativeProxyUsage" expires_after="M82">
-  <obsolete>
-    Obsoleted in April 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Breakdown of how requests which could potentially make use of an alternative
-    QUIC proxy server use or don't use the QUIC server.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicChromiumPacketReader.ShouldStopReadingInLoop"
-    enum="BooleanHit" expires_after="M82">
-  <obsolete>
-    Removed 11/2019, associated bug is root-caused and fixed.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times that QuicChromiumPacketReader should stop reading in the
-    loop at StartReading. This data will be compared against crashes and help
-    investigate https://crbug.com/1014092.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicChromiumPacketReader.ShouldStopReadingOnReadComplete"
-    enum="BooleanHit" expires_after="M82">
-  <obsolete>
-    Removed 11/2019, associated bug is root-caused and fixed.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times that QuicChromiumPacketReader should stop reading after
-    finishing the previous read. This data will be compared against crashes and
-    help investigate https://crbug.com/1014092.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicClientHelloServerConfig.HowExpired" units="ms"
-    expires_after="2014-08-06">
-  <obsolete>
-    Removed 08/2014, and replaced by
-    Net.QuicClientHelloServerConfig.InvalidDuration.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    How expired server config is for sending inchoate ClientHello to the server.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicClientHelloServerConfig.InvalidDuration" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in 2018.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The time since expiration of server config when we sent inchoate ClientHello
-    to the server.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicClientHelloServerConfigState"
-    enum="QuicServerConfigState" expires_after="2014-11-13">
-  <obsolete>
-    Removed as of 11/2014. Replaced by Net.QuicInchoateClientHelloReason.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The reason (the state of the server config) for sending inchoate ClientHello
-    to the server.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicCloseConnection.NullVisitor" enum="BooleanNullVisitor"
-    expires_after="2018-02-23">
-  <obsolete>
-    Removed 02/2018. No data for this histogram for more than 30 days.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times Connection's visitor is a nullptr when CloseConnection
-    is called.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicCryptoClientConfig.PopulatedFromCanonicalConfig"
-    enum="BooleanPopulated" expires_after="2018-08-30">
-  <obsolete>
-    Removed in 2018.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times CryptoClientConfig's CachedState is populated from
-    canonical config whenever we create a new CryptoClientConfig::CachedState.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicDiskCache.APICall" enum="QuicDiskCacheAPICall"
-    expires_after="2017-04-20">
-  <obsolete>
-    Removed as of 4/15/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Tracks number of times data read/parse/write API calls of QuicServerInfo to
-    and from disk cache is called.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicDiskCache.EntryState" enum="QuicDiskCacheEntryState"
-    expires_after="2014-10-31">
-  <obsolete>
-    Removed as of 10/2014.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Tracks the opening and closing of disk cache entries. Recorded each time a
-    disk cache entry is either opened or closed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicEphemeralPortsSuggested" units="units"
-    expires_after="2016-04-25">
-  <obsolete>
-    Removed as of 04/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>The number of ports suggested per server.</summary>
-</histogram>
-
-<histogram name="Net.QuicHttpStream::DoStreamRequest.IsNullSession"
-    enum="Boolean" expires_after="2016-09-12">
-  <obsolete>
-    Removed 2016. No longer tracked.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times QuicHttpStream's session_ is a nullptr before
-    StartRequest() is called.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicInchoateClientHelloReason"
-    enum="QuicServerConfigState" expires_after="2018-08-30">
-  <obsolete>
-    Removed in 2018.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The reason (the state of the server config) for sending inchoate ClientHello
-    to the server.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicNumSentClientHellosCryptoHandshakeConfirmed"
-    units="units" expires_after="2014-01-22">
-  <obsolete>
-    see Net.QuicSession.Connect*PortForHTTP*
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of client hello messages sent when the crypto handshake was
-    confirmed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicNumStreamFramesInPacket" units="units"
-    expires_after="2021-05-11">
-  <obsolete>
-    Removed in 07/2020.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of stream frames bundled within a received packet.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicNumStreamFramesPerStreamInPacket" units="units"
-    expires_after="2021-05-11">
-  <obsolete>
-    Removed in 07/2020.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of stream frames per stream ID within a received packet.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicReadAvailableData.NullStream" enum="BooleanNullStream"
-    expires_after="2017-05-26">
-  <obsolete>
-    Removed as of 05/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times QuicHttpStream's stream_ is a nullptr before
-    IsDoneReading() is called.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.DiskCacheLoadTime" units="ms"
-    expires_after="2017-04-20">
-  <obsolete>
-    Removed as of 4/15/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>Time spent to load QUIC server information from disk cache.</summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.DiskCacheReadTime" units="ms"
-    expires_after="2014-10-21">
-  <obsolete>
-    Removed as of 10/2014. Replaced by DiskCacheWaitForDataReadyTime.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>Time spent to load QUIC server information from disk cache.</summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.DiskCacheWaitForDataReadyTime" units="ms"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed as of 4/19/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Time spent waiting to load QUIC server information from disk cache.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.ExpectConfigMissingFromDiskCache"
-    enum="BooleanMissingFromDiskCache" expires_after="2017-04-20">
-  <obsolete>
-    Removed as of 4/15/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of times AlternateProtocolMap supports QUIC, but there is no QUIC
-    server information in the disk cache. This is recorded whenever QUIC server
-    information is loaded from the disk cache.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.WaitForDataReady.HandshakeConfirmedTime"
-    units="Milliseconds" expires_after="2017-08-04">
-  <obsolete>
-    Removed as of 8/3/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The elapsed time between waiting for reading of QUIC server information from
-    disk cache, and receiving crypto handshake confirmation from the server.
-    Will measure the impact of cancelling the WaitForDataReady callback. Logged
-    after crypto handshake is confirmed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicServerInfo.WaitForDataReadyToRtt" units="%"
-    expires_after="2017-04-20">
-  <obsolete>
-    Removed as of 4/15/2017.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The ratio of the time spent waiting to load QUIC server information from
-    disk cache to the min rtt. Logged when session is closed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.21CumulativePacketsReceived"
-    units="Received in Ranges" expires_after="2016-08-18">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    This histogram summarizes information about a 21 packet sequence, indicating
-    for each of the 21 possible prefixes of this pattern, how many packets were
-    received in that prefix. The first range uses buckets 0 and 1, and it
-    describes the 1st packet in the sequence. It indicates if the first packet
-    was missing (bucket 0), or the first packet was present (bucket 1). The
-    second range uses buckets 2 through 4, and describes the first 2 packets in
-    the prefix of this sequence. It indicates if there were no packets received
-    in the first two packets (bucket 2), or there was one out of two packets
-    received (bucket 3), or if there was two out of tow received (bucket 4).
-    etc. etc. Reading this histogram may require post-processing in a spread
-    sheet, but can indicate the potential value of using FEC packets to convey
-    data.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.6PacketsPatternsReceived"
-    units="Binay of Packets ACKed" expires_after="2016-08-18">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Each of the 64 buckets represents a different binary pattern of 6
-    consecutive packets that were received by the client. The LSB of the bucket
-    number corresponds to the reception of the oldest packet. A bit in the
-    bucket-number being 1 indicates the packet was received, and a 0 means the
-    packet was never received (by the client).
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.ConnectionCloseErrorCode"
-    enum="QuicErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed in M81.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The QUIC error code which resulted in the Google QUIC connection being
-    closed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.CookieSentToAccountsOverChannelId"
-    enum="BooleanUsage" expires_after="2018-08-30">
-  <obsolete>
-    Removed in M75
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Logs whether channel ID was used when a cookie is sent over QUIC to
-    https://accounts.google.com.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.FailToSerializePacketLocation"
-    enum="QuicFailToSerializePacketLocation" expires_after="2021-05-21">
-  <obsolete>
-    Deprecated 10/2020 because it's no longer needed for analysis.
-  </obsolete>
-  <owner>renjietang@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Record where exactly packet serialization fails for investigation.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.HandshakeRoundTrips" units="RTTs"
-    expires_after="2014-01-22">
-  <obsolete>
-    see Net.QuicSession.Connect*PortForHTTP*
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Samples of the number of round-trips needed by a QUIC connection before a
-    request could be sent by the client.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.HeadersHOLBlockedTime" units="Milliseconds"
-    expires_after="2018-05-09">
-  <obsolete>
-    The experiments with head of line blocking have been completed, and the code
-    tracking head of line blocking was removed.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The elapsed time that headers are head of line blocked on others, presumably
-    due to lost headers stream packets.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.HeadersStream.EarlyFramesReceived"
-    units="units" expires_after="2016-08-17">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The frames received on the headers stream which arrived early.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.HostResolutionTime" units="ms"
-    expires_after="2016-08-17">
-  <obsolete>
-    Removed 08/2016. No longer tracked.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Time spent resolving the DNS name of the server for a QUIC connection.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.InternalErrorLocation"
-    enum="QuicInternalErrorLocation" expires_after="M85">
-  <obsolete>
-    Removed 2018-10. No longer tracked.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The location where a QUIC internal error was generated, recorded any time an
-    internal error is generated, which should be once per connection.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.QuicSession.LocallyTimedOutWithOpenStreams.TimeSinceLastReceived{UnackedPackets}"
-    units="units" expires_after="2021-05-11">
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    If a QUIC connection timed out locally with open streams, this contains the
-    time since any data was read from the network until the connection was
-    closed. The suffix specifies whether there were any unacked packets pending
-    when the connection timed out. {UnackedPackets}
-  </summary>
-  <token key="UnackedPackets">
-    <variant name="" summary="">
-      <obsolete>
-        Removed as of 08/2016.
-      </obsolete>
-    </variant>
-    <variant name=".NoUnackedPackets"
-        summary="The session had no outstanding unacked packets.">
-      <obsolete>
-        Removed as of 08/2016.
-      </obsolete>
-    </variant>
-    <variant name=".UnackedPackets"
-        summary="The session had outstanding unacked packets.">
-      <obsolete>
-        Removed as of 08/2016.
-      </obsolete>
-    </variant>
-  </token>
-</histogram>
-
-<histogram name="Net.QuicSession.NumQueuedPacketsAtOutOfOrder" units="packets"
-    expires_after="M85">
-  <obsolete>
-    Removed 04/2020, no longer needed.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of queued packets when a connection is closed due to writing an
-    out of order packet.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.NumQueuedPacketsBeforeWrite" units="packets"
-    expires_after="M77">
-  <obsolete>
-    Removed in 2018.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of queued packets when a connection starts to write queued
-    packets.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.PacketReceived" units="SequenceNumber"
-    expires_after="2016-08-18">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Each bucket corresponds to a specific packet sequence number that was sent
-    by a server to Chrome at the start of a QUIC connection. This histogram is
-    compared, bucket by bucket, with a second histogram to compute the ratio for
-    each bucket (each packet sequence number).
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.PublicResetAddressMismatch"
-    enum="QuicAddressMismatch" expires_after="2018-03-01">
-  <obsolete>
-    Removed 02/2018. Use Net.QuicSession.PublicResetAddressMismatch2.
-  </obsolete>
-  <owner>wtc@google.com</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    When a public reset packet is received, whether the client IP address and
-    port number in it differ from the client IP address and port number in the
-    ServerHello handshake message. In the comparison, the first address is the
-    one in ServerHello and the second address is the one in public reset. Note:
-    this histogram is obsolete because it failed to treat IPv4-mapped IPv6
-    addresses as IPv4 addresses.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.ReceivedSettings.MaxHeaderListSize"
-    units="bytes" expires_after="2021-04-29">
-  <obsolete>
-    Removed in M84. Use Net.QuicSession.ReceivedSettings.MaxHeaderListSize2
-    instead.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The value of the SETTINGS_MAX_HEADER_LIST_SIZE parameter received on an
-    HTTP/3 connection, if any.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.ReceivedSettings.MaxTableCapacity"
-    units="bytes" expires_after="2021-04-29">
-  <obsolete>
-    Removed in M84. Use Net.QuicSession.ReceivedSettings.MaxTableCapacity2.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The value of the SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter received on an
-    HTTP/3 connection, if any.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.RetryAfterWriteErrorCount" units="retries"
-    expires_after="2017-11-22">
-  <obsolete>
-    Removed 11/2017. Use Net.QuicSession.RetryAfterWriteErrorCount2.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of consecutive times a packet was retried after a write error.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.SentConnectivityProbe" enum="Boolean"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed 03/2018 as crbug.com/817496 is resolved.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    The number of times the connection sends connectivity probe to the peer.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.SessionAvailableWhenValidatingDNS"
-    enum="BooleanAvailable" expires_after="2019-12-31">
-  <obsolete>
-    Removed in 9/19 because this metric was added to inspect a crash and the
-    crash had been fixed.
-  </obsolete>
-  <owner>renjietang@chromium.org</owner>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    True if at the time of Dns comparison between fresh resolution and stale
-    resolution, session_ is valid.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.StaleHostResolveFailed"
-    enum="EmptyStaleResultLocation" expires_after="2019-12-31">
-  <obsolete>
-    Removed in 9/19 because this metric was added to inspect a crash and the
-    crash had been fixed.
-  </obsolete>
-  <owner>renjietang@chromium.org</owner>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    Logs places in code where stale host resolution doesn't have valid results.
-    For control purpose, it also logs when a valid stale result is used.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.TooManyOpenStream" enum="BooleanTooMany"
-    expires_after="2015-04-06">
-  <obsolete>
-    Removed 04/2015. Tracked as Net.QuicSession.TooManyOpenStreams.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    True if more than 100 streams are open when a new stream is activated.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicSession.TruncatedAcksReceived" units="units"
-    expires_after="2016-08-04">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>The number of truncated ACK frames received.</summary>
-</histogram>
-
-<histogram name="Net.QuicSession.TruncatedAcksSent" units="units"
-    expires_after="2016-08-04">
-  <obsolete>
-    Removed 08/2016.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>The number of truncated ACK frames sent.</summary>
-</histogram>
-
-<histogram name="Net.QuicSession.WriteOutOfOrderQueuedPacketAfterClose"
-    enum="Boolean" expires_after="2018-06-12">
-  <obsolete>
-    Removed 06/2018 after https://crbug.com/818040 is fixed.
-  </obsolete>
-  <owner>wub@chromium.org</owner>
-  <summary>
-    Temporary histogram being used to investigate https://crbug.com/818040.
-    Records whether a connection is closed when an out of order queued packet is
-    about to be written.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicStreamFactory.MigrationBeforeHandshake"
-    enum="BooleanSuccess" expires_after="2020-11-01">
-  <obsolete>
-    Removed 11/2018. Replaced by MigrationBeforeHandshake2.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    Status of the connection which is created for migration before handshake is
-    confirmed.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicStreamFactory.NumDegradingSessions" units="sessions"
-    expires_after="2021-05-11">
-  <obsolete>
-    Depecated on 07/2020. Replaced by
-    Net.QuicConnectivityMonitor.NumAllDegradedSessions.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of sessions that are degrading on network change. The suffix
-    specifies the network change.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicStreamFactory.NumQuicSessionsAtNetworkChange"
-    units="units" expires_after="2021-05-11">
-  <obsolete>
-    Deprecated on 07/2020. Replaced by
-    Net.QuicConnectivityMonitor.NumActiveQuicSessionsAtNetworkChange.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>rockot@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    The number of QUIC sessions when a network change is detected.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicStreamFactory.PercentageDegradingSessions" units="%"
-    expires_after="2021-05-11">
-  <obsolete>
-    Depecated on 07/2020. Replaced by
-    Net.QuicConnectivityMonitor.PercentageAllDegradedSessions.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Of all the exisiting sessions, the percentage of sessions that detects
-    degrading on network change. The suffix specifies the network change.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicStreamFactory.TSVIPCliIsLoaded" enum="Boolean"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed 06/2016. No longer tracked.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Whether TSVIPCli DLL is loaded or not on windows when the socket is
-    configured.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicTimeBetweenTwoPacketSent" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    Removed 08/2016. No longer tracked.
-  </obsolete>
-  <owner>zhongyi@chromium.org</owner>
-  <summary>
-    Time duration from last packet sent to a new packet sent in QUIC connection.
-  </summary>
-</histogram>
-
-<histogram name="Net.QuicVerifyProofFailed.HandshakeConfirmed"
-    enum="BooleanHandshakeConfirmed" expires_after="M77">
-  <obsolete>
-    Removed in 2018.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/quic/OWNERS</owner>
-  <summary>
-    Logged whenever proof verification fails and if the failure occurred before
-    or after the crypto handshake is confirmed.
-  </summary>
-</histogram>
-
-<histogram name="Net.RenegotiationExtensionSupported" units="units"
-    expires_after="2015-03-30">
-  <obsolete>
-    Removed 03/2015. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    True if the HTTP request was sent to a server which supports the TLS
-    renegotiation extension.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.HeaderEndpointGroupOutcome"
-    enum="NetReportingHeaderEndpointGroupOutcome" expires_after="M77">
-  <obsolete>
-    Removed 06/2020. No longer tracked.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a single endpoint group in a
-    Report-To header once the header itself has been parsed.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.HeaderEndpointOutcome"
-    enum="NetReportingHeaderEndpointOutcome" expires_after="M77">
-  <obsolete>
-    Removed 06/2020. No longer tracked.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a single endpoint in a Report-To
-    header once the header itself has been parsed.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.HeaderOutcome" enum="NetReportingHeaderOutcome"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020. No longer tracked.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a Report-To header. Once it is
-    parsed, Reporting.HeaderEndpointOutcome records the outcome of the endpoints
-    within it.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.ReportDeliveredAttempts" units="attempts"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020 for cleanup. https://crbug.com/1089017
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    When Reporting successfully delivers a report, the number of unsuccessful
-    delivery attempts that preceded the successful one.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.ReportDeliveredLatency" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020 for cleanup. https://crbug.com/1089017
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The delivery latency of reports successfully delivered by Reporting. Starts
-    when the report is queued and finishes when the delivery attempt returns
-    successfully.
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.UploadError"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M85">
-  <obsolete>
-    Removed June 2020 for cleanup. https://crbug.com/1089017
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The error (net or HTTP) encountered by Reporting trying to upload one or
-    more reports to a single endpoint in a single request, recorded when the
-    upload attempt completes, if and only if the attempt failed with a net error
-    or an HTTP error other than 410 (which is specified to mean &quot;remove
-    endpoint&quot;).
-  </summary>
-</histogram>
-
-<histogram name="Net.Reporting.UploadOutcome" enum="NetReportingUploadOutcome"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020 for cleanup. https://crbug.com/1089017
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to upload one or more reports to a single
-    endpoint in a single request, recorded when the upload attempt completes.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime" units="units" expires_after="2015-07-08">
-  <obsolete>
-    Replaced by Net.RequestTime2 due to bug in original implementation.
-  </obsolete>
-  <summary>
-    The amount of time between request initiation and request completion for
-    success and various different errors.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2" units="units" expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <summary>
-    The amount of time between request initiation and request completion for
-    success and various different errors.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2.ErrAborted.HttpScheme" units="ms"
-    expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    ERR_ABORTED when the request's scheme is http/s.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2.ErrAborted.NetworkContent" units="ms"
-    expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    ERR_ABORTED when the requests TotalReceivedBytes() &gt; 0.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2.ErrAborted.NoBytesRead" units="ms"
-    expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    ERR_ABORTED when the requests TotalReceivedBytes() = 0 and
-    received_response_content_length() = 0.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2.ErrAborted.NoNetworkContent.CachedContent"
-    units="ms" expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    ERR_ABORTED when the requests TotalReceivedBytes() = 0 and
-    received_response_content_length() &gt; 0.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2.ErrAborted.NonHttpScheme" units="ms"
-    expires_after="2017-09-01">
-  <obsolete>
-    Unused, so removed from Chromium as of 2017/8/31.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    ERR_ABORTED when the request's scheme is not http/s.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2Success.MainFrame" units="ms"
-    expires_after="2018-07-02">
-  <obsolete>
-    Removed from Chromium as of 2018/7/2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    success for main frame resources.
-  </summary>
-</histogram>
-
-<histogram name="Net.RequestTime2Success.Subresource" units="ms"
-    expires_after="2018-07-02">
-  <obsolete>
-    Removed from Chromium as of 2018/7/2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The amount of time between request initiation and request completion for
-    success for non-main frame resources.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.OutstandingRequests.PerProcess"
-    units="requests" expires_after="2018-07-09">
-  <obsolete>
-    Removed from Chromium as of 2018/7.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    The largest number of outstanding requests that are handled by the resource
-    dispatcher host for a single process.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.OutstandingRequests.Total"
-    units="requests" expires_after="2018-07-09">
-  <obsolete>
-    Removed from Chromium as of 2018/7.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    The largest number of outstanding requests that are handled by the resource
-    dispatcher host across all processes.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.PeakOutstandingRequests"
-    units="requests" expires_after="2018-03-28">
-  <obsolete>
-    Removed from code as of 03/2018.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The largest number of outstanding requests handled by the resource
-    dispatcher host, during the last sample interval (60 seconds). Not logged if
-    there are no outstanding requests in the interval. This metric is temporary
-    for the Loading Dispatcher v0 (crbug.com/723233), and will be removed soon.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.RequestMode.Get"
-    enum="FetchRequestMode" expires_after="M69">
-  <obsolete>
-    Removed from code as of 11/2018.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>
-    Records request mode (https://fetch.spec.whatwg.org/#concept-request-mode)
-    for HTTP &quot;GET&quot; requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.RequestMode.Post"
-    enum="FetchRequestMode" expires_after="M69">
-  <obsolete>
-    Removed from code as of 11/2018.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>
-    Records request mode (https://fetch.spec.whatwg.org/#concept-request-mode)
-    for HTTP &quot;POST&quot; requests.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceDispatcherHost.RequestMode.Post.WithPort"
-    enum="FetchRequestMode" expires_after="M69">
-  <obsolete>
-    Removed from code as of 11/2018.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>toyoshim@chromium.org</owner>
-  <summary>
-    Records request mode (https://fetch.spec.whatwg.org/#concept-request-mode)
-    for HTTP &quot;POST&quot; requests whose url contains a port.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceLoader.ExpectedContentSizeResult"
-    enum="ResourceLoaderExpectedContentSizeResult" expires_after="2017-10-11">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <owner>maksim.sisov@intel.com</owner>
-  <summary>
-    Records how many times expected content size equals/less/more than size of
-    read body/buffer or content size is unkown. Recorded for each resource load.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceLoader.InliningStatus"
-    enum="ResourceLoaderInliningStatus" expires_after="2017-03-22">
-  <obsolete>
-    This experiment was turned down, see https://crbug.com/703188.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Counts whether the chunk inlining is applicable or not to a resource
-    loading. Counts the reason if inapplicable.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceLoader.ResponseStartToEnd" units="microseconds"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020, no longer needed.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Time from the start to the end of receiving a response body. Recorded for
-    each resource load.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResourceLoader.TimeToURLRequestStart" units="ms"
-    expires_after="2018-07-02">
-  <obsolete>
-    Removed from Chromium as of 2018/7/2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time elapsed from URLRequest creation to when a ResourceLoader actually
-    calls Start on it.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResponseSizeByProcess.Browser" units="KB"
-    expires_after="2017-11-14">
-  <obsolete>
-    The code to record this histogram was removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Count of (post-SSL/proxy, pre-filter) kilobytes received per request made by
-    the browser process.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResponseSizeByProcess.Renderer" units="KB"
-    expires_after="2017-11-14">
-  <obsolete>
-    The code to record this histogram was removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Count of (post-SSL/proxy, pre-filter) kilobytes received per request made by
-    a renderer process.
-  </summary>
-</histogram>
-
-<histogram name="Net.ResponseSizeByProcess.Unknown" units="KB"
-    expires_after="2017-11-14">
-  <obsolete>
-    The code to record this histogram was removed November 2017.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    Count of (post-SSL/proxy, pre-filter) kilobytes received per request made by
-    a process not covered by one of the other ResponseSizeByProcess histograms.
-  </summary>
-</histogram>
-
-<histogram name="Net.RestrictedCookieManager.SetCanonicalCookieDomainMatch"
-    enum="Boolean" expires_after="2020-08-30">
-  <obsolete>
-    Removed Aug 2020. This was added to evaluate safety of proposed code
-    changes, and is no longer necessary as the necessary results were obtained.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Logged whenever the RestrictedCookieManager sets a CanonicalCookie. True if
-    the domain of the cookie matches the domain of the URL, false otherwise.
-  </summary>
-</histogram>
-
-<histogram name="Net.Socket.IdleSocketFate" enum="IdleSocketFate"
-    expires_after="2017-09-21">
-  <obsolete>
-    Removed as of 9/2017.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Whether an idle socket is reused, timed out, or closed to make room for new
-    sockets.
-  </summary>
-</histogram>
-
-<histogram name="Net.Socket.IdleSocketReuseTime" units="seconds"
-    expires_after="2017-07-14">
-  <obsolete>
-    Removed as of 7/2017.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Seconds a socket was idle before it was reused. Emitted upon reuse. Does not
-    record the times sockets were idle before first use.
-  </summary>
-</histogram>
-
-<histogram name="Net.Socket.IdleSocketTimeSaving" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed as of 11/2016.
-  </obsolete>
-  <owner>mef@chromium.org</owner>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Number of milliseconds an idle socket saved in connection establishment
-    because it is reused.
-  </summary>
-</histogram>
-
-<histogram name="Net.Socket.NumIdleSockets" units="units" expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>Number of idle sockets when one of them was reused.</summary>
-</histogram>
-
-<histogram name="Net.SocketIdleTimeBeforeNextUse_ReusedSocket" units="units"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time an already used socket sat idle before being used.</summary>
-</histogram>
-
-<histogram name="Net.SocketIdleTimeBeforeNextUse_UnusedSocket" units="units"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an unused socket (all HTTP sockets, regardless of any proxy used)
-    sat idle before being used.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketIdleTimeOnIOError2_ReusedSocket" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time a previously used socket sat idle before encountering a recoverable
-    socket IO error (connection abort/reset/close).
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketIdleTimeOnIOError2_UnusedSocket" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an unused socket sat idle before encountering a recoverable socket
-    IO error (connection abort/reset/close).
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketInitErrorCodes" enum="NetErrorCodes"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Net error codes that socket initializations end with, including net::OK and
-    net::ERR_ABORTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketReceiveBufferUnchangeable" units="Bytes"
-    expires_after="2014-04-09">
-  <obsolete>
-    Replaced by Net.SocketUnchangeableReceiveBuffer 3/31/2014.
-  </obsolete>
-  <summary>
-    The size of a socket's receive buffer when the attempt to change it via
-    setsockopt failed.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketRequestTime" units="units"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time in milliseconds from initial RequestSocket() call until successfully
-    acquiring a connected socket.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ConnectionEstablish" units="ms"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>The time from the connection start to connection establish.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ConnectionLatency" units="ms"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>The time waiting to be ready to start connecting.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ConnectionType"
-    enum="SocketStreamConnectionType" expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Each bucket is the number of connection type of socket stream.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketStream.Duration" units="ms"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. Replaced by Net.WebSocket.Duration.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>The time a socket stream was open.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ProtocolType" enum="SocketStreamProtocolType"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Each bucket is the number of protocol type on socket stream.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ReceivedBytes" units="bytes"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>Number of bytes on a socket stream.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.ReceivedCounts" units="units"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>Number of reads on a socket stream.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.SentBytes" units="bytes"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>Number of bytes on a socket stream.</summary>
-</histogram>
-
-<histogram name="Net.SocketStream.SentCounts" units="units"
-    expires_after="2014-11-05">
-  <obsolete>
-    Removed 2014-10-28. No longer generated. No direct replacement.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>Number of Write on a socket stream.</summary>
-</histogram>
-
-<histogram name="Net.SocketType" enum="HttpSocketType"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed as of 03/2015.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The counts of the type of sockets returned by the socket pools.
-  </summary>
-</histogram>
-
-<histogram name="Net.SOCKSSocketIdleTimeBeforeNextUse_ReusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete>
-    see SocketIdleTimeBeforeNextUse_ReusedSocket_SOCK
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an already used SOCKS socket sat idle before being used.
-  </summary>
-</histogram>
-
-<histogram name="Net.SOCKSSocketIdleTimeBeforeNextUse_UnusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete>
-    see SocketIdleTimeBeforeNextUse_UnusedSocket_SOCK
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The time an unused SOCKS socket sat idle before being used.</summary>
-</histogram>
-
-<histogram name="Net.SOCKSSocketRequestTime" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    see SocketRequestTime_SOCK
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from initial SOCKSClientSocketPool::RequestSocket() call until
-    successfully acquiring a connected SOCKS socket.
-  </summary>
-</histogram>
-
-<histogram name="Net.SocksSocketRequestTime" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time it takes to request a new (unused) SOCKS proxy socket.</summary>
-</histogram>
-
-<histogram name="Net.SOCKSSocketType" enum="HttpSocketType"
-    expires_after="2013-04-09">
-  <obsolete>
-    see SocketType_SOCK
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The counts of the type of sockets returned by the SOCKS pool.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyConnectionLatency" units="ms"
-    expires_after="2014-10-22">
-  <obsolete>
-    Replaced by Net.SpdyConnectionLatency_2 on 2014-10-21.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>Time from when the Connect() starts until it completes.</summary>
-</histogram>
-
-<histogram name="Net.SpdyConnectionLatency_2" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed 2018-02.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>Time from when the Connect() starts until it completes.</summary>
-</histogram>
-
-<histogram name="Net.SpdyFrameStreamFlowControlState"
-    enum="SpdyFrameFlowControlState" expires_after="2016-01-19">
-  <obsolete>
-    The last protocol which would trigger this was deprecated in 2014 November.
-    This histogram is deprecated in 2016 January.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The counts of the flow control state of each frame (with stream flow control
-    on).
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyHighestQueuedCappedFramesCount" units="units"
-    expires_after="M82">
-  <obsolete>
-    Removed in 2020-03 once we confirmed the numbers looked as expected.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <summary>
-    The highest number of capped frames queued in the SPDY write queue.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyHpackEncodedCharacterFrequency" units="ASCII codes"
-    expires_after="2015-03-26">
-  <obsolete>
-    Obsolete as HTTP/2 standard is finalized.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Frequencies of characters observed in request and response headers.
-    Temporarily being collected to inform the construction of an optimized
-    Huffman code for the HTTP/2 specification. Buckets are ASCII codes offset by
-    1.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyPing.RTT" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 2019-10-01.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The RTT for SPDY's PING.</summary>
-</histogram>
-
-<histogram name="Net.SpdyPriorityCount" units="units"
-    expires_after="2016-05-27">
-  <obsolete>
-    Removed 2016-05-26.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The count of streams at each priority over Spdy sessions.</summary>
-</histogram>
-
-<histogram name="Net.SpdyRecvBytes" units="bytes" expires_after="M80">
-  <obsolete>
-    Removed because it took up too much space and nobody used it.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The number of bytes recevied per stream.</summary>
-</histogram>
-
-<histogram name="Net.SpdySendBytes" units="bytes" expires_after="M80">
-  <obsolete>
-    Removed because it took up too much space and nobody used it.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The number of bytes sent per stream.</summary>
-</histogram>
-
-<histogram name="Net.SpdySession.BytesRead.EOF" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Total number of bytes recevied per session before closing session due to
-    EOF.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySession.BytesRead.OtherErrors" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Total number of bytes recevied per session before closing session due to an
-    error during read.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessionErrorDetails" enum="SpdyProtocolErrorDetails"
-    expires_after="2013-04-19">
-  <obsolete>
-    Replaced by SpdySessionErrorDetails2 on 2013-04-19.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    WARNING: r181910 added an enum value in the middle, so don't trust the
-    counts for values 9 and above for Chrome builds after that revision.
-
-    The type of SPDY Protocol error encountered.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessionErrorDetails_Google"
-    enum="SpdyProtocolErrorDetails" expires_after="2013-04-19">
-  <obsolete>
-    Replaced by SpdySessionErrorDetails_Google2 on 2013-04-19.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The type of SPDY Protocol error encountered when talking to a google.com
-    server.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessions_DataReductionProxy"
-    enum="BooleanDataReductionProxy" expires_after="2014-09-22">
-  <obsolete>
-    Removed 7/21/2014. No longer tracked.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The count of SPDY sessions using the data reduction proxy and the count of
-    other SPDY sessions.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessionSocketNotConnectedGetLocalAddress"
-    enum="BooleanSuccess" expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    SpdySession::GetLocalAddress returned ERR_SOCKET_NOT_CONNECTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessionSocketNotConnectedGetPeerAddress"
-    enum="BooleanSuccess" expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    SpdySession::GetPeerAddress returned ERR_SOCKET_NOT_CONNECTED.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySessionsWithStalls" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The count of SPDY Sessions with or without stalls.</summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsCwnd" units="packets"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The congestion window (in pkts) received at the end of a SpdySession.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsCwndSent" units="packets"
-    expires_after="2016-07-14">
-  <obsolete>
-    Removed 2016 July with removal of SPDY/3.1.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The congestion window (in pkts) sent at the beginning of a SpdySession.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsReceived" enum="SpdySettingsReceived"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Percentage of sessions which received settings from the server.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsRetransRate" units="%"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The Download Retransmission Rate (%) received at the end of a SpdySession.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsRTT" units="ms" expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The RTT received at the end of a SpdySession.</summary>
-</histogram>
-
-<histogram name="Net.SpdySettingsSent" enum="SpdySettingsSent"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>Percentage of sessions which sent settings to the server.</summary>
-</histogram>
-
-<histogram name="Net.SpdyStreamDownloadTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed because it took up too much space and nobody used it.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The time between receiving the first chunk and the last chunk of data on a
-    Spdy stream.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyStreamStallsPerSession" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-10-10.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>The number of stream stalls per session.</summary>
-</histogram>
-
-<histogram name="Net.SpdyStreamTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed because it took up too much space and nobody used it.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The time of a Spdy stream. Measured from sending the first chunk to
-    receiving the last chunk of data.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyStreamTimeToFirstByte" units="ms" expires_after="M80">
-  <obsolete>
-    Removed because it took up too much space and nobody used it.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The time between sending the request and receiving the first chunk of data
-    on a Spdy stream.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdySynStreamCompressionPercentage" units="%"
-    expires_after="2016-11-29">
-  <obsolete>
-    Removed on 2016-11-28, because SPDY/3 and, accordingly, SYN_STREAM frames
-    are no longer used. Compression values are now calculated slightly
-    differently. Replaced by Net.SpdyHeadersCompressionPercentage.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The percent compression achieved when compression SYN_STREAM frames.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyVersion" enum="ProtocolVersion"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed on 2014-09-11, because the uploaded values were changing as
-    protocols were removed, therefore statistics couldn't be combined across
-    different builds. Replaced by Net.SpdyVersion2.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The SPDY protocol version that is used to talk to SPDY servers.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyVersion2" enum="SpdyProtocolVersion"
-    expires_after="2016-02-02">
-  <obsolete>
-    Removed on 2016-02-01, because the incorrect bucket count caused data
-    corruption. Replaced by Net.SpdyVersion3.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The SPDY protocol version that is used to talk to SPDY servers. Logged every
-    time a SPDY session is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Net.SpdyVersion3" enum="SpdyProtocolVersion"
-    expires_after="2016-07-14">
-  <obsolete>
-    Removed 2016 July with removal of SPDY/3.1.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    The SPDY protocol version that is used to talk to SPDY servers. Logged every
-    time a SPDY session is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_AuthRootConsistency" enum="SSLAuthRootConsistency"
-    expires_after="2018-01-23">
-  <obsolete>
-    Removed 2018-01 with the transition to a unified root list with OS fallback.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    The results of comparing the built-in list of known Windows roots against
-    the CERT_AUTH_ROOT_SHA256_HASH_PROP_ID certificate property. Recorded for
-    each certificate verification on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Error_FastRadioPadding"
-    enum="NetErrorCodes" expires_after="2015-07-21">
-  <obsolete>
-    Removed 7/21/2015. No longer tracked.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned when opening an SSL connection for
-    an endpoint which is eligible for fastradio padding.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Error_Google" enum="NetErrorCodes"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed 2018-03-07. No longer tracked.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    Counts of specific error codes returned when opening an SSL connection for
-    google.com and any subdomain of it.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency" units="ms"
-    expires_after="2014-10-22">
-  <obsolete>
-    Replaced by Net.SSL_Connection_Latency_2 on 2014-10-21.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>Time from when the Connect() starts until it completes.</summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_DataReductionProxy" units="ms"
-    expires_after="2014-09-22">
-  <obsolete>
-    Removed 7/21/2014. No longer tracked.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes when using the data
-    reduction proxy. This includes certificate retrieval and verification.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Full_Handshake" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-07-19. No longer tracked.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for full handshakes.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google" units="ms"
-    expires_after="2014-10-22">
-  <obsolete>
-    Replaced by Net.SSL_Connection_Latency_Google2 on 2014-10-21.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google2" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed 2018-03-07. No longer tracked.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google_Full_Handshake" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed 2018-03-07. No longer tracked.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it for full handshakes.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google_No_Revocation_Checking"
-    units="ms" expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2011.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it. This only includes users in a 50% field trial that
-    disables revocation checking for certificate pinned sites.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google_Resume_Handshake" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed 2018-03-07. No longer tracked.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it for resumption handshakes.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Google_Revocation_Checking"
-    units="ms" expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2011.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for google.com and
-    any subdomain of it. This only includes users not in a 50% field trail that
-    disables revocation for certificate pinned sites.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_PostQuantum" units="ms"
-    expires_after="M79">
-  <obsolete>
-    Experiment ended 2019-10-01.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes, but only for servers
-    that are part of the post-quantum experiment.
-  </summary>
-</histogram>
-
-<histogram
-    name="Net.SSL_Connection_Latency_PostQuantumSupported_Full_Handshake"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed as of 2016-12-01.
-  </obsolete>
-  <owner>mab@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes (full handshakes
-    only), for a set of domains that we expect to always offer the experimental
-    post-quantum (CECPQ1) ciphersuites.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_PQPadding" units="ms"
-    expires_after="2018-08-15">
-  <obsolete>
-    Removed as of 2018-07-06.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for any server that
-    echos a dummy post-quantum padding extension.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_Latency_Resume_Handshake" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-07-19. No longer tracked.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Time from when the Connect() starts until it completes for resumption
-    handshakes.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_Connection_PostQuantum_Negotiated"
-    enum="BooleanSupported" expires_after="2016-12-07">
-  <obsolete>
-    Removed as of 2016-12-01.
-  </obsolete>
-  <owner>mab@chromium.org</owner>
-  <summary>
-    For only browsers in the post-quantum (CECPQ1) ciphersuite experiment,
-    counts the full TLS handshakes where CECPQ1 was, or was not, negotiated on
-    hosts where we expect it to be negotiated.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_EVCertificateCTCompliance"
-    enum="CTRequirementCompliance" expires_after="2016-02-25">
-  <obsolete>
-    Removed as of 01/2016.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    The state of compliance with Certificate Transparency presence requirements
-    for each EV certificate. An EV certificate could be non-compliant (in which
-    case it loses the EV status), comply through inclusion in the EV whitelist
-    or have the required number of Signed Certificate Timestamps. This metric
-    will gauge adoption rate of Certificate Transparency and will help identify
-    when the EV whitelist is no longer needed. Emitted during every SSL
-    connection establishment, but only if the client is checking compliance with
-    Certificate Transparency requirements (currently guarded by a Finch
-    experiment).
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_EVCertificateInWhitelist" enum="Boolean"
-    expires_after="2017-06-14">
-  <obsolete>
-    Removed 06/2017 with the deprecation of the EV certificate whitelist after
-    all certificates expired.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether an EV certificate is present in the Certificate Transparency
-    whitelist. Emitted once for every EV certificate encountered (during SSL
-    connection establishment), but only if the client has a valid whitelist.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_EVCTCompliance" enum="EVCTCompliance"
-    expires_after="2017-06-14">
-  <obsolete>
-    Removed 06/2017 with the deprecation of distinct EV and !EV CT policies.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    The state of compliance with Certificate Transparency presence requirements
-    for each EV certificate. An EV certificate could be non-compliant (in which
-    case it loses the EV status), comply through inclusion in the EV whitelist
-    or comply with the CT certificate policy. This metric will gauge adoption
-    rate of Certificate Transparency and will help identify when the EV
-    whitelist is no longer needed. Emitted during every SSL connection
-    establishment.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_EVWhitelistValidityForNonCompliantCert"
-    enum="EVWhitelistStatus" expires_after="2017-06-14">
-  <obsolete>
-    Removed 06/2017 with the deprecation of the EV certificate whitelist after
-    all certificates expired.
-  </obsolete>
-  <owner>eranm@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <summary>
-    Whether the client holds a valid EV Certificates whitelist or not. Only
-    emitted when an EV cert that is not compliant with the Certificate
-    Transparency requirement is encountered. This histogram is intended to be
-    short-lived and help determine if EV certificates are considered
-    non-compliant because they are not whitelisted or if the client does not
-    hold a valid instance of the whitelist.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_KeyExchange.DHE" units="units"
-    expires_after="2016-09-20">
-  <obsolete>
-    Removed September 2016.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <owner>sigbjorn@opera.com</owner>
-  <summary>
-    Bit strength of the key exchange for DHE. Recorded for each SSL/TLS
-    connection in the socket pool where Connect() succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSL_KeyExchange.RSA" units="units"
-    expires_after="2016-06-02">
-  <obsolete>
-    Removed May 2016.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <owner>rsleevi@chromium.org</owner>
-  <owner>sigbjorn@opera.com</owner>
-  <summary>
-    Bit strength of the key exchange for RSA. Recorded for each SSL/TLS
-    connection in the socket pool where Connect() succeeds. See |SSL_SESSION|'s
-    key_exchange_info for more information.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLCertBlacklisted" units="units"
-    expires_after="2016-01-23">
-  <obsolete>
-    Removed on 01/2016. Only ever measured blacklisted Comodo serials, not any
-    of the other blacklisted certificates and keys.
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Counts the number of times that users have hit blacklisted certificates. The
-    indexes match up to the indexes in
-    net/base/x509_certificate.cc:IsBlacklisted. The details of the certificates
-    in question is confidential.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLDraftDowngradeTLS13Experiment" enum="BooleanDowngrade"
-    expires_after="2018-08-17">
-  <obsolete>
-    Removed in 08/2017.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each HTTPS connection to the TLS 1.3 experiment server set, whether the
-    TLS 1.3 anti-downgrade mechanism would have fired. This is to measure the
-    effects of non-compliant middleboxes on this otherwise safe security
-    feature. The numbers are only valid while the TLS 1.3 experiment set deploys
-    a TLS 1.3 draft version compatible with the corresponding Chrome version and
-    implement the our draft anti-downgrade signal. See
-    https://crbug.com/boringssl/226.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLFallbackErrorCode" enum="NetErrorCodes"
-    expires_after="2016-06-24">
-  <obsolete>
-    Removed June 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each successful HTTPS request which used the TLS version fallback, the
-    error code of the last failed attempt.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLFallbackFailureState" enum="SSLFailureState"
-    expires_after="2016-06-24">
-  <obsolete>
-    Removed June 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each successful HTTPS request which used the TLS version fallback, the
-    type of handshake failure of the last failed attempt.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLHostInfoDNSLookup" units="ms"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2011.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time to complete a DNS lookup for a DNS CAA record.</summary>
-</histogram>
-
-<histogram name="Net.SSLHostInfoDNSLookupDelayMs" units="ms"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2011.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time that we would have wasted had we waited for a CAA lookup in order to
-    validate a certificate.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLHostInfoVerificationTimeMs" units="ms"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time to complete a speculative certificate verification.</summary>
-</histogram>
-
-<histogram name="Net.SSLProtocolErrorCipher" enum="SSLCipherSuite"
-    expires_after="2016-03-18">
-  <obsolete>
-    Removed in March 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    The cipher suite used when the corresponding operation on an SSLClientSocket
-    fails with ERR_SSL_PROTOCOL_ERROR. This histogram will be removed when
-    https://crbug.com/593963 is resolved.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLProtocolErrorReason" enum="BoringSSLReasonCode"
-    expires_after="2016-03-18">
-  <obsolete>
-    Removed in March 2016.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    The internal, version-specific BoringSSL error reason reported when the
-    corresponding operation on an SSLClientSocket fails with
-    ERR_SSL_PROTOCOL_ERROR. This histogram will be removed when
-    https://crbug.com/593963 is resolved.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLProtocolNegotiation" enum="SSLProtocolNegotiation"
-    expires_after="2016-09-14">
-  <obsolete>
-    Superseded by Net.SSLNegotiatedAlpnProtocol in 2016 August.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    TLS extension used to negotiate protocol (ALPN or NPN); in case of NPN,
-    whether the protocol is indeed supported by both the client and the server
-    or is a fallback because of no overlap; and the negotiated protocol itself.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLRecordSizeRead" units="bytes"
-    expires_after="2018-01-24">
-  <obsolete>
-    Removed in January 2018.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    The number of bytes, excluding the record header, of each TLS record read.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLRSAKeyUsage.KnownRoot" enum="RSAKeyUsage"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each TLS connection which uses a known root, an RSA key, and TLS 1.2 or
-    below, what the result of checking the RSA key usage would have been.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLSecureRenegotiation" enum="BooleanSecure"
-    expires_after="M77">
-  <obsolete>
-    Removed in August 2019
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each attempted SSL renegotiation (non-initial handshake), whether the
-    server supported the renegotiation_info extension (RFC 5746).
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLServerKeyExchangeHash" enum="SSLHashAlgorithm"
-    expires_after="2016-07-07">
-  <obsolete>
-    Replaced by Net.SSLSignatureAlgorithm.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each SSL connection with a full handshake using a DHE- or ECDHE-based
-    key exchange, the hash function used in the ServerKeyExchange signature.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLSessionConcurrentLookupCount" units="units"
-    expires_after="2017-10-05">
-  <obsolete>
-    Removed on 2017-10-02.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    For each SSL connection where we resume a session and negotiate HTTP/2, the
-    simulated minimum number of sessions retained per host it would have
-    required with TLS 1.3 single-use sessions. See https://crbug.com/631988.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLSessionVersionMatch" enum="BooleanMatched"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed on 2015-11-10.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each SSL connection that resumed a session, whether the session was
-    resumed at the same version it was established at. This is only recorded in
-    BoringSSL ports.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13Downgrade" enum="BooleanDowngrade"
-    expires_after="2020-07-28">
-  <obsolete>
-    Removed 2020-07-28.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each HTTPS connection, whether the TLS 1.3 anti-downgrade mechanism
-    would have fired. This is only recorded if enforcement has been disabled and
-    includes samples from non-1.3 servers. See https://crbug.com/boringssl/226.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13DowngradeTLS13Experiment" enum="BooleanDowngrade"
-    expires_after="2020-07-28">
-  <obsolete>
-    Removed 2020-07-28.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each HTTPS connection to the TLS 1.3 experiment server set, whether the
-    TLS 1.3 anti-downgrade mechanism would have fired. This is only recorded if
-    enforcement has been disabled and is only valid while the TLS 1.3 experiment
-    set deploys the final TLS 1.3 version. See https://crbug.com/boringssl/226.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13DowngradeType" enum="TLS13DowngradeType"
-    expires_after="2020-07-28">
-  <obsolete>
-    Removed 2020-07-28.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each HTTPS connection that triggered the TLS 1.3 anti-downgrade
-    mechanism, the key exchange and whether the root was known.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13DowngradeTypeTLS13Experiment"
-    enum="TLS13DowngradeType" expires_after="2020-07-28">
-  <obsolete>
-    Removed 2020-07-28.
-  </obsolete>
-  <owner>svaldez@chromium.org</owner>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each HTTPS connection to the TLS 1.3 experiment server set that
-    triggered the TLS 1.3 anti-downgrade mechanism, the key exchange and whether
-    the root was known.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13SessionLifetime" units="ms"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed 2020-03.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>vasilvv@chromium.org</owner>
-  <summary>
-    For each session added to TLS session cache that uses TLS 1.3 or later, the
-    lifetime of the session. Note that this incorporates both the
-    server-supplied timeout and any local restrictions imposed by the client
-    itself.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLTLS13SessionTimeToUse" units="ms"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed 2020-03.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>vasilvv@chromium.org</owner>
-  <summary>
-    For each TLS 1.3 session successfully retrieved from the session cache, the
-    time between the session was added and the time it was retrieved.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLv3FallbackToRenegoPatchedServer"
-    enum="TLSRenegotiationPatched" expires_after="2014-08-25">
-  <obsolete>
-    Removed on 2014-08-20.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times that we have performed SSLv3 fallback and found a TLS
-    renegotiation patched server.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLVerificationMerged" units="units"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Was a speculative certificate verification used?</summary>
-</histogram>
-
-<histogram name="Net.SSLVerificationMergedMsSaved" units="ms"
-    expires_after="2015-11-11">
-  <obsolete>
-    Removed in 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time saved by a speculative certificate vertification.</summary>
-</histogram>
-
-<histogram name="Net.SSLVersionInterferenceDetails_TLS13Experiment"
-    enum="SSLVersionInterferenceDetails" expires_after="2018-04-06">
-  <obsolete>
-    Removed April 2018.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    For each detected SSL version interference against a server in the initial
-    TLS 1.3 deployment, details on how the initial connection failed.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLVersionInterferenceError" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each detected SSL version interference, what network error the original
-    failed connection reported.
-  </summary>
-</histogram>
-
-<histogram name="Net.SSLVersionInterferenceProbeTrigger" enum="NetErrorCodes"
-    expires_after="M77">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    For each SSL version interference probe, what network error triggered it.
-    Probes are only triggered for a small set of network errors.
-  </summary>
-</histogram>
-
-<histogram name="Net.SuccessfulResolutionWithValidDNSName" enum="Boolean"
-    expires_after="2017-07-20">
-  <obsolete>
-    Removed in 07/2017.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    True if a DNS name contains only characters for which
-    |net::IsValidLabelCharacter| returns true. Used to see if we can deprecate
-    and remove support for arbitrary bytes in DNS names. This histogram is
-    recorded after DNS resolution has completed successfully.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCP_Connection_Idle_Sockets" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Number of idle sockets when the Connect() succeeded.</summary>
-</histogram>
-
-<histogram name="Net.TcpFastOpenSocketConnection" enum="TcpSocketStatus"
-    expires_after="2019-02-13">
-  <obsolete>
-    Removed 02/2019, as fast open support has been removed.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    For sockets for which a TCP Fast Open protocol might be used, the result of
-    trying to use it.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCPForSOCKSSocketIdleTimeBeforeNextUse_ReusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete>
-    see SocketIdleTimeBeforeNextUse_ReusedSocket_TCPforSOCKS
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an already used TCP socket sat idle before being used for a SOCKS
-    request.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCPForSOCKSSocketIdleTimeBeforeNextUse_UnusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete>
-    see SocketIdleTimeBeforeNextUse_UnusedSocket_TCPforSOCKS
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an unused TCP socket sat idle before being used for a SOCKS
-    request.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCPForSOCKSSocketRequestTime" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    see SocketRequestTime_TCPforSOCKS
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from initial SOCKSClientSocketPool::RequestSocket() call until
-    successfully acquiring a connected TCP socket.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCPForSOCKSSocketType" enum="HttpSocketType"
-    expires_after="2013-04-09">
-  <obsolete>
-    see SocketType_TCPforSOCKS
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The counts of the type of sockets returned by the TCP pool used by the SOCKS
-    pool.
-  </summary>
-</histogram>
-
-<histogram name="Net.TCPSocketType" enum="HttpSocketType"
-    expires_after="2013-04-09">
-  <obsolete>
-    Was only used for HTTP[S] connections, renamed to Net.HTTPSocketType.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The counts of the type of TCP socket returned.</summary>
-</histogram>
-
-<histogram name="Net.ThreadHopResourceThrottleTime" units="ms"
-    expires_after="2016-08-26">
-  <obsolete>
-    Experiment complete, code removed.
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <summary>
-    The time it took to do an IO to UI round-trip in the
-    ThreadHopResourceThrottle. This is part of an experiment to determine the
-    feasibility to moving some high-level resource loading checks to the UI
-    thread.
-  </summary>
-</histogram>
-
-<histogram name="Net.TokenBinding.HeaderCreationTime" units="ms"
-    expires_after="2019-03-14">
-  <obsolete>
-    Token Binding was removed in Q4 2018 and this histogram was removed in
-    3/2019.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>Time spent creating a Token-Binding header.</summary>
-</histogram>
-
-<histogram name="Net.TokenBinding.KeyMatch" enum="TokenBinding.KeyMatch"
-    expires_after="2019-03-14">
-  <obsolete>
-    Token Binding was removed in Q4 2018 and this histogram was removed in
-    3/2019.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    Logs on each request that is sent on a connection where Channel ID was sent
-    whether the key that would be used for Token Binding matches the key used
-    for Channel ID.
-  </summary>
-</histogram>
-
-<histogram name="Net.TokenBinding.StoreEphemerality"
-    enum="TokenBinding.StoreEphemerality" expires_after="2019-03-14">
-  <obsolete>
-    Token Binding was removed in Q4 2018 and this histogram was removed in
-    3/2019.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    For each request to accounts.google.com on a connection where Channel ID was
-    sent, this logs whether the Cookie store and the Channel ID store were
-    ephemeral or persistent.
-  </summary>
-</histogram>
-
-<histogram name="Net.TokenBinding.Support" enum="TokenBinding.Support"
-    expires_after="2019-03-14">
-  <obsolete>
-    Token Binding was removed in Q4 2018 and this histogram was removed in
-    3/2019.
-  </obsolete>
-  <owner>nharper@chromium.org</owner>
-  <summary>
-    The number of secure HTTP requests broken down by support for Token Binding,
-    indicating if Token Binding was negotiated and supported by both client and
-    server, or why it wasn't if not.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Bandwidth" units="KB/s"
-    expires_after="2014-11-01">
-  <obsolete>
-    Discontinued as of 4/12/09
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Effective bandwidth in KByte/Second of transactions logged to
-    Transaction_Latency histogram. Note that only samples durations greater than
-    zero ms, and less than 1 hour are tallied into this ratio.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Connected" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the when the network transaction is requested, until the first
-    byte of the header is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Connected_New" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Connected_New_b.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When a new connection is established, the time from the when the network
-    transaction is requested, until the first byte of the header is received.
-    Only items under 10 minutes are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Connected_New_b" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When a new connection is established, the time from the when the network
-    transaction is requested, until the first byte of the header is received.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Connected_Under_10" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Connected.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from the when the network transaction is requested, until the first
-    byte of the header is received. Only items under 10 minutes are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency" units="ms" expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Latency_b.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from first byte sent until last byte received by the new network stack.
-    Only items under 1 hour are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_b" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from first byte sent until last byte received by the new network stack.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_Total" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a network transaction is requested until last byte received
-    by the new network stack.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_Total_New_Connection" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed as of 11/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When an existing TCP/IP connection is NOT reused, the time from when a
-    network transaction is requested until last byte received by the new network
-    stack.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_Total_New_Connection_Under_10"
-    units="ms" expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Latency_Total_New_Connection.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When an existing TCP/IP connection is NOT reused, the time from when a
-    network transaction is requested until last byte received by the new network
-    stack. Only items under 10 minutes are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_Total_Under_10" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Latency_Total.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a network transaction is requested until last byte received
-    by the new network stack. Only items under 10 minutes are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_Under_10" units="ms"
-    expires_after="2013-04-09">
-  <obsolete>
-    Replaced by Net.Transaction_Latency.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from first byte sent until last byte received by the new network stack.
-    Only items under 10 minutes are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.Transaction_Latency_WinHTTP" units="ms"
-    expires_after="2014-11-01">
-  <obsolete>
-    Removed a long time ago.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from first byte sent until last byte received with old WinHTTP network
-    stack. Only items under 1 hour are logged.
-  </summary>
-</histogram>
-
-<histogram name="Net.TransportSocketIdleTimeBeforeNextUse_ReusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete/>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an already used TCP socket sat idle before being used (either for
-    direct or non-socks use).
-  </summary>
-</histogram>
-
-<histogram name="Net.TransportSocketIdleTimeBeforeNextUse_UnusedSocket"
-    units="units" expires_after="2013-04-09">
-  <obsolete/>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time an unused TCP socket sat idle before being used (either for direct
-    or non-socks use).
-  </summary>
-</histogram>
-
-<histogram name="Net.TransportSocketRequestTime" units="ms"
-    expires_after="2013-04-09">
-  <obsolete/>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from initial ClientSocketPool::RequestSocket() call until successfully
-    acquiring a connected socket (either for direct or non-socks use).
-  </summary>
-</histogram>
-
-<histogram name="Net.TransportSocketType" enum="HttpSocketType"
-    expires_after="2013-04-09">
-  <obsolete/>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The counts of the type of sockets returned by the TCP pool (either for
-    direct or non-socks use).
-  </summary>
-</histogram>
-
-<histogram name="Net.UdpSocketBindErrorFromPosix" units="PosixError"
-    expires_after="2017-10-18">
-  <obsolete>
-    Removed as of 10/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Posix error code from call to bind() UDP socket.</summary>
-</histogram>
-
-<histogram name="Net.UdpSocketBindErrorFromWinOS" units="WinError"
-    expires_after="2017-10-18">
-  <obsolete>
-    Removed as of 10/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Windows error code from call to bind() UDP socket.</summary>
-</histogram>
-
-<histogram name="Net.URLRequest_SetReferrer_IsEmptyOrValid" enum="Boolean"
-    expires_after="2014-06-25">
-  <obsolete>
-    Removed 6/23/2014. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>True if a URLRequest's referrer is empty or valid when set.</summary>
-</histogram>
-
-<histogram name="Net.URLRequestContext.OutstandingRequests" units="count"
-    expires_after="2018-01-02">
-  <obsolete>
-    Removed 1/1/2018. No longer tracked.
-  </obsolete>
-  <summary>
-    Indicates the number of URLRequests that are handed out by a
-    URLRequestContext and are not yet destroyed.
-  </summary>
-</histogram>
-
-<histogram name="Net.URLRequestContext.OutstandingRequests.Type"
-    enum="URLRequestAnnotationType" expires_after="2018-01-02">
-  <obsolete>
-    Removed 1/1/2018. No longer tracked.
-  </obsolete>
-  <summary>
-    Records the annotation type of the URLRequest that is handed out by a
-    URLRequestContext when Net.URLRequestContext.OutstandingRequests is
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="Net.ValidDNSName" enum="Boolean" expires_after="2017-07-19">
-  <obsolete>
-    Removed 07/2017, not necessary to determine deprecation for invalid DNS
-    names.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    True if a DNS name contains only characters for which
-    |net::IsValidLabelCharacter| returns true. Used to see if we can deprecate
-    and remove support for arbitrary bytes in DNS names. This histogram is
-    recorded when converting dotted DNS names into DNS query form, in
-    preparation for issuing a DNS request.
-  </summary>
-</histogram>
-
-<histogram name="Net.WebSocket.DataUse.Downstream" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Removed in March 2020.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the downstream data use of WebSockets. Logged on every read
-    operation in the WebSocket.
-  </summary>
-</histogram>
-
-<histogram name="Net.WebSocket.DataUse.Upstream" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Removed in March 2020.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the upstream data use of WebSockets. Logged on every write operation
-    in the WebSocket.
-  </summary>
-</histogram>
-
-<histogram name="Net.WebSocket.DeflateMode"
-    enum="WebSocketNewPerMessageDeflateContextTakeoverMode" expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count the number of WebSockets that accepted permessage-deflate extension
-    for each context take over mode. Used by the new Chromium-based WebSocket
-    implementation.
-  </summary>
-</histogram>
-
-<histogram name="Net.WebSocket.Duration" units="ms" expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    The time from a WebSocket is successfully opened until it's closed. Used to
-    study how WebSockets are used.
-  </summary>
-</histogram>
-
-<histogram name="Net.WebSocket.HandshakeResult"
-    enum="WebSocketNewHandshakeResult" expires_after="2018-03-13">
-  <obsolete>
-    Removed 03/2018, replaced by Net.WebSocket.HandshakeResult2.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Results of WebSocket handshakes. Use this histogram as a baseline for
-    investigating feature usage counters.
-  </summary>
-</histogram>
-
-<histogram name="Net.Wifi.InterfaceCount" units="units"
-    expires_after="2020-02-01">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>deviceapi-team@google.com</owner>
-  <summary>
-    The number of Wi-fi adapters on the computer. Because the histogram is
-    logged each time Chrome performs a Wi-fi scan, it's better to see results in
-    the &quot;user count&quot; view.
-  </summary>
-</histogram>
-
-<histogram name="Net.Wifi.LbsLatency" units="ms" expires_after="2020-02-01">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>deviceapi-team@google.com</owner>
-  <summary>The time that a request to Location Based Services takes.</summary>
-</histogram>
-
-<histogram name="Net.Wifi.ScanLatency" units="ms" expires_after="2020-02-01">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>deviceapi-team@google.com</owner>
-  <summary>The time that a Wi-fi scan takes.</summary>
-</histogram>
-
-<histogram name="Net.WpadQuickCheckFailure" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 02/2019.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Duration of time that a failing WPAD QuickCheck takes. WPAD QuickCheck does
-    a name lookup for &quot;wpad&quot; and times out quickly to fail fast when
-    there's no WPAD server on the network.
-  </summary>
-</histogram>
-
-<histogram name="Net.WpadQuickCheckSuccess" units="ms"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 02/2019.
-  </obsolete>
-  <owner>eroman@chromium.org</owner>
-  <summary>
-    Duration of time that a successful WPAD QuickCheck takes. WPAD QuickCheck
-    does a name lookup for &quot;wpad&quot; and times out quickly to fail fast
-    when there's no WPAD server on the network.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.0.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the first pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.0.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the first pipeline connectivity response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.0.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the first pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.1.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the second pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.1.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the second pipeline connectivity
-    response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.1.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the second pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.2.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the third pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.2.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the third pipeline connectivity response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.2.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the third pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.3.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the fourth pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.3.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the fourth pipeline connectivity
-    response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.3.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the fourth pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.4.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the fifth pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.4.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the fifth pipeline connectivity response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.4.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the fifth pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.5.NetworkError" enum="NetErrorCodes"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The network error, if any, of the stats pipeline connectivity request.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.5.ResponseCode" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The HTTP response code, if any, of the stats pipeline connectivity response.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.5.Status" enum="HttpPipelineStatus"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The result of the stats pipeline connectivity request.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.AllHTTP11" enum="BooleanSuccess"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    True if all requests received by the pipelining test server were HTTP/1.1.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.CanarySuccess" enum="BooleanSuccess"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    True if the non-pipelined canary request sent immediately before the
-    pipelining test requests succeeded. Note that if this fails, the rest of the
-    NetConnectivity.Pipeline.* stats are not collected.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.Depth" units="units"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The maximum depth of pipelined requests received by the test server.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Pipeline.Success" enum="BooleanSuccess"
-    expires_after="2014-05-27">
-  <obsolete>
-    Removed 05/2014, related field trial already long expired.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>True if the entire pipeline connectivity trial passed.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.Sent21" units="units"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 6/25/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP at port 6121 as
-    rapidly as possible, just after successfully sending an UMA upload. Each
-    packet was numbered, as was its ACK sent back by Google. If no packets (of
-    the 21) were ever ACKed, then the port is assumed to be blocked, and no data
-    is recorded in this histogram. If the port is not blocked, then this
-    histogram shows the number of echo responses received from the first
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Sent21.AckReceivedForNthPacket" units="units"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 6/25/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP at port 6121 as
-    rapidly as possible, just after successfully sending an UMA upload. Each
-    packet was numbered, as was its ACK sent back by Google. This histogram
-    records, for each packet number, how often we received an ACK for that
-    packet.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.Sent21.GotAnAck" enum="BooleanSuccess"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 6/25/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP at port 6121 as
-    rapidly as possible, just after successfully sending an UMA upload. If no
-    packets (of the 21) were ever ACKed, then the port is assumed to be blocked.
-    The histogram shows if we ever got an ACK for a packet in our series of 21.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Fail.100B.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 100 bytes of TCP data unsuccessfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Fail.1k.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 1K bytes of TCP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Status"
-    enum="NetConnectivityProtocolStatus" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for TCP protocol for echoing</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Status.100B" enum="NetConnectivityStatus"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for echoing 100 bytes of TCP data.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Status.1K" enum="NetConnectivityStatus"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for echoing 1K bytes of TCP data.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Success" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for TCP protocol for echoing</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Success.100B.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 100 bytes of TCP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.TCP.Success.1K.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 1K bytes of TCP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Fail.100B.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 100 bytes of UDP data unsuccessfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Fail.1k.RTT" units="ms"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 1K bytes of UDP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.PacketLoss" units="units"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 6/25/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome sends 4 UDP packets in a row to test to see if there is a
-    probabalistic dependency in packet loss for consecutive packets. We record a
-    bit vector of packets received, where the least significant bit is a 1 if
-    the first packet was received, etc. For example, if packets 1 and 3 are
-    received, but packets 2 and 4 are lost, then we'd record a sample of binary
-    0101B, or 5.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.PacketLoss6" units="units"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 6/25/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome sends 6 UDP packets in a row to test to see if there is a
-    probabalistic dependency in packet loss for consecutive packets. We record a
-    bit vector of packets received, where the least significant bit is a 1 if
-    the first packet was received, etc. For example, if all packets other than
-    packet 2 and 4 are responded to, then we'd have a sample (in binary) of
-    110101B, or 53.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Status"
-    enum="NetConnectivityProtocolStatus" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for UDP protocol for echoing</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Status.100B" enum="NetConnectivityStatus"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for echoing 100 bytes of UDP data.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Status.1K" enum="NetConnectivityStatus"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Status for echoing 1K bytes of UDP data.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Success" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for UDP protocol for echoing</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Success.100B.RTT" units="ms"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 100 bytes of UDP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity.UDP.Success.1K.RTT" units="ms"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 4/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The RTT for echoing 1k bytes of UDP data successfully.</summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Send6.PacketsSent" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This histogram records how many packets (out of 6 attempted) were sent via
-    UDP as rapidly as possible, just after successfully sending an UMA upload.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Send6.SeriesAcked" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome sends 6 UDP packets in a row to test to see if there is a
-    probabalistic dependency in packet loss for consecutive packets. We record a
-    bit vector of packets received, where the least significant bit is a 1 if
-    the first packet was received, etc. For example, if all packets other than
-    packet 2 and 4 are responded to, then we'd have a sample (in binary) of
-    110101B, or 53.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Sent21" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP as rapidly as
-    possible, just after successfully sending an UMA upload. Each packet was
-    numbered, as was its ACK sent back by Google. If no packets (of the 21) were
-    ever ACKed, then the port is assumed to be blocked, and no data is recorded
-    in this histogram. If the port is not blocked, then this histogram shows the
-    number of echo responses received from the first
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Sent21.AckReceivedForNthPacket" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP as rapidly as
-    possible, just after successfully sending an UMA upload. Each packet was
-    numbered, as was its ACK sent back by Google. This histogram records, for
-    each packet number, how often we received an ACK for that packet.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Sent21.GotAnAck" enum="BooleanSuccess"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP as rapidly as
-    possible, just after successfully sending an UMA upload. If no packets (of
-    the 21) were ever ACKed, then the port is assumed to be blocked. The
-    histogram shows if we ever got an ACK for a packet in our series of 21.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity2.Sent21.PacketsSent" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This histogram records how many packets (out of 21 attempted) were sent via
-    UDP as rapidly as possible, just after successfully sending an UMA upload.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity3" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, 21 packets were sent to Google via UDP on port 443 or
-    6121.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.443.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.443.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.443.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.6121.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.6121.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.6121.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.GotAnAck"
-    enum="BooleanSuccess" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.NonPacedPacket.Sent21.Success.RTT" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.443.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.443.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.443.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.6121.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.6121.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.6121.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.GotAnAck"
-    enum="BooleanSuccess" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.PacedPacket.Sent21.Success.RTT" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Send6.PacketsSent" units="units"
-    expires_after="2013-04-26">
-  <obsolete>
-    Removed 9/2012. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This histogram records how many packets (out of 6 attempted) were sent via
-    UDP as rapidly as possible, just after successfully sending an UMA upload.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.443.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.443.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.443.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.6121.100B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.6121.1200B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.6121.500B.PacketDelay"
-    units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.GotAnAck"
-    enum="BooleanSuccess" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity3.StartPacket.Sent21.Success.RTT" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="NetConnectivity4" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, a few packets were sent from Google to clients via UDP
-    on port 443 or 80 to perform net connectivity test.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity5" units="units" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    In this experiment, a few packets were sent from Google to clients via UDP
-    on port 443 or 80 to perform net connectivity test.
-  </summary>
-</histogram>
-
-<histogram name="NetConnectivity5.TestFailed.WritePending"
-    enum="BooleanSuccess" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Next NetConnectivity5 experiment weren't started because there is an
-    outstading pending write.
-  </summary>
-</histogram>
-
-<histogram name="Network.Cellular.TimeOnline" units="seconds"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network metric sampling the time spent using Cellular to transport
-    data. These data are mostly useful when summed and compared to TimeOnline
-    for other network technologies (e.g. WiFi vs Cellular).
-  </summary>
-</histogram>
-
-<histogram name="Network.Cellular.TimeToConfig" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join a 3G/Cellular
-    network and configure Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Cellular.TimeToOnline" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that a
-    3G/Cellular network is online after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Cellular.TimeToPortal" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that a
-    3G/Cellular network is in a captive portal after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Cellular.UsageRequestStatus"
-    enum="NetworkCellularUsageRequestStatus" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Chrome OS cellular usage API request status codes.</summary>
-</histogram>
-
-<histogram name="Network.Ethernet.TimeOnline" units="seconds"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network metric sampling the time spent using Ethernet to transport
-    data. These data are mostly useful when summed and compared to TimeOnline
-    for other network technologies (e.g. WiFi vs Cellular).
-  </summary>
-</histogram>
-
-<histogram name="Network.Ethernet.TimeToConfig" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join a wired
-    Ethernet network and configure Layer 3 state (typically acquire a DHCP
-    lease).
-  </summary>
-</histogram>
-
-<histogram name="Network.Ethernet.TimeToOnline" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that an
-    Ethernet network is online after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Ethernet.TimeToPortal" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that an
-    Ethernet network is in a captive portal after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.MigrationNssToPem"
-    enum="MigrationNssToPemNetworkTypes" expires_after="2015-08-11">
-  <obsolete>
-    Removed 8/2015.
-  </obsolete>
-  <owner>cschuet@chromium.org</owner>
-  <summary>
-    Chrome OS metric counting the number of network configurations that
-    contained a NSS nickname identifying a CA certificate, which triggered the
-    migration to PEM encoding. This metric doesn't consider whether the
-    migration was successful but once a migration was successful the nickname is
-    removed.
-  </summary>
-</histogram>
-
-<histogram name="Network.ServiceErrors" enum="NetworkServiceError"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Chrome OS connection manager service errors seen.</summary>
-</histogram>
-
-<histogram name="Network.Shill.Cellular.DHCPOptionFailureDetected"
-    enum="NetworkDHCPOptionFailure" expires_after="2014-05-17">
-  <obsolete>
-    Removed 5/2014, and replaced by Network.Shill.DHCPOptionFailureDetected.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network metric that tracks the number of DHCP option failures
-    encountered by Shill. This indicates that Shill is using minimal DHCP
-    options due to suspected MTU issues on the return path from the DHCP server
-    back to the client.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Cellular.ExpiredLeaseLengthSeconds"
-    units="seconds" expires_after="2017-10-11">
-  <obsolete>
-    Removed since Chrome OS build 10010.0.0 and superceded by
-    Network.Shill.Cellular.ExpiredLeaseLengthSeconds2 due to change in number of
-    buckets (crosreview.com/557297, crosreview.com/703679).
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric that tracks the length of a lease for a
-    cellular network at the time it expired without the DHCP client being able
-    to renew it.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.DarkResumeActionTime" units="ms"
-    expires_after="2015-01-27">
-  <obsolete>
-    Removed 01/2015. Migrated to Network.Shill.DarkResumeActionsTimeTaken.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes dark resume actions to complete when shill suspends.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Ethernet.DHCPOptionFailureDetected"
-    enum="NetworkDHCPOptionFailure" expires_after="2014-05-17">
-  <obsolete>
-    Removed 5/2014, and replaced by Network.Shill.DHCPOptionFailureDetected.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network metric that tracks the number of DHCP option failures
-    encountered by Shill. This indicates that Shill is using minimal DHCP
-    options due to suspected MTU issues on the return path from the DHCP server
-    back to the client.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Ethernet.ExpiredLeaseLengthSeconds"
-    units="seconds" expires_after="2017-10-11">
-  <obsolete>
-    Removed since Chrome OS build 10010.0.0 and superceded by
-    Network.Shill.Ethernet.ExpiredLeaseLengthSeconds2 due to change in number of
-    buckets (crosreview.com/557297, crosreview.com/703679).
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric that tracks the length of a lease for
-    an Ethernet network at the time it expired without the DHCP client being
-    able to renew it.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.SandboxingEnabled" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>mortonm@chromium.org</owner>
-  <summary>
-    Chrome OS metric signifying whether a system is running shill in a sandbox
-    or not. This is controlled through a VariationsService flag, but requires
-    1-2 reboots to take affect. This metric will help us ensure that shill is
-    being run with sandboxing enabled/disabled at the proportion that we expect.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.SuspendActionsTimeTaken" units="ms"
-    expires_after="2021-12-01">
-  <obsolete>
-    Removed 03/2020. Migrated to Network.Shill.SuspendActionTimeTaken.
-  </obsolete>
-  <owner>briannorris@chromium.org</owner>
-  <owner>cros-network-metrics@google.com</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes suspend actions to complete when shill suspends. Note that this was a
-    misspelling of the metric that is really in use by Shill. No histogram
-    should ever have included this entry.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.SuspendActionTime" units="ms"
-    expires_after="2015-01-27">
-  <obsolete>
-    Removed 01/2015. Migrated to Network.Shill.SuspendActionsTimeTaken.
-  </obsolete>
-  <owner>briannorris@chromium.org</owner>
-  <owner>cros-network-metrics@google.com</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes suspend actions to complete when shill suspends.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.TerminationActionResult.OnSuspend"
-    enum="ShillSuspendTerminationDarkResumeActionResult"
-    expires_after="2014-11-11">
-  <obsolete>
-    Removed 10/2014. Migrated to Network.Shill.SuspendActionResult.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the number of termination
-    actions that successfully complete or fail when shill suspends.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.TerminationActionResult.OnTerminate"
-    enum="ShillSuspendTerminationDarkResumeActionResult"
-    expires_after="2014-11-11">
-  <obsolete>
-    Removed 10/2014. Migrated to Network.Shill.TerminationActionResult.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the number of termination
-    actions that successfully complete or fail when shill terminates.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.TerminationActionTime" units="ms"
-    expires_after="2015-01-27">
-  <obsolete>
-    Removed 01/2015. Migrated to Network.Shill.TerminationActionsTimeTaken.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes termination actions to complete when shill terminates.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.TerminationActionTime.OnSuspend" units="ms"
-    expires_after="2014-11-11">
-  <obsolete>
-    Removed 10/2014. Migrated to Network.Shill.SuspendActionTime.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes termination actions to complete when shill suspends.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.TerminationActionTime.OnTerminate" units="ms"
-    expires_after="2014-11-11">
-  <obsolete>
-    Removed 10/2014. Migrated to Network.Shill.TerminationActionTime.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network diagnostic metric sampling the time in milliseconds it
-    takes termination actions to complete when shill terminates.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wifi.ApMode" enum="WiFiApMode"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 05/2019.
-  </obsolete>
-  <owner>kirtika@chromium.org</owner>
-  <summary>
-    Chrome OS network usage metric. The AP mode setting for each successful WiFi
-    connection.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wifi.DHCPOptionFailureDetected"
-    enum="NetworkDHCPOptionFailure" expires_after="2014-05-17">
-  <obsolete>
-    Removed 5/2014, and replaced by Network.Shill.DHCPOptionFailureDetected.
-  </obsolete>
-  <owner>kirtika@chromium.org</owner>
-  <summary>
-    Chrome OS network metric that tracks the number of DHCP option failures
-    encountered by Shill. This indicates that Shill is using minimal DHCP
-    options due to suspected MTU issues on the return path from the DHCP server
-    back to the client.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wifi.ExpiredLeaseLengthSeconds" units="seconds"
-    expires_after="2017-10-11">
-  <obsolete>
-    Removed since Chrome OS build 10010.0.0 and superceded by
-    Network.Shill.Wifi.ExpiredLeaseLengthSeconds2 due to change in number of
-    buckets (crosreview.com/557297, crosreview.com/703679).
-  </obsolete>
-  <owner>kirtika@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric that tracks the length of a lease for a
-    WiFi network at the time it expired without the DHCP client being able to
-    renew it.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.WiFi.FrequenciesConnectedEver" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>briannorris@chromium.org</owner>
-  <owner>cros-network-metrics@google.com</owner>
-  <summary>
-    Chrome OS metric sampling the number of different frequencies (i.e.
-    channels) on which a device has connected to a WiFi network. This value is
-    recorded every time a WiFi connection is established
-    (WPASupplicant::kInterfaceStateCompleted). Note that the word
-    &quot;Ever&quot; in the metric name is misleading. Chrome OS actually ages
-    out historical information, currently after 3 weeks.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.DevicePresenceStatus"
-    enum="BooleanPresent" expires_after="M77">
-  <obsolete>
-    Wimax support has been dropped from shill since M76.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network metric that tracks the presence of a WiMax device in the
-    system. A sample is emitted once every 3 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.DHCPOptionFailureDetected"
-    enum="NetworkDHCPOptionFailure" expires_after="2014-05-17">
-  <obsolete>
-    Removed 5/2014, and replaced by Network.Shill.DHCPOptionFailureDetected.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network metric that tracks the number of DHCP option failures
-    encountered by Shill. This indicates that Shill is using minimal DHCP
-    options due to suspected MTU issues on the return path from the DHCP server
-    back to the client.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.ExpiredLeaseLengthSeconds" units="seconds"
-    expires_after="2017-10-11">
-  <obsolete>
-    Removed since Chrome OS build 10010.0.0 and superceded by
-    Network.Shill.Wimax.ExpiredLeaseLengthSeconds2 due to change in number of
-    buckets (crosreview.com/557297, crosreview.com/703679).
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric that tracks the length of a lease for a
-    WiMax network at the time it expired without the DHCP client being able to
-    renew it.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.ExpiredLeaseLengthSeconds2"
-    units="seconds" expires_after="M80">
-  <obsolete>
-    Wimax support has been dropped from shill since M76.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric that tracks the length of a lease for a
-    WiMax network at the time it expired without the DHCP client being able to
-    renew it.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.TimeToConfig" units="ms"
-    expires_after="2019-12-31">
-  <obsolete>
-    Wimax support has been dropped from shill since M76.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to configure Layer 3
-    state on a WiMax network (typically acquire a DHCP lease).
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.TimeToInitialize" units="ms"
-    expires_after="2019-12-31">
-  <obsolete>
-    Wimax support has been dropped from shill since M76.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to initialize a WiMax
-    device.
-  </summary>
-</histogram>
-
-<histogram name="Network.Shill.Wimax.TimeToOnline" units="ms"
-    expires_after="2019-12-31">
-  <obsolete>
-    Wimax support has been dropped from shill since M76.
-  </obsolete>
-  <owner>benchan@chromium.org</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that a
-    WiMax network is online after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.TimeToConfig.Cellular" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join a 3G/Cellular
-    network and configure Layer 3 state. Note this metric is deprecated; see
-    Network.Cellular.TimeToConfig.
-  </summary>
-</histogram>
-
-<histogram name="Network.TimeToConfig.Ethernet" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join a wired
-    Ethernet network and configure Layer 3 state (typically acquire a DHCP
-    lease). Note this metric is deprecated; see Network.Ethernet.TimeToConfig.
-  </summary>
-</histogram>
-
-<histogram name="Network.TimeToConfig.Wifi" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to configure Layer 3
-    state on an 802.11 wireless network (typically acquire a DHCP lease). Note
-    this metric is deprecated; see Network.Wifi.TimeToConfig.
-  </summary>
-</histogram>
-
-<histogram name="Network.TimeToDrop" units="seconds" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network stability metric sampling the time in seconds between the
-    networking going online to going offline. Offline events due to device
-    shutdown or suspend are ignored (along with the online time before that
-    offline event).
-  </summary>
-</histogram>
-
-<histogram name="Network.TimeToJoin.Wifi" units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join (associate
-    plus authenticate) an 802.11 wireless network. Note this metric is
-    deprecated; see Network.Wifi.TimeToJoin.
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.AuthMode" enum="NetworkAuthModeType"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to configure Layer 3
-    state on an 802.11 wireless network (typically acquire a DHCP lease).
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.BitRate" units="bps" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Network metric reporting the download speed test results run at setup time.
-    Recorded at least once per day.
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeOnline" units="seconds"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network metric sampling the time spent using WiFi to transport
-    data. These data are mostly useful when summed and compared to TimeOnline
-    for other network technologies (e.g. WiFi vs Cellular).
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeResumeToReady" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time from the resume event
-    to the time when an 802.11 wireless network has configured its Layer 3
-    state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeToConfig" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to configure Layer 3
-    state on an 802.11 wireless network (typically acquire a DHCP lease).
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeToJoin" units="ms" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to join (associate
-    plus authenticate) an 802.11 wireless network.
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeToOnline" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that an
-    802.11 wireless network is online after configuring Layer 3 state.
-  </summary>
-</histogram>
-
-<histogram name="Network.Wifi.TimeToPortal" units="ms"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Chrome OS network performance metric sampling the time to determine that an
-    802.11 wireless network is in a captive portal after configuring Layer 3
-    state.
-  </summary>
-</histogram>
-
-<histogram name="NetworkTimeTracker.UpdateTimeFetchAttempted" units="units"
-    expires_after="2016-08-15">
-  <obsolete>
-    Removed 08/2016 because it does not provide additional information beyond
-    NetworkTimeTracker.UpdateTimeFetchFailed and
-    NetworkTimeTracker.UpdateTimeFetchValid.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>mab@chromium.org</owner>
-  <summary>
-    NetworkTimeTracker makes periodic queries to obtain a secure timestamp over
-    the network. This histogram increments whenever such a query is attempted.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ActionAndroid" enum="NewTabPageActionAndroid"
-    expires_after="2017-01-10">
-  <obsolete>
-    Removed as of 01/2017. Replaced by NewTabPage.ActionAndroid2.
-  </obsolete>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    Actions taken by users from the new tab page on Android. These actions may
-    navigate away from the NTP (e.g. searching in the omnibox or opening a
-    bookmark), but can also happen without navigating away from the NTP (e.g.
-    opening a bookmark in a new tab).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.AnimatedLogoDownloadTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019. No longer used.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The amount of time it takes to download the animated logo. Android only.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.BackgroundService.Albums.RequestLatency" units="ms"
-    expires_after="2019-03-01">
-  <obsolete>
-    Removed 02/2019 with the removal of the associated service integration.
-  </obsolete>
-  <owner>ramyan@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    The time it took until a request from the New Tab Page for Google Photos
-    albums was served.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.BackgroundService.Photos.RequestLatency" units="ms"
-    expires_after="2019-03-01">
-  <obsolete>
-    Removed 02/2019 with the removal of the associated service integration.
-  </obsolete>
-  <owner>ramyan@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    The time it took until a request from the New Tab Page for Google Photos (in
-    a specific album) was served.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.BookmarkActionAndroid"
-    enum="NewTabPageBookmarkActionAndroid" expires_after="2014-04-30">
-  <obsolete>
-    Removed on M33 with the change to native NTP.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Actions taken by users on partner bookmarks (editing / renaming) on the NTP
-    on Android.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.ArticleFaviconFetchResult"
-    enum="FaviconFetchResult" expires_after="M77">
-  <obsolete>
-    Not used anymore. Removed in April 2020.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: Result of fetching a favicon for an article suggestion on the New
-    Tab Page.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.ArticleFaviconFetchTime"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Not used anymore. Removed in April 2020.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: Time it takes to fetch a favicon for an article suggestion on the
-    New Tab Page.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.BreakingNews.MessageReceived"
-    enum="ContentSuggestionsBreakingNewsMessageContainsNews"
-    expires_after="2017-10-25">
-  <obsolete>
-    Removed in October 2017 (M64) and replaced by
-    NewTabPage.ContentSuggestions.BreakingNews.ReceivedMessageAction, when
-    adding support for push-to-refresh messages.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: Number of received messages and whether they contain pushed news. A
-    message contains pushed news if the payload key exists in the message. The
-    payload content is not checked at all (e.g. it may be empty). Recorded when
-    a message is received.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.ReceivedMessageAction"
-    enum="ContentSuggestionsBreakingNewsMessageAction" expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Android: Action of a received message. An action can be either push-by-value
-    or push-to-refresh. A message with a missing or invalid action is recorded
-    as well. Recorded when a message is received.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.SubscriptionRequestStatus"
-    enum="ContentSuggestionsStatusCode" expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: The result of a subscription request for breaking news at the
-    content suggestions server. Recorded when a request finishes. Analogous to
-    NewTabPage.ContentSuggestions.BreakingNews.UnsubscriptionRequestStatus.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.TimeSinceLastTokenValidation"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: Time between a token validation and the last successful token
-    retrieval from InstanceID. Recorded when InstanceID answers our token
-    request for a validation either with a token or an error. If the token was
-    never received before the validation, the metric is not recorded.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.TokenRetrievalResult"
-    enum="InstanceIDResult" expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: The result of our inquiry to InstanceID to receive the current
-    token. Recorded when InstanceID replies to our inquiry for a token
-    (including for a validation).
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.UnsubscriptionRequestStatus"
-    enum="ContentSuggestionsStatusCode" expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: The result of an unsubscription request for breaking news at the
-    content suggestions server. Recorded when a request finishes. Analogous to
-    NewTabPage.ContentSuggestions.BreakingNews.SubscriptionRequestStatus.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.BreakingNews.WasTokenValidBeforeValidation"
-    enum="ContentSuggestionsBreakingNewsTokenValidationOutcome"
-    expires_after="M80">
-  <obsolete>
-    Removed 04/2019. Breaking News feature removed.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: Whether a token validation detected an invalid token. This is
-    recorded only for validations where no error occured and the token was
-    actually retrieved.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.CountOnNtpOpened" units="units"
-    expires_after="2017-07-07">
-  <obsolete>
-    Removed in July 2017. This metric was replaced by CountOnNtpOpenedIfVisible.
-    Initially the metric was not recorded properly if any category was not
-    visible. This was fixed in https://codereview.chromium.org/2874213002/,
-    however, not visible categories still were polluting the metric (they were
-    recorded as showing 0 suggestions).
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Android: The number of suggestion cards that were available at the time an
-    NTP was opened.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible.Articles.Prefetched.Offline"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed in October 2017 (M63) and replaced by
-    CountOnNtpOpenedIfVisible.Articles.Prefetched.Offline2, because
-    underreported. UI checked whether a URL is prefetched asynchronously. As a
-    result, there was a race condition and this metric could be reported before
-    all URLs are checked.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: The number of prefetched suggestion cards that were available in
-    Articles category if it was visible at the time an NTP was opened and the
-    user was offline. Analogous to
-    NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.MenuOpenedScore" units="score"
-    expires_after="2017-01-18">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.MenuOpenedScoreNormalized.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Android: The relevance score of a suggestion card on the NTP whose
-    long-press menu was opened, analogous to
-    NewTabPage.ContentSuggestions.OpenedScore.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.OpenedScore" units="score"
-    expires_after="2017-01-18">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.OpenedScoreNormalized.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Android: The score of a suggestion card on the NTP that is clicked through
-    to the host website of the content. The recorded score is from the moment
-    the suggestion was fetched, it could have changed since.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.Shown.Articles.Prefetched.Offline"
-    units="index" expires_after="M80">
-  <obsolete>
-    Removed in October 2017 (M63) and replaced by
-    Shown.Articles.Prefetched.Offline2, because underreported. UI checked
-    whether a URL is prefetched asynchronously. As a result, there was a race
-    condition and for suggestions immediately visible on the suggestions surface
-    this metric could be reported before their URLs are actually checked.
-  </obsolete>
-  <owner>vitaliii@chromium.org</owner>
-  <summary>
-    Android: The position of a prefetched suggestion card that was shown on the
-    NTP when offline. Analogous to NewTabPage.ContentSuggestions.Shown. That is
-    a card is considered shown when at least 2/3 of its height is visible on the
-    screen. For each card, at most one impression is recorded per NTP instance.
-    We track the position the card had in the list when it was first seen by the
-    user. This tracked position can be different from the position observed by
-    the user, e.g. when the user dismissed some suggestions from the list or
-    requested more that got inserted in the middle of the feed.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.ShownScore" units="score"
-    expires_after="2017-01-18">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.ShownScoreNormalized.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Android: The score of a suggestion card that was shown on the NTP. A card is
-    considered shown when at least 2/3 of its height is visible on the screen.
-    For each card, at most one impression is recorded per NTP instance.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.TimeSinceLastBackgroundFetch"
-    units="ms" expires_after="2017-02-23">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.TimeSinceSuggestionFetched.
-  </obsolete>
-  <owner>markusheintz@chromium.org</owner>
-  <summary>
-    Android: The time since the last successful background fetch of remote
-    content suggestions. Recorded when the user looks at content suggestions on
-    the NTP.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger" units="ms"
-    expires_after="2017-07-10">
-  <obsolete>
-    Removed as of July 2017, in favor of
-    NewTabPage.ContentSuggestions.TimeUntilFirstShownTrigger and
-    NewTabPage.ContentSuggestions.TimeUntilFirstStartupTrigger.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The time since the last fetch, recorded upon the first soft fetch
-    trigger. The first soft trigger does not necessarily cause a fetch (if it
-    comes before the end of the respective scheduling interval). This metric is
-    recorded at most once after each fetch (and additionaly at most once after
-    each startup of Chrome before the next fetch). This is used to understand
-    how changing scheduling intervals will impact traffic of background fetches.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.UIUpdateResult"
-    enum="ContentSuggestionsUIUpdateResult" expires_after="2017-01-21">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.UIUpdateResult2 in January 2017.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The result of updating the list of content suggestions in the UI.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ContentSuggestions.UIUpdateResult2"
-    enum="ContentSuggestionsUIUpdateResult2" expires_after="M77">
-  <obsolete>
-    Not used anymore. Removed in April 2020.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The result of updating the list of content suggestions in one UI
-    section.
-  </summary>
-</histogram>
-
-<histogram
-    name="NewTabPage.ContentSuggestions.UIUpdateSuccessNumberOfSuggestionsSeen"
-    units="suggestions" expires_after="M78">
-  <obsolete>
-    Not used anymore. Removed in April 2020.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The number of content suggestions that have been seen by the user
-    in the UI section before the section was successfully updated. The seen
-    suggestions were not removed in the update so that we do not change visible
-    parts of the UI. This histogram is only recorded when the UIUpdateResult2 is
-    &quot;Success (some suggestions replaced)&quot;.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.CustomizationAvailability.Backgrounds"
-    enum="NTPBackgroundCustomizationAvailability" expires_after="M90">
-  <obsolete>
-    Removed 2019-08.
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    The availability of New Tab Page background customization features on
-    Desktop, based on feature flags or other configuration settings; logged per
-    NTP load.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.CustomizationAvailability.Shortcuts"
-    enum="NTPShortcutCustomizationAvailability" expires_after="M90">
-  <obsolete>
-    Removed 2019-08.
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <summary>
-    The availability of New Tab Page shortcut customization features on Desktop,
-    based on feature flags or other configuration settings; logged per NTP load.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.DefaultPageType" enum="NtpPaneType"
-    expires_after="2016-02-22">
-  <obsolete>
-    Removed 2016-02.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The default pane when the NTP is first opened.</summary>
-</histogram>
-
-<histogram name="NewTabPage.ExploreOffline.Action"
-    enum="NewTabPage.ExploreOffline.Action" expires_after="2020-08-01">
-  <obsolete>
-    Deprecated as of 08/2020.
-  </obsolete>
-  <owner>shaktisahu@chromium.org</owner>
-  <owner>clank-downloads@google.com</owner>
-  <summary>
-    Android: Records user actions on the explore offline card on the NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Feed.ImageFetchResult" enum="FeedImageFetchResult"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Image.FetchResult.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: Represents success/failure of Feed image loading. Recorded upon
-    each individual image retrieved from the feed_image_cache.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Feed.ImageLoadFromCacheTime" units="ms"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Image.LoadFromCacheTime.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The time it takes for Feed to load an image from the cache.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Feed.ImageLoadFromNetworkTime" units="ms"
-    expires_after="2018-10-17">
-  <obsolete>
-    Removed in favor of ContentSuggestions.Feed.Image.LoadFromNetworkTime.
-  </obsolete>
-  <owner>wylieb@chromium.org</owner>
-  <summary>
-    Android: The time it takes for Feed to load an image from the network.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.HoverTimeClicked" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram of the time, in milliseconds, users have the cursor over a most
-    visited thumbnail before clicking.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.HoverTimeNotClicked" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram of the time, in milliseconds, users have the cursor over a most
-    visited thumbnail before moving it away from the thumbnail without clicking.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.IconsColor" units="units"
-    expires_after="2017-04-03">
-  <obsolete>
-    Removed 2017-04, replaced by NewTabPage.TileType and
-    NewTabPage.SuggestionsImpression.IconsColor.
-  </obsolete>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    The number of most visited tiles on the new tab page that are displayed
-    using a fallback color (as opposed to having an icon, or simply being gray).
-    Android only.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.IconsGray" units="units" expires_after="2017-04-03">
-  <obsolete>
-    Removed 2017-04, replaced by NewTabPage.TileType and
-    NewTabPage.SuggestionsImpression.IconsGray.
-  </obsolete>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    The number of most visited tiles on the new tab page that are displayed as
-    gray (as opposed to having an icon, or a fallback color). Android only.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.IconsReal" units="units" expires_after="2017-04-03">
-  <obsolete>
-    Removed 2017-04, replaced by NewTabPage.TileType and
-    NewTabPage.SuggestionsImpression.IconsReal.
-  </obsolete>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    The number of most visited tiles on the new tab page that are displayed with
-    the site's icon (as opposed using a fallback color or just gray). Android
-    only.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Interests.ImageDownloadSuccess"
-    enum="BooleanSuccess" expires_after="2017-05-13">
-  <obsolete>
-    Removed 2017-05 (and not recorded for some time before that).
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: Whether an attempt to download the image for an interest was
-    successful.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Interests.InterestsFetchSuccess"
-    enum="BooleanSuccess" expires_after="2017-05-13">
-  <obsolete>
-    Removed 2017-05 (and not recorded for some time before that).
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: Whether an attempt to fetch the interests for a user was
-    successful.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Interests.NumInterests" units="interests"
-    expires_after="2017-05-13">
-  <obsolete>
-    Removed 2017-05 (and not recorded for some time before that).
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The number of interests fetched for a user to display on the NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Layout" enum="NTPLayout" expires_after="2018-05-10">
-  <obsolete>
-    Removed 2018-04 with full launch of NTP condensed layout.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Android: A histogram detailing how the NewTabPageLayout is laid out on the
-    device (eg, whether it fits fully above the fold or not). This is logged
-    once per NewTabPageLayout creation (so once per NTP).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.LoadType" enum="NTPLoadType" expires_after="M85">
-  <obsolete>
-    Removed 2020-06 because it was no longer being monitored.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    Android: the type of load for the NTP, such as cold or warm start. It's a
-    warm start if the native library is already loaded and initialized at the
-    time the activity is created. This might happen if for example a service was
-    already running.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.LogoShownTime" units="ms"
-    expires_after="2017-08-31">
-  <obsolete>
-    Removed 2017-08 because it was only recorded for cached logos. Replaced by
-    LogoShownTime2.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The amount of time between opening an NTP and the logo appearing. Only
-    recorded when there is a logo, and only recorded once per NTP. Android only.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.MobilePromo" enum="NewTabPageMobilePromo"
-    expires_after="2014-04-30">
-  <obsolete>
-    Removed on M33 with the change to native NTP.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Android: Tallies counts for how the user interacted with the NTP promo page.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.MostVisitedAction" enum="NtpFollowAction"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    Action taken by the user on the Most Visited NTP pane. If the user switches
-    panes during this use of the NTP, this action is sometimes not recorded. Ask
-    mpearson@ for details.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.MostVisitedScheme" enum="NtpMostVisitedScheme"
-    expires_after="2016-05-23">
-  <obsolete>
-    Removed 2016-05.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The schemes of URLs of most visited thumbnails that the user clicked on.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.MostVisitedTilePlacementExperiment"
-    enum="NtpTileExperimentActions" expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <owner>newt@chromium.org</owner>
-  <summary>
-    Records anomalous events for the Most Visited Tile Placement experiment,
-    where it is unable to operate as expected. These are recorded during New Tab
-    Page load time, once for every NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NonVisibleScreenshots" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of screenshots that were cached for the non-visible but ranked
-    suggestions on the Suggested NTP pane.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NonVisibleSuggestedSiteRank" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Given that the user has typed a URL, and given that that specific URL was
-    ranked but not visible on the Suggested pane of the NTP, this is the rank
-    that the Suggested pane had for that URL.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfExternalTileFallbacks" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of tiles for which we relied on external tiles as a fallback
-    because a local screenshot was not available to be used as a thumbnail.
-    External tiles are those for which the visuals are handled by the page
-    itself, not by the iframe. Recorded before reloading the suggestions,
-    navigating to a URL, switching tabs, changing the active window, or closing
-    the tab/shutting down Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfExternalTiles" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of external tiles that are displayed on the NTP. External tiles
-    are those for which the visuals are handled by the page itself, not by the
-    iframe. Recorded before reloading the suggestions, navigating to a URL,
-    switching tabs, changing the active window or closing the tab/shutting down
-    Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfGrayTileFallbacks" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of tiles for which we displayed a gray tile with the domain name
-    as a fallback because a local screenshot was not available to be used as a
-    thumbnail. Recorded before reloading the suggestions, navigating to a URL,
-    switching tabs, changing the active window or closing the tab/shutting down
-    Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfGrayTiles" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of tiles for which no thumbnail was specified, but a domain was
-    so we displayed a gray tile with the domain name in it. Recorded before
-    reloading the suggestions, navigating to a URL, switching tabs, changing the
-    active window or closing the tab/shutting down Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfMouseOvers" units="units"
-    expires_after="2016-07-08">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The total number of times the user hovered the mouse over Most Visited tile
-    or title elements before changing focus away from the NTP, be it by
-    navigating to a URL, switching tabs, changing the active window or closing
-    the tab/shutting down Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfThumbnailAttempts" units="units"
-    expires_after="2014-01-17">
-  <obsolete>
-    Removed 01/2014. Replaced by NewTabPage.NumberOfThumbnailTiles.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of tiles for which we attempted to use a local screenshot as a
-    thumbnail. Recorded before reloading the suggestions, navigating to a URL,
-    switching tabs, changing the active window or closing the tab/shutting down
-    Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfThumbnailErrors" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of thumbnails for which a local screenshot was not available so
-    we were not able to display them on the Most Visited section of the NTP.
-    Recorded before reloading the suggestions, navigating to a URL, switching
-    tabs, changing the active window or closing the tab/shutting down Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.NumberOfThumbnailTiles" units="units"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    The number of tiles for which we attempted to use a local screenshot as a
-    thumbnail. Recorded before reloading the suggestions, navigating to a URL,
-    switching tabs, changing the active window or closing the tab/shutting down
-    Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.OfflineUrlsLoadTime" units="ms" expires_after="M58">
-  <obsolete>
-    Removed in M58.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <summary>
-    The amount of time spent waiting for the offline page model to return which
-    New Tab Page URLs are available offline.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.OtherSessionsMenu" enum="OtherSessionsActions"
-    expires_after="2015-05-18">
-  <obsolete>
-    Removed 05/2015. Feature was removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram for usage of the menu on the NTP that allows the user to access
-    tabs from other devices.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.PreviousSelectedPageType" enum="NtpPaneType"
-    expires_after="2016-02-22">
-  <obsolete>
-    Removed 2016-02.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The pane that had been previously selected when the user switches panes in
-    the NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Promo.Bubble" enum="NtpPromoAction"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Histogram for NTP bubble promo activity.</summary>
-</histogram>
-
-<histogram name="NewTabPage.Promo.Notification" enum="NtpPromoAction"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Histogram for NTP notification promo activity.</summary>
-</histogram>
-
-<histogram name="NewTabPage.Promos.RequestLatency" units="ms"
-    expires_after="M76">
-  <obsolete>
-    Removed 2018-03 as it doesn't correctly capture all request states.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    The time it took until a request from the New Tab page for the middle slot
-    promo script was served. Recorded only on the local NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.RecentTabsPage.TimeVisibleAndroid" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Removed March 2020.
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Records the amount of time that the &quot;Recent Tabs&quot; page is visible
-    and Chrome is in the foreground on Android. The metric is recorded whenever
-    the &quot;Recent Tabs&quot; page moves out of the foreground. The metric is
-    recorded when the &quot;Recent Tabs&quot; page is closed, when the user
-    switches from the &quot;Recent Tabs&quot; page to a different tab and when
-    Chrome is backgrounded.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SearchAvailableLoadTime.ColdStart" units="ms"
-    expires_after="2017-02-06">
-  <obsolete>
-    Removed February 2017.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The time until the search box became available on the NTP in a cold start.
-    It's a cold start if the native library is not already loaded and
-    initialized at the time the activity is created. Only measured on Android.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SearchAvailableLoadTime.WarmStart" units="ms"
-    expires_after="2017-02-06">
-  <obsolete>
-    Removed February 2017.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The time until the search box became available on the NTP in a warm start.
-    It's a warm start if the native library is already loaded and initialized at
-    the time the activity is created. This might happen if for example a service
-    was already running. Only measured on Android.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SearchSuggestions.RequestLatency" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-03 as it doesn't correctly capture all request states.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    The time it took until a request from the New Tab page for the search
-    suggestions script was served. Recorded only on the local NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SearchSuggestions.RequestStatus"
-    enum="NTPSearchSuggestionsRequestStatus" expires_after="M76">
-  <obsolete>
-    Removed 2019-03 as it grouped together requests that returned no suggestions
-    with those that failed completely, which is misleading.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    Whether a request was made for search suggestions on NTP load; and if a
-    request was not made, the reason why.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SearchURLs.Total" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD.</summary>
-</histogram>
-
-<histogram name="NewTabPage.SelectedPageType" enum="NtpPaneType"
-    expires_after="2016-02-22">
-  <obsolete>
-    Removed 2016-02.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The pane selected when the user switches panes in the NTP.</summary>
-</histogram>
-
-<histogram name="NewTabPage.SessionRestore" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram for user clicks of the Recently Closed items. The value is the
-    recency of the entry being restored (0 is most recent).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SingleSessionPageSwitches" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram to track how many times a user switched pages in a single NTP
-    session.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardClicked" units="units"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.Opened.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The position of the snippets card on the NTP, that is clicked
-    through to the host website of the content. We track the position the
-    snippet had in the list when NTP was loaded. This tracked position is thus
-    different from the position observed by the user whenever before scrolling
-    down to the given snippet, the user discards some snippets in the top of the
-    list.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardClickedAge" units="ms"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.OpenedAge.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The age of the snippets card on the NTP, that is clicked through to
-    the host website of the content. The age is measured from the moment the
-    content has been published. In each &quot;_x_y&quot; suffix of the
-    histogram, only snippets on positions \gt;=x and \lt;=y are tracked. We
-    track the position the snippet had in the list when NTP was loaded. This
-    tracked position is thus different from the position observed by the user
-    whenever before scrolling down to the given snippet, the user discards some
-    snippets in the top of the list.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardClickedScore" units="score"
-    expires_after="2016-10-27">
-  <obsolete>
-    Removed as of 6/2016
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The score of the snippets card on the NTP, that is clicked through
-    to the host website of the content. The recorded score is from the moment
-    the snippet was fetched, it could have changed since. In each &quot;_x&quot;
-    suffix of the histogram, only snippets on positions \lt;=x are tracked. We
-    track the position the snippet had in the list when NTP was loaded. This
-    tracked position is thus different from the position observed by the user
-    whenever before scrolling down to the given snippet, the user discards some
-    snippets in the top of the list.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardClickedScoreNew" units="score"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.OpenedScore.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The score of the snippets card on the NTP, that is clicked through
-    to the host website of the content. The recorded score is from the moment
-    the snippet was fetched, it could have changed since. In each &quot;_x&quot;
-    suffix of the histogram, only snippets on positions \lt;=x are tracked. We
-    track the position the snippet had in the list when NTP was loaded. This
-    tracked position is thus different from the position observed by the user
-    whenever before scrolling down to the given snippet, the user discards some
-    snippets in the top of the list. In contrast to CardClickedScore, this
-    histogram has a proper maximal value of 100 000.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardExpanded" units="units"
-    expires_after="2016-10-27">
-  <obsolete>
-    Removed as of 4/2016
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The position of the snippets card on the NTP, that is expanded to
-    reveal more content.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardHidden" units="units"
-    expires_after="2016-10-27">
-  <obsolete>
-    Removed as of 4/2016
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The position of the snippets card on the NTP, for which the
-    expanded content was minimized/hidden.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardLongPressed" units="index"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.MenuOpened.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Android: The position of a snippet card when it is long pressed, analagous
-    to NewTabPage.Snippets.CardClicked.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardLongPressedAge" units="ms"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.MenuOpenedAge.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Android: The time difference between when a snippet card is long pressed and
-    when its content was published. Analagous to
-    NewTabPage.Snippets.CardClickedAge.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardLongPressedScoreNew" units="score"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.MenuOpenedScore.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Android: The relevance score of an interest card that is long pressed,
-    analagous to NewTabPage.Snippets.CardClickedScoreNew.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardShown" units="units"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.Shown.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: The position of the snippets card that is shown on the NTP. Each
-    snippet (its position) is recorded whenever at least 2/3 of its height
-    becomes visible by scrolling through the NTP. Each snippet is recorded at
-    most once for a given instance of NTP and a given data set of snippets that
-    is shown. We track the position the snippet had in the list when NTP was
-    loaded. This tracked position is thus different from the position observed
-    by the user whenever before scrolling down to the given snippet, the user
-    discards some snippets in the top of the list. Previously (in the code
-    before 2016/05/27), this histogram was recorded each time a snippet became
-    visible (e.g. by scrolling up and down) at least by 1px; the first snippet
-    was thus recorded even without scrolling down.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardShownAge" units="ms"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.ShownAge.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The age of the snippets card that is shown on the NTP. Each snippet
-    (its age) is recorded whenever at least 2/3 of its height becomes visible by
-    scrolling through the NTP. Each snippet is recorded at most once for a given
-    instance of NTP and a given data set of snippets that is shown. The age is
-    measured from the moment the content has been published. In each
-    &quot;_x_y&quot; suffix of the histogram, only snippets on positions \gt;=x
-    and \lt;=y are tracked. By this, we mean the position the snippet had in the
-    list when NTP was loaded. This tracked position is thus different from the
-    position observed by the user whenever before scrolling down to the given
-    snippet, the user discards some snippets in the top of the list.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardShownScore" units="score"
-    expires_after="2016-10-27">
-  <obsolete>
-    Removed as of 6/2016
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The score of the snippets card that is shown on the NTP. Each
-    snippet (its score) is recorded whenever at least 2/3 of its height becomes
-    visible by scrolling through the NTP. Each snippet is recorded at most once
-    for a given instance of NTP and a given data set of snippets that is shown.
-    The recorded score is from the moment the snippet was fetched, it could have
-    changed since. In each &quot;_x&quot; suffix of the histogram, only snippets
-    on positions \lt;=x are tracked. By this, we mean the position the snippet
-    had in the list when NTP was loaded. This tracked position is thus different
-    from the position observed by the user whenever before scrolling down to the
-    given snippet, the user discards some snippets in the top of the list.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.CardShownScoreNew" units="score"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.ShownScore.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Android: The score of the snippets card that is shown on the NTP. Each
-    snippet (its score) is recorded whenever at least 2/3 of its height becomes
-    visible by scrolling through the NTP. Each snippet is recorded at most once
-    for a given instance of NTP and a given data set of snippets that is shown.
-    The recorded score is from the moment the snippet was fetched, it could have
-    changed since. In each &quot;_x&quot; suffix of the histogram, only snippets
-    on positions \lt;=x are tracked. By this, we mean the position the snippet
-    had in the list when NTP was loaded. This tracked position is thus different
-    from the position observed by the user whenever before scrolling down to the
-    given snippet, the user discards some snippets in the top of the list. In
-    contrast to CardShownScore, this histogram has a proper maximal value of 100
-    000.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.Interactions" enum="SnippetsInteractions"
-    expires_after="2016-10-27">
-  <obsolete>
-    Removed 2016-10.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Android: A histogram giving an overall summary of important events like
-    impressions, scroll events, clicks etc.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.NumArticlesOnScrolledBelowTheFoldOnce"
-    units="articles" expires_after="2016-10-27">
-  <obsolete>
-    Removed 2016-10.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Android: The number of snippet articles available to the user in the UI,
-    logged when the user scrolls below the fold (at max once per NTP load).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.OpenMethod" enum="SnippetOpenMethod"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.OpenDisposition.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <summary>
-    Android: A histogram detailing how the articles linked from snippets are
-    opened (eg, plain click, open in new tab, open in incognito).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.Snippets.VisitDuration" units="ms"
-    expires_after="2016-10-27">
-  <obsolete>
-    Replaced by NewTabPage.ContentSuggestions.VisitDuration.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Android: Time spent reading the page linked by an opened (clicked) snippet
-    card. Exit conditions include the tab not being in the foreground or
-    starting a new navigation.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SuggestedSite" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Histogram for user clicks of the suggested site thumbnails. The value is
-    equal to the index of the thumbnail.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.SuggestedSitesAction" enum="NtpFollowAction"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Action taken by the user on the Suggested Sites NTP pane.</summary>
-</histogram>
-
-<histogram name="NewTabPage.SuggestedSitesLoadTime" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time to load the Suggested Sites NTP pane, in milliseconds.</summary>
-</histogram>
-
-<histogram name="NewTabPage.SuggestedSitesViewTime" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time spent on the Suggested Sites NTP pane, in seconds.</summary>
-</histogram>
-
-<histogram name="NewTabPage.SuggestionsType" enum="NtpSuggestionsType"
-    expires_after="2016-07-11">
-  <obsolete>
-    Removed 2016-07.
-  </obsolete>
-  <summary>
-    Indicate, for each impression of the New Tab Page, whether the suggestions
-    were obtained from the client or server. Recorded before changing focus away
-    from the NTP, be it by navigating to a URL, switching tabs, changing the
-    active window or closing the tab/shutting down Chrome.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ThumbnailErrorRate" units="units"
-    expires_after="2014-01-17">
-  <obsolete>
-    Removed 01/2014. Replaced by NewTabPage.NumberOfThumbnailAttempts and
-    NewTabPage.NumberOfThumbnailErrors.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The percentage of errors per attempts to load image thumbnails on the New
-    Tab Page. When an error occurs, a grey tile is shown instead of a thumbnail
-    image. We measure the rate instead of the number of errors because multiple
-    attempts are made to load images at different times during the NTP's
-    lifetime. Each NTP session's error rate is logged after the user navigates
-    to a new URL from that NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.ThumbnailFallbackRate" units="%"
-    expires_after="2014-01-17">
-  <obsolete>
-    Removed 01/2014. Replaced by NewTabPage.NumberOfGrayTileFallbacks and
-    NewTabPage.NumberOfExternalFallbacks.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The percentage of times most visited tiles use the fallback thumbnail. Only
-    requests that actually specify a fallback thumbnail are considered here. We
-    measure the rate instead of the number of errors because multiple attempts
-    are made to load thumbnails at different times during the NTP's lifetime.
-    Each NTP session's error rate is logged after the user navigates to a new
-    URL from that NTP.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.TileFaviconFetchStatus.Server"
-    enum="GoogleFaviconServerRequestStatus" expires_after="M77">
-  <obsolete>
-    Removed 07/2019 because the histogram was unused and close to expiration.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Mobile only. The result of fetching a favicon for a tile on the New Tab
-    Page. This is recorded for each gray MostVisited tile on the New Tab Page
-    once per impression of the tile.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.TileFaviconFetchSuccess.Popular"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed 07/2019 because the histogram was unused and close to expiration.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Mobile only. The result of fetching a favicon for a tile on the New Tab
-    Page. This is recorded for each gray PopularSites tile on the New Tab Page
-    once per updating the set of tiles (notably upon each NTP impression).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.TileFaviconFetchSuccess.Server"
-    enum="BooleanSuccess" expires_after="2017-07-10">
-  <obsolete>
-    Removed 06/2017. Replaced by NewTabPage.TileFaviconFetchStatus.Server.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Mobile only. The result of fetching a favicon for a tile on the New Tab
-    Page. This is recorded for each gray MostVisited tile on the New Tab Page
-    once per lifetime of Chrome (there as an in-memory cache of failed
-    requests).
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.TilesReceivedTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 06/2019. No longer used.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Histogram of the time, in milliseconds since navigation start, it took for
-    the NTP most visited iframe to receive the data for all of its tiles. This
-    does not include actually loading the DOM elements for the tiles, in
-    particular the thumbnail images; see NewTabPage.LoadTime for that.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.TimeToFirstDraw" units="ms"
-    expires_after="2019-01-22">
-  <obsolete>
-    Removed 01/2019, replaced by NewTabPage.TimeToFirstDraw2 when a bug in how
-    this was calculated was fixed.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The time from when a new tab page is created until the first pre-draw call
-    on the main UI containing the search provider logo (if available), fake
-    search box, most visited tiles, etc. More specifically, this is the time
-    between NewTabPage's constructor and the first pre-draw pass on
-    NewTabPageLayout.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.VisibleScreenshots" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of screenshots that were cached for the visible suggestions on
-    the Suggested NTP pane.
-  </summary>
-</histogram>
-
-<histogram name="NewTabPage.VisibleSuggestedSiteRank" units="units"
-    expires_after="2016-02-19">
-  <obsolete>
-    Removed 2016-02 (and not recorded for some time before that).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Given that the user has typed a URL, and given that that specific URL was
-    visible on the Suggested pane of the NTP, this is the rank that the
-    Suggested pane had for that URL.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.AuthorDataSizeKB" units="KB"
-    expires_after="2016-02-22">
-  <obsolete>
-    Replaced by Notifications.AuthorDataSize in February 2016.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The size, in kilobytes, of the author-provided data associated with a Web
-    Notification. Recorded when a persistent Web Notification is being shown by
-    the developer.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.DifferentRequestingEmbeddingOrigins"
-    enum="Boolean" expires_after="2015-07-02">
-  <obsolete>
-    Removed July 2015. No longer tracked since M42.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Records if the requesting and embedding origins are different when
-    requesting permission to display Web Notifications.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Display" enum="NotifierType"
-    expires_after="2017-10-31">
-  <obsolete>
-    Removed October 2017 (fullscreen notifications feature enabled by default).
-  </obsolete>
-  <owner>bmalcolm@chromium.org</owner>
-  <summary>
-    Counts the number of times a notification was shown for the various types of
-    sources. The suffix distinguishes between the window state of the app or
-    webpage that sent the notification. This will be used to determine whether a
-    legacy mode is required when we allow apps or webpages to display
-    notifications over fullscreen content in the future.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.ExtensionNotificationActionCount"
-    units="buttons" expires_after="M86">
-  <obsolete>
-    Removed in July 2020 as the metrics are not needed anymore, and
-    documentation has been amended as a result of this collection.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of action buttons the developer provided for a notification
-    created using the extensions notification API. Logged when creating the
-    notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.ExtensionNotificationIdLength"
-    units="characters" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 because this was measuring risk for a feature that has
-    now been implemented and shipped.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The length, in characters, of the id given to an extension notification.
-    These can be automatically generated, in which case they will be either 36
-    bytes (GUID) or 16 bytes (random data) in length, or provided by the
-    developer. Measured when the notification is being displayed through the
-    chrome.notifications.create() extension API.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.ExtensionNotificationType"
-    enum="ExtensionNotificationType" expires_after="M86">
-  <obsolete>
-    Removed in July 2020 as the metrics are not needed anymore as platforms have
-    moved to native notifications, for which these metrics were used.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The type of a notification created using the extensions notification API.
-    Logged when creating the notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.HeaderClick"
-    enum="NotificationHeaderClickAction" expires_after="M80">
-  <obsolete>
-    Removed Nov 2019 because the histogram data was not being used.
-  </obsolete>
-  <owner>knollr@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Whether a click on a notification header caused it to collapse, expand or
-    had no effect at all. Logged when clicking on the notification header.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Icon.FileSize" units="bytes"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed Nov 2016 in favor of Notifications.LoadFileSize.*
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>The number of bytes loaded for a Web Notification icon.</summary>
-</histogram>
-
-<histogram name="Notifications.Icon.LoadFailTime" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed Nov 2016 in favor of Notifications.LoadFailTime.*
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to fail loading an icon for a Web
-    Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Icon.LoadFinishTime" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed Nov 2016 in favor of Notifications.LoadFinishTime.*
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to finish successfully loading an icon
-    for a Web Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Icon.ScaleDownTime" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed Nov 2016 in favor of Notifications.LoadScaleDownTime.*
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to scale down an icon for a Web
-    Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.LoadFailTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="NotificationImageTypes" -->
-
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to fail loading an icon/image for a Web
-    Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.LoadFileSize" units="bytes" expires_after="M80">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="NotificationImageTypes" -->
-
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of bytes loaded for a Web Notification icon/image.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.LoadFinishTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="NotificationImageTypes" -->
-
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to finish successfully loading an
-    icon/image for a Web Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.LoadScaleDownTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="NotificationImageTypes" -->
-
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The number of milliseconds it took to scale down an icon/image for a Web
-    Notification.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.NotificationHelper.NotificationActivatorStatus"
-    enum="NotificationHelperNotificationActivatorStatus"
-    expires_after="2018-06-02">
-  <obsolete>
-    Removed 06/2018. Replaced by NotificationActivatorPrimaryStatus and
-    NotificationActivatorSecondaryStatus.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    The execute status of NotificationActivator::Activate. Logged whenever a
-    notification_helper process is launched by Windows.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.PersistentNotificationDataDeleted"
-    enum="BooleanSuccess" expires_after="2016-02-05">
-  <obsolete>
-    Removed 01/2016, no longer used.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>deepak.m1@samsung.com</owner>
-  <summary>
-    Recorded when the data associated with a persistent Web Notification gets
-    deleted. The value will be true if data deletion succeeded, and false if
-    there was an error.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.ImageRetainerDestructionTime" units="ms"
-    expires_after="2018-10-23">
-  <obsolete>
-    Obsolete 10/2018 as we no long record this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>finnur@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Amount of time taken to destroy a NotificationImageRetainer object when the
-    image directory is valid.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.ImageRetainerInitializationTime"
-    units="ms" expires_after="2018-10-23">
-  <obsolete>
-    Obsolete 10/2018 as we no long record this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>finnur@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Amount of time taken to initialize the image retainer directory.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.OnDismissedStatus"
-    enum="WindowsNotificationOnDismissedStatus" expires_after="2020-06-23">
-  <obsolete>
-    Obsolete 06/2020 as we no long record this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The status of OnDismissed requests in NotificationPlatformBridgeWin (Windows
-    only). Logged whenever a dismiss event is handled.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.SetReadyCallbackStatus"
-    enum="WindowsNotificationSetReadyCallbackStatus" expires_after="2018-06-01">
-  <obsolete>
-    Replaced with Notifications.Windows.SetReadyCallbackStatus2 which is not
-    skewed.
-  </obsolete>
-  <owner>finnur@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The status of SetReadyCallback requests in NotificationPlatformBridgeWin
-    (Windows only). Logged once at startup.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.StartMenuShortStatus"
-    enum="WindowsNotificationStartMenuShortStatus" expires_after="2018-06-11">
-  <obsolete>
-    Removed 06/2018. Replaced with Notifications.Windows.StartMenuShortcutStatus
-    where typo is fixed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>finnur@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Used to indicate the status of start menu shortcut (Windows only). Logged
-    whenever a notification display attempt is made.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.ToastActivatorCLSIDMismatchReason"
-    enum="WindowsToastActivatorCLSIDMismatchReason" expires_after="2018-12-30">
-  <obsolete>
-    Removed 12/2018 as this is no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>finnur@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Used to indicate the reason why toast activator CLSID in shortcut is
-    different from the one retrieved from the installer (Windows only). Logged
-    whenever this mismatch is detected during a notification display attempt.
-  </summary>
-</histogram>
-
-<histogram name="Notifications.Windows.UserManagerShowupStatus"
-    enum="WindowsNotificationUserManagerShowupStatus"
-    expires_after="2018-05-23">
-  <obsolete>
-    Removed 05/2018 as this is no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Used to indicate the code path where the user profile manager shows up
-    during startup (Windows only). Logged whenever a notification event is being
-    handled.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Accuracy.DownstreamThroughputKbps.EstimatedObservedDiff"
-    units="kbps" expires_after="2019-01-09">
-  <obsolete>
-    Obsoleted in Jan 2019
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated downstream throughput (in
-    kilobits per second) and the observed downstream throughput (in kilobits per
-    second). Downstream throughput estimated by the network quality estimator at
-    the time of navigation start is compared with the downstream throughput
-    observed during the specified time interval following the start of the
-    navigation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Accuracy.EffectiveConnectionType.EstimatedObservedDiff"
-    units="Effective connection type" expires_after="2019-01-09">
-  <obsolete>
-    Obsoleted in Jan 2019
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated effective connection type and
-    the observed effective connection type. Effective connection type is
-    estimated by the network quality estimator at the time of navigation start
-    is compared with the effective connection type observed during the specified
-    time interval following the start of the navigation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Accuracy.HttpRTT.EstimatedObservedDiff" units="ms"
-    expires_after="2019-01-09">
-  <obsolete>
-    Obsoleted in Jan 2019
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated HTTP RTT and the observed HTTP
-    RTT. HTTP RTT estimated by the network quality estimator at the time of
-    navigation start is compared with the HTTP RTT observed during the specified
-    time interval following the start of the navigation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Accuracy.TransportRTT.EstimatedObservedDiff" units="ms"
-    expires_after="2019-01-09">
-  <obsolete>
-    Obsoleted in Jan 2019
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated transport RTT and the observed
-    transport RTT. Transport RTT estimated by the network quality estimator at
-    the time of navigation start is compared with the transport RTT observed
-    during the specified time interval following the start of the navigation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.BDPComputationKbps.OnECTComputation" units="Kbps"
-    expires_after="2018-10-17">
-  <obsolete>
-    Obsoleted in October 2018
-  </obsolete>
-  <owner>devdeepray@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The value of the downstream throughput used to compute the bandwidth delay
-    product. The 80th percentile throughput observation is used to calculate the
-    bandwidth delay product. This gets recorded everytime the BDP is computed.
-  </summary>
-</histogram>
-
-<histogram name="NQE.BDPComputationTransportRTT.OnECTComputation" units="ms"
-    expires_after="2018-10-17">
-  <obsolete>
-    Obsoleted in October 2018
-  </obsolete>
-  <owner>devdeepray@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The value of the TransportRTT used to compute the bandwidth delay product.
-    The 20th percentile TransportRTT observation is used to calculate the
-    bandwidth delay product. This gets recorded everytime the BDP is computed.
-  </summary>
-</histogram>
-
-<histogram name="NQE.BDPKbits.OnECTComputation" units="kbits"
-    expires_after="2018-10-17">
-  <obsolete>
-    Obsoleted in October 2018
-  </obsolete>
-  <owner>devdeepray@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    An estimate of the bandwidth delay product which is computed on main-frame
-    requests. It is calculated using the 80th percentile throughput and 20th
-    percentile TransportRTT values whenever |ComputeEffectiveConnectionType| is
-    called and the throughput and TransportRTT estimates are available.
-  </summary>
-</histogram>
-
-<histogram name="NQE.CellularSignalStrength.AtECTComputation"
-    units="Signal Strength Level" expires_after="2020-01-26">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Cellular signal strength level reported by the device at the time of ECT
-    computation. Recorded only on cellular networks, and only when the value is
-    available. The value ranges between 0 and 4 (both inclusive).
-  </summary>
-</histogram>
-
-<histogram name="NQE.CellularSignalStrength.LevelDifference"
-    units="Signal Strength Level" expires_after="2020-01-26">
-  <obsolete>
-    Obsoleted.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Difference between the minimum and the maximum received signal strength
-    since the last connection change event. Recorded only on cellular
-    connections on Android platform when the cellular signal strength was
-    available. Recorded right before a connection change event.
-  </summary>
-</histogram>
-
-<histogram name="NQE.CellularSignalStrengthAvailable" enum="BooleanAvailable"
-    expires_after="2017-06-28">
-  <obsolete>
-    Replaced by NQE.CellularSignalStrength.LevelAvailable in June 2017.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Whether the signal strength for the cellular network was available or not.
-    Recorded right before a connection change event. Recorded only on cellular
-    connections on Android platform.
-  </summary>
-</histogram>
-
-<histogram name="NQE.CellularSignalStrengthDifference" units="dBm"
-    expires_after="2017-06-28">
-  <obsolete>
-    Replaced by NQE.CellularSignalStrength.LevelDifference in June 2017.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Difference between the minimum and the maximum received signal strength
-    since the last connection change event. Recorded only on cellular
-    connections on Android platform when the cellular signal strength was
-    available. Recorded right before a connection change event.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="NQE.CongestionAnalyzer.CountInflightRequestsForPeakQueueingDelay"
-    units="requests" expires_after="M82">
-  <obsolete>
-    Obsoleted in Apr 2020.
-  </obsolete>
-  <owner>jfwang@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the count of in-flight requests causing the peak queueing delay
-    within the current ongoing measurement period. These samples are bucketized
-    into 10 peak queueing delay levels. This is emitted at the end of the
-    current measurement period.
-  </summary>
-</histogram>
-
-<histogram name="NQE.CongestionAnalyzer.PeakQueueingDelayMappingScore"
-    units="PercentTotalSamples" expires_after="M82">
-  <obsolete>
-    Obsoleted in April 2020.
-  </obsolete>
-  <owner>jfwang@google.com</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the score that evaluates the mapping between the count of in-flight
-    requests to the peak observed queueing delay. The score is the percentage of
-    total samples that follow the rule 'the more in-flight requests, the higher
-    peak queueing delay' when a new peak queueing delay mapping sample is
-    acquired. This is emitted at the end of the current measurement period and
-    only when there are at least 10 cached mapping samples.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ContentObserver.NetworkQualityMeaningfullyChanged"
-    enum="BooleanChanged" expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    This metric is recorded when the network quality change notification is
-    received by content and before the network quality change is notified to the
-    renderers. Records true if the notified network quality change is
-    meaningfully different from the last network quality notified to the
-    renderers.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Correlation.ResourceLoadTime.0Kb_128Kb" units="units"
-    expires_after="2017-12-19">
-  <obsolete>
-    Obsoleted in December 2017.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records estimated network quality (estimated RTT, estimated downlink
-    bandwidth), resource load size, and the resource load time in a single UMA
-    sample. This metric is recorded randomly when a resource load finishes. Each
-    sample in this sparse histogram consists of multiple metrics (each occupying
-    few bits in the sample). The data in the histogram would be analyzed using
-    custom scripts. A sample is recorded only when the resource size is between
-    0 Kilobits (inclusive) and 128 Kilobits (exclusive).
-  </summary>
-</histogram>
-
-<histogram name="NQE.DifferenceRTTActualAndEstimated" units="ms"
-    expires_after="2016-06-08">
-  <obsolete>
-    Replaced in June 2016 by NQE.Accuracy.HttpRTT.* metrics.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Difference between the actual RTT observation and the estimated RTT. This
-    metric is recorded on every request when the actual observation is higher
-    than the estimated value.
-  </summary>
-</histogram>
-
-<histogram name="NQE.DifferenceRTTEstimatedAndActual" units="ms"
-    expires_after="2016-06-08">
-  <obsolete>
-    Replaced in June 2016 by NQE.Accuracy.HttpRTT.* metrics.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Difference between the estimated RTT and the actual RTT observation. This
-    metric is recorded on every request when the estimated value is higher than
-    the actual observation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.EstimateAvailable.MainFrame" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    This histogram records whether the estimate of the network quality metric
-    was available or not. Recorded at every main frame request.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ExternalEstimateProvider.DownlinkBandwidth" units="Kbps"
-    expires_after="2018-02-16">
-  <obsolete>
-    Obsoleted in February 2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the estimate of the downlink bandwidth (in Kbps) provided by the
-    external estimate provided. Recorded every time the external estimate
-    provider provides a valid downlink bandwidth estimate to the network quality
-    estimator.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ExternalEstimateProvider.RTT" units="ms"
-    expires_after="2018-02-16">
-  <obsolete>
-    Obsoleted in February 2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the estimate of the RTT provided by the external estimate provided.
-    Recorded every time the external estimate provider provides a valid RTT
-    estimate to the network quality estimator.
-  </summary>
-</histogram>
-
-<histogram
-    name="NQE.ExternalEstimateProvider.RTT.Accuracy.EstimatedObservedDiff"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Obsoleted in February 2018.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the HTTP RTT estimated by the external
-    estimate provider and the observed HTTP RTT. The HTTP RTT estimated by the
-    external estimate provider at the time of navigation start is compared with
-    the HTTP RTT observed during the specified time interval following the start
-    of the navigation.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ExternalEstimateProviderStatus"
-    enum="NQEExternalEstimateProviderStatus" expires_after="2018-02-16">
-  <obsolete>
-    Obsoleted in February 2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records the interaction (availability and query count) of Network Quality
-    Estimator with external estimates provider. Logged on network change events,
-    everytime external estimate provider is queried for an updated estimate, and
-    when it proactively notifies that an updated estimate is available.
-  </summary>
-</histogram>
-
-<histogram name="NQE.FastestRTT" units="ms" expires_after="2017-08-29">
-  <obsolete>
-    Obsoleted in August 2017
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the fastest round-trip-time, before a connectivity change
-    is detected.
-
-    This metric is recorded when a connectivity change is detected. This will
-    miss data from users whose connection type never changes and will be biased
-    to users whose connection type changes frequently.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Kbps.ObservationSource" enum="NQEObservationSource"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in April 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Number of Kbps observations indexed by the source of the observation.
-    Recorded by the network quality estimator every time a new observation is
-    made or synthesized.
-  </summary>
-</histogram>
-
-<histogram name="NQE.Kbps.RawObservation" units="Kbps"
-    expires_after="2020-06-28">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Downstream throughput observation received or synthesized by network quality
-    estimator. Observations from different sources are recorded in separate
-    histograms.
-  </summary>
-</histogram>
-
-<histogram name="NQE.MainFrame.EffectiveConnectionType"
-    enum="NQEEffectiveConnectionType" expires_after="2020-09-27">
-  <obsolete>
-    Obsoleted in M84.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Effective connection type estimated by network quality estimator. Suffixed
-    with the connection type reported by the operating system.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.MainFrame.Kbps" units="Kbps" expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the downstream peak throughput at different percentiles.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.MainFrame.RTT" units="ms" expires_after="2020-03-01">
-  <obsolete>
-    Obsoleted in M84.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the URLRequest layer at
-    different percentiles.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.MainFrame.TransportRTT" units="ms" expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the transport layer at
-    different percentiles.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.PeakKbps" units="Kbps" expires_after="2017-08-29">
-  <obsolete>
-    Obsoleted in August 2017
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of downstream peak throughput, before a connectivity change
-    is detected.
-
-    This metric is recorded when a connectivity change is detected. This will
-    miss data from users whose connection type never changes and will be biased
-    to users whose connection type changes frequently.
-  </summary>
-</histogram>
-
-<histogram name="NQE.PeerToPeerConnectionsDuration" units="duration"
-    expires_after="M82">
-  <obsolete>
-    Obsoleted in Apr 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Records the duration of the time period for which there was at least one
-    peer to peer active connection. Recorded when the count of peer to peer
-    connections drop from a non-zero value to a zero value.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RatioEstimatedToActualRTT" units="100 times"
-    expires_after="2016-06-08">
-  <obsolete>
-    Replaced in June 2016 by NQE.Accuracy.HttpRTT.* metrics.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Ratio of the estimated RTT to the actual RTT observation multiplied by 100.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RenderThreadNotified" enum="BooleanHit"
-    expires_after="M77">
-  <obsolete>
-    Obsoleted in M-77.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Count of the number of times renderers were notified of the changes in the
-    network quality estimator. This metric makes sense to compare in frequency
-    relative to other events like the number of page loads or the number of
-    renderers seen. It is expected that we will see at least 1 notification per
-    renderer (on average), and less than 100.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT" units="ms" expires_after="2018-05-15">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the URLRequest layer at
-    different percentiles.
-
-    This metric is recorded immediately after a connectivity change is detected.
-    The metric name is suffixed with the connection type before the connectivity
-    change was detected. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.HangingRequest" units="ms" expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP RTT observation received by the network quality estimator. Recorded
-    when the request is detected as hanging.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.NotAHangingRequest.EndToEndRTT" units="ms"
-    expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP RTT observation received by the network quality estimator. Recorded at
-    the beginning of a request if the request is detected as not hanging because
-    the observed HTTP RTT was comparable to the end to end RTT estimate.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.NotAHangingRequest.HttpRTT" units="ms"
-    expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP RTT observation received by the network quality estimator. Recorded
-    when the request is detected as not hanging because it was comparable to the
-    HTTP RTT estimate.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.NotAHangingRequest.MinHttpBound" units="ms"
-    expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP RTT observation received by the network quality estimator. Recorded
-    when the request is detected as not hanging because the RTT value was lower
-    than the minimum threshold RTT needed to be categorized as a hanging
-    request.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.NotAHangingRequest.TransportRTT" units="ms"
-    expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    HTTP RTT observation received by the network quality estimator. Recorded
-    when the request is detected as not hanging because it was comparable to the
-    transport RTT estimate.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTT.RawObservation" units="ms" expires_after="2020-02-23">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    RTT observation received or synthesized by network quality estimator.
-    Observations from different sources are recorded in separate histograms.
-  </summary>
-</histogram>
-
-<histogram name="NQE.RTTObservations" units="ms" expires_after="2016-06-08">
-  <obsolete>
-    Replaced in May 2016 by NQE.MainFrame.RTT.* metrics.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    RTT observations at the URLRequest layer made by network quality estimator,
-    recorded on every request.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ThroughputAnalyzer.HangingRequests.Erased" units="count"
-    expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Count of the requests that were marked as hanging by the heuristic algorithm
-    in the throughput analyzer in the network quality estimator. A sample is
-    recorded everytime the heuristic algorithm is run.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ThroughputAnalyzer.HangingRequests.NotErased"
-    units="count" expires_after="2019-03-06">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Count of the requests that were not marked as hanging by the heuristic
-    algorithm in the throughput analyzer in the network quality estimator. A
-    sample is recorded everytime the heuristic algorithm is run.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ThroughputObservation.Hanging" units="Kbps"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Throughput observation made by network quality estimator, and eventually
-    discarded because the window (over which the througput was computed) was
-    detected as hanging.
-  </summary>
-</histogram>
-
-<histogram name="NQE.ThroughputObservation.NotHanging" units="Kbps"
-    expires_after="M81">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Throughput observation made by network quality estimator, and used when the
-    window (over which the througput was computed) was detected as not hanging.
-  </summary>
-</histogram>
-
-<histogram name="NQE.TransportRTT" units="ms" expires_after="2018-05-15">
-  <obsolete>
-    Removed 01/2018.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the transport layer at
-    different percentiles.
-
-    This metric is recorded immediately after a connectivity change is detected.
-    The metric name is suffixed with the connection type before the connectivity
-    change was detected. This will miss data from users whose connection type
-    never changes and will be biased to users whose connection type changes
-    frequently.
-  </summary>
-</histogram>
-
-<histogram name="NQE.UnweightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff"
-    units="ms" expires_after="2017-08-22">
-  <obsolete>
-    Obsoleted in August 2017.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated HTTP RTT and the observed HTTP
-    RTT. HTTP RTT estimated by the network quality estimator at the time of
-    navigation start is compared with the HTTP RTT observed during the specified
-    time interval following the start of the navigation. Both the estimated and
-    the observed RTT are computed using average algorithm that assigns equal
-    weight to all observations.
-  </summary>
-</histogram>
-
-<histogram name="NQE.UnweightedAverage.MainFrame.RTT" units="ms"
-    expires_after="2017-08-22">
-  <obsolete>
-    Obsoleted in August 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the URLRequest layer
-    computed using average algorithm that assigns equal weight to all
-    observations.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.WeightedAverage.Accuracy.HttpRTT.EstimatedObservedDiff"
-    units="ms" expires_after="2017-08-22">
-  <obsolete>
-    Obsoleted in August 2017.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Records the difference between the estimated HTTP RTT and the observed HTTP
-    RTT. HTTP RTT estimated by the network quality estimator at the time of
-    navigation start is compared with the HTTP RTT observed during the specified
-    time interval following the start of the navigation. Both the estimated and
-    the observed RTT are computed using weighted average algorithm.
-  </summary>
-</histogram>
-
-<histogram name="NQE.WeightedAverage.MainFrame.RTT" units="ms"
-    expires_after="2017-08-22">
-  <obsolete>
-    Obsoleted in August 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Rough estimate of the computed round trip time at the URLRequest layer
-    computed using weighted average algorithm.
-
-    This metric is recorded on main-frame requests.
-  </summary>
-</histogram>
-
-<histogram name="NQE.WifiSignalStrength.AtECTComputation"
-    units="Signal Strength Level" expires_after="2021-07-22">
-  <obsolete>
-    Obsoleted April 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Wifi signal strength level reported by the device at the time of ECT
-    computation. Recorded only on Wifi networks, and only when the value is
-    available. The value ranges between 0 and 4 (both inclusive).
-  </summary>
-</histogram>
-
-<histogram name="NQE.WifiSignalStrength.LevelDifference"
-    units="Signal Strength Level" expires_after="2020-02-16">
-  <obsolete>
-    Obsoleted in M81.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Difference between the minimum and the maximum received signal strength
-    since the last connection change event. Recorded only on Wifi connections on
-    Android platform when the Wifi signal strength was available. Recorded right
-    before a connection change event.
-  </summary>
-</histogram>
-
-<histogram name="ntp.searchurls.total" units="units" expires_after="M80">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="NtpHandler.AttachShownPageType" enum="NtpPaneType"
-    expires_after="2013-06-01">
-  <obsolete>
-    Removed 10/2011. No longer tracked, replaced with NewTabPage.DefaultPageType
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The default pane when the NTP is first opened.</summary>
-</histogram>
-
-<histogram name="NtpHandler.SelectedShownPageType" enum="NtpPaneType"
-    expires_after="2013-06-01">
-  <obsolete>
-    Removed 10/2011. No longer tracked, replaced with
-    NewTabPage.SelectedPageType
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The pane selected when the user switches panes in the NTP.</summary>
-</histogram>
-
-<histogram name="OAuth2Login.AccountRevoked.IsEmailId" enum="Boolean"
-    expires_after="2019-02-14">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    This histogram records whether the account ID is actually an email if we
-    detect an account that has an account ID but not email.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.AccountRevoked.MigrationState"
-    enum="OAuth2LoginAccountRevokedMigrationState" expires_after="2019-02-14">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    This histogram records the account ID migration status from email to GAIA ID
-    if we detect an account that has an account ID but not email.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.GetOAuth2AccessTokenFailure"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Failure reason of final OAuth2 access token retrieval call during Chrome OS
-    login.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.GetOAuth2AccessTokenRetry"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Retry reason of failed OAuth2 access token retrieval call during Chrome OS
-    login.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.ListAccountsFailure" enum="GoogleServiceAuthError"
-    expires_after="2015-05-27">
-  <obsolete>
-    Removed 2015-05-22. Replaced by Signin.ListAccountsFailure.
-  </obsolete>
-  <owner>zelidrag@chromium.org</owner>
-  <summary>
-    Failure reason of final ListAccounts call failure during Chrome OS login.
-    This data is now included in Signin.ListAccountsFailure.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.ListAccountsRetry" enum="GoogleServiceAuthError"
-    expires_after="2015-05-27">
-  <obsolete>
-    Removed 2015-05-22. Replaced by Signin.ListAccountsRetry.
-  </obsolete>
-  <owner>zelidrag@chromium.org</owner>
-  <summary>
-    Retry reason of failed ListAccounts call during Chrome OS login. This data
-    is now included in Signin.ListAccountsRetry.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.OAuthLoginGaiaCredFailure"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Failure reason of final OAuthLogin (with SID+LSID) call during Chrome OS
-    login.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.OAuthLoginGaiaCredRetry"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>tbarzic@chromium.org</owner>
-  <summary>
-    Retry reason of failed OAuthLogin (with SID+LSID) call during Chrome OS
-    login.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.OAuthLoginUberTokenFailure"
-    enum="GoogleServiceAuthError" expires_after="2015-05-27">
-  <obsolete>
-    Removed 2015-05-22
-  </obsolete>
-  <owner>zelidrag@chromium.org</owner>
-  <summary>
-    Failure reason of final OAuthLogin (with uber token) call during Chrome OS
-    login. This data is now (M44+) included in Signin.UberTokenFailure.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.OAuthLoginUberTokenRetry"
-    enum="GoogleServiceAuthError" expires_after="2015-05-27">
-  <obsolete>
-    Removed 2015-05-22
-  </obsolete>
-  <owner>zelidrag@chromium.org</owner>
-  <summary>
-    Retry reason of failed OAuthLogin (with uber token) call during Chrome OS
-    login. This data is now (M44+) included in Signin.UberTokenRetry.
-  </summary>
-</histogram>
-
-<histogram name="OAuth2Login.SeedState" enum="OAuth2LoginSeedState"
-    expires_after="2019-02-14">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>knn@chromium.org</owner>
-  <summary>
-    Only applicable on M47 on Android. Measure the frequency of a suppressed
-    error state when the account is not seeded.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.AggregatedRequestResult"
-    enum="OfflinePagesAggregatedRequestResult" expires_after="2016-10-26">
-  <obsolete>
-    Removed 2016-10, and replaced by OfflinePages.AggregatedRequestResult2.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>Result of servicing requests that may contain offline page.</summary>
-</histogram>
-
-<histogram base="true"
-    name="OfflinePages.ArchiveManager.ArchiveDirsCreationResult"
-    enum="PlatformFileError" expires_after="2017-10-03">
-  <obsolete>
-    Removed 2017-10, and replaced by
-    OfflinePages.ArchiveManager.ArchiveDirsCreationResult2 with suffixes for
-    temporary and persistent pages.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    This is recorded every time the archive directory is being created. It
-    doesn't include the case which the archive directory exists.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.BackgroundLoadingFailedCode"
-    enum="NetErrorCodes" expires_after="M61">
-  <obsolete>
-    Removed in M61.
-  </obsolete>
-  <owner>chili@chromium.org</owner>
-  <summary>The error codes that caused a page load failure.</summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.CctApiDisableStatus"
-    enum="OfflinePagesCctApiPrerenderAllowedStatus" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    Reason for the Chrome Custom Tabs API prerender call to be ignored.
-
-    There are several causes for the Chrome Custom Tabs API calls to be ignored,
-    this tracks the potential causes so we can see how often the prerenderer
-    doesn't prerender due to these being switched off. Since this is checked
-    elsewhere (CCTAPI), this only catches the user switching off the third party
-    cookies or navigation prediction after the CCT API has checked.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.ResourceCompletion.Css"
-    enum="BooleanEnabled" expires_after="M80">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    True if all requested CSS was loaded when a background page loaded.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.ResourceCompletion.Image"
-    enum="BooleanEnabled" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    True if all requested images were loaded when a background page loaded.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.ResourceCompletion.Xhr"
-    enum="BooleanEnabled" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    True if all requested XHRs were completed when a background page loaded.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Background.UnsupportedScheme.ConnectionType"
-    enum="NetworkConnectionType" expires_after="M61">
-  <obsolete>
-    Removed in M61.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Connection type when prerenderer reports Unsupported Scheme error.
-
-    To give insight about Unsupported Scheme errors that may be due to lost
-    network connection (as data URL used for rendering an error page will
-    manifest as an Unsupported Scheme error by the prerenderer).
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.BatchDelete.Count" units="units"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of offline pages that are deleted in a batch.</summary>
-</histogram>
-
-<histogram name="OfflinePages.BatchDelete.TotalPageSize" units="KB"
-    expires_after="M65">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Total size, in kilobytes, of all offline pages that are deleted in a batch.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.CanSaveRecentPage" enum="Boolean"
-    expires_after="2019-05-31">
-  <obsolete>
-    Removed on 6/2019. No longer considered useful.
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <summary>
-    Reports whether a web page complies with all requirements for it to be
-    allowed to be saved as an offline page. This is reported only on Android,
-    after a successful main frame navigation is finished.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.ClearAllStatus" enum="OfflinePagesClearAllStatus"
-    expires_after="2016-03-03">
-  <obsolete>
-    Removed 3/2016, and replaced by OfflinePages.ClearAllStatus2.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Status code of wiping out the offline page data.</summary>
-</histogram>
-
-<histogram name="OfflinePages.ClearAllStatus2"
-    enum="OfflinePagesClearAllStatus" expires_after="M83">
-  <obsolete>
-    Removed a long time ago, marked as expired for M83.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Status code of wiping out the offline page data.</summary>
-</histogram>
-
-<histogram name="OfflinePages.ClearStorageBatchSize" units="pages"
-    expires_after="2018-01-08">
-  <obsolete>
-    Removed as of Jan 2018, replaced by
-    OfflinePages.ClearTemporaryPages.BatchSize.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Number of pages deleted in a batch during one clear-storage request.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.ClearStoragePreRunUsage" units="bytes"
-    expires_after="2017-10-19">
-  <obsolete>
-    Removed in Oct 2017 and replaced by OfflinePages.ClearStoragePreRunUsage2 as
-    it was reporting data in bytes instead of the expected MiB.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    The total storage size used by all offline pages from a specific client
-    namespace.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.ClearStorageResult"
-    enum="OfflinePagesClearStorageResult" expires_after="2018-01-08">
-  <obsolete>
-    Removed as of Jan 2018, replaced by OfflinePages.ClearTemporaryPages.Result.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>Result of asking storage manager to clear storage.</summary>
-</histogram>
-
-<histogram name="OfflinePages.Consistency.DeleteOrphanedArchivesResult"
-    enum="BooleanSuccess" expires_after="2017-12-08">
-  <obsolete>
-    Removed 12/2017, replaced by OfflinePages.ConsistencyCheck.Temporary.Result
-    and OfflinePages.ConsistencyCheck.Persistent.Result.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Whether an attempt to delete archive files without metadata was successful.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Consistency.DeletePagesMissingArchiveFileResult"
-    enum="OfflinePagesDeletePageResult" expires_after="2017-12-08">
-  <obsolete>
-    Removed 12/2017, replaced by OfflinePages.ConsistencyCheck.Temporary.Result
-    and OfflinePages.ConsistencyCheck.Persistent.Result.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Whether an attempt to delete pages without archives was successful.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Consistency.ExpirePagesMissingArchiveFileResult"
-    enum="BooleanSuccess" expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016, replaced by
-    OfflinePages.Consistency.DeletePagesMissingArchiveFileResult.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Whether an attempt to expire pages without archives was successful.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Consistency.OrphanedArchivesCount" units="units"
-    expires_after="2017-12-08">
-  <obsolete>
-    Removed 12/2017, replaced by
-    OfflinePages.ConsistencyCheck.Temporary.PagesMissingDbEntryCount and
-    OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Number of archives without metadata entry when checking consistency.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Consistency.PagesMissingArchiveFileCount"
-    units="units" expires_after="2017-12-08">
-  <obsolete>
-    Removed 12/2017, replaced by
-    OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount and
-    OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Number of offline pages without archive file when checking consistency.
-  </summary>
-</histogram>
-
-<histogram
-    name="OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount"
-    units="pages" expires_after="M80">
-  <obsolete>
-    Removed 04/2018, since saving public offline pages to external download
-    directory needs a different consistency check strategy.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Number of persistent offline pages without archive file when checking
-    consistency. It will only be reported if the number is larger than 0.
-  </summary>
-</histogram>
-
-<histogram
-    name="OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount"
-    units="pages" expires_after="M80">
-  <obsolete>
-    Removed 04/2018, since saving public offline pages to external download
-    directory needs a different consistency check strategy.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Number of archives without database entry when checking persistent page
-    consistency. It will only be reported if the number is larger than 0.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.AccessCount" units="units"
-    expires_after="2017-12-21">
-  <obsolete>
-    Removed as of 12/2017. Replaced by OfflinePages.AccessCount.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Number of accesses to the offline page since its creation. This is reported
-    when the offline page was deleted.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.FreeSpaceMB" units="MB"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used, duplicate of
-    OfflinePages.SavePage.FreeSpaceMB.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The amount of free space available, in megabytes, on the user's device after
-    the page is deleted.
-
-    Note that before M52 this operation was started before delete operation.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.FreeSpacePercentage" units="%"
-    expires_after="2016-05-18">
-  <obsolete>
-    Removed as of 5/2016. Marginal applicability.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The percentage of free space available on the user's device when the page is
-    being deleted.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.LastOpenToCreated" units="minutes"
-    expires_after="2018-01-08">
-  <obsolete>
-    Removed as of 01/2018. Replaced by OfflinePages.PageAccessInterval.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time between when an offline page was created and was opened last
-    time. This is reported when the page was deleted.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.PageSize" units="KB"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used, duplicate of OfflinePages.PageSize.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Size of the offline page, in kilobytes, that was deleted.</summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.TimeSinceLastOpen" units="minutes"
-    expires_after="2018-01-08">
-  <obsolete>
-    Removed as of 01/2018. Replaced by OfflinePages.PageAccessInterval.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Length of time between when an offline page was last opened and was deleted.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DeletePage.TotalPageSizeAsPercentageOfFreeSpace"
-    units="%" expires_after="2018-03-30">
-  <obsolete>
-    Removed as of 03/2018. Replaced by similar metric
-    OfflinePages.StorageInfo.InternalUsagePercentage and
-    OfflinePages.StorageInfo.ExternalUsagePercentage.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The percentage of space taken by offline pages from the free space that
-    could be available, if the feature was not present. I.e. considering
-    situation where the user has: Free Space, Offline content, other apps and
-    data. This is a percentage of: Offline content / (Offline content + Free
-    Space).
-
-    The value will be recorded after user deletes a single or multiple offline
-    pages. In case pages are removed in bulk, this value will be reported once.
-    This value is only reported with deleting, as we are trying to infer if lack
-    of free space might have caused the user to delete.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DownloadDeletedPageDuplicateCount" units="pages"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    The number of downloaded pages with the same URL that exist at the time that
-    we delete a downloaded page.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DownloadSavedPageDuplicateCount" units="pages"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    The number of downloaded pages with the same URL that exist at the time that
-    we save a downloaded page.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.DownloadSavedPageTimeSinceDuplicateSaved"
-    units="seconds" expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    If at save time there is another downloaded page with the same URL, this
-    tracks this amount of time between creation of the most recent existing page
-    and the current page.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Edit.BookmarkUrlChangedForOfflinePage"
-    enum="BooleanMatched" expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Offline pages no longer depend on bookmarks UI.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Whether a user-edited bookmark URL had a saved offline page.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.ExpirePage.BatchSize" units="units"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016. Offline pages no longer use two-step expiration.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>Number of pages that are expired in a batch.</summary>
-</histogram>
-
-<histogram name="OfflinePages.ExpirePage.PageLifetime" units="minutes"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016. Offline pages no longer use two-step expiration.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Length of time between when an offline page was created and was expired.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.ExpirePage.StoreUpdateResult"
-    enum="BooleanSuccess" expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016. Offline pages no longer use two-step expiration.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>Result of updating expired page in store.</summary>
-</histogram>
-
-<histogram name="OfflinePages.ExpirePage.TimeSinceLastAccess" units="minutes"
-    expires_after="2016-11-30">
-  <obsolete>
-    Removed 11/2016. Offline pages no longer use two-step expiration.
-  </obsolete>
-  <owner>romax@chromium.org</owner>
-  <summary>
-    Length of time between when an offline page was last opened and was expired.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Filter.OnlineWhenEntering" enum="Boolean"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Offline pages no longer depend on bookmarks UI.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether user is connected when entering the filter with offline only
-    content.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Filter.OnlineWhenLeaving" enum="Boolean"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Offline pages no longer depend on bookmarks UI.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether user is connected when leaving the filter with offline only content.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.FirstOpenSinceCreated" units="minutes"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. Merged to OfflinePages.PageAccessInterval.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The time elapsed between creation of the offline page and the first time it
-    was opened.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.IncognitoSave" enum="Boolean"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Not longer needed.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether the page that was being saved offline was in incognito mode.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.LaunchLocation" enum="StarsLaunchLocation"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Offline pages no longer depend on bookmarks UI.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>Logs a UI location from which an offline page is launched.</summary>
-</histogram>
-
-<histogram name="OfflinePages.LoadStatus" enum="OfflinePagesLoadStatus"
-    expires_after="M65">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Status code of loading from the offline pages metadata store.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.LoadSuccess" enum="BooleanSuccess"
-    expires_after="2015-10-27">
-  <obsolete>
-    Removed 10/2015, and replaced by OfflinePages.LoadStatus.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether an attempt to load the offline pages metadata store was successful.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Model.ArchiveDirCreationTime" units="ms"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The amount of time to create the offline pages archive directory.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Model.ConstructionToLoadedEventTime" units="ms"
-    expires_after="M65">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>dewittj@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The amount of time to create the offline pages archive directory and load
-    the offline page model.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Model.FinalLoadSuccessful" enum="Boolean"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Whether the metadata database was successfully loaded, after possibly
-    several retries.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Model.InitAttemptsSpent" units="attempts"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. No longer used.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    The count of attempts spent to open the metadata database. In the best case,
-    it's 1. There is a small upper limit. This is recorded only at success.
-    Failures are counted by OfflinePages.Model.FinalLoadSuccessful.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.OfflinePageCount" units="units"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. This was the dup of OfflinePages.SavedPageCount.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>Number of offline pages the user has. Android only.</summary>
-</histogram>
-
-<histogram name="OfflinePages.OnlineOnOpen" enum="Boolean"
-    expires_after="2016-05-17">
-  <obsolete>
-    Removed 5/2016. Offline pages no longer depend on bookmarks UI.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether the user was online when a saved page with offline copy was opened.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.OpenSinceLastOpen" units="minutes"
-    expires_after="2018-02-05">
-  <obsolete>
-    Removed 2/2018. Merged to OfflinePages.PageAccessInterval.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Length of time between two consecutive opens.</summary>
-</histogram>
-
-<histogram name="OfflinePages.Prefetching.ActionRetryAttempts" units="attempts"
-    expires_after="2017-09-15">
-  <obsolete>
-    Removed 9/2017. Replaced by OfflinePages.Prefetching.ActionAttempts
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <summary>
-    Number of attempts to perform a specific retriable pipeline action for each
-    finished prefetch item.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Prefetching.DownloadedArchiveSizeVsExpected"
-    enum="OfflinePrefetchArchiveActualSizeVsExpected"
-    expires_after="2018-08-20">
-  <obsolete>
-    Removed 8/2018.
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <summary>
-    Reports differences between the expected size of a prefetch archive -- as
-    reported by the service -- and the actual downloaded file size.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Prefetching.FetchThumbnail.Complete"
-    enum="OfflinePagesThumbnailFetchStatus" expires_after="2018-11-30">
-  <obsolete>
-    Removed as of 5/2018. Replaced with
-    OfflinePages.Prefetching.FetchThumbnail.Complete2.
-  </obsolete>
-  <owner>harringtond@chromium.org</owner>
-  <summary>
-    Records the final status of attempts to fetch thumbnails for prefetched
-    offline pages.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Prefetching.FetchThumbnail.Complete2"
-    enum="OfflinePagesThumbnailFetchStatus" expires_after="2019-05-30">
-  <obsolete>
-    Removed as of 2/2019.
-  </obsolete>
-  <owner>harringtond@chromium.org</owner>
-  <owner>carlosk@chromium.org</owner>
-  <summary>
-    Records the final status of attempts to fetch thumbnails for prefetched
-    offline pages. The 1st attempt takes place right after the prefetch item was
-    sent to the cloud service as part of a request for the creation of its
-    offline snapshot. The 2nd attempt occurs right after the offline snapshot
-    was successfully downloaded by the client.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Prefetching.FetchThumbnail.Start" enum="Boolean"
-    expires_after="2019-03-04">
-  <obsolete>
-    Removed as of 2/2019.
-  </obsolete>
-  <owner>harringtond@chromium.org</owner>
-  <summary>Reports each time a thumbnail fetch is attempted.</summary>
-</histogram>
-
-<histogram name="OfflinePages.PrefetchStore.TimeFromCloseToOpen" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 8/2019. No longer needed.
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Tracks the time between store closing and reopening again within a session.
-    The store is meant to close itself after a period of inactivity. We are
-    trying to assess how much time the store is unloaded from memory vs. time it
-    is loaded and not used. This event will be reported when the store is opened
-    after being closed within the same lifetime of Chrome.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.PublishArchive.CreateDirectoryError"
-    enum="PlatformFileError" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    When publishing an archive, we create the download directory if it doesn't
-    already exist. If we get an error, we record it here.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.PublishArchive.MoveFileError"
-    enum="PopularOSErrno" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    When publishing an offline page, the move file step can fail. This returns
-    the reason for failure as a linux errno.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.PublishArchive.MoveFileFailureReason"
-    enum="OfflinePagesPublishArchiveMoveFileFailureReason" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    When a move file fails for publishing, what caused the failure.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.PublishPageResult"
-    enum="OfflinePagesSavePageResult" expires_after="M85">
-  <obsolete>
-    Removed on 04/2020 in favor of becoming a special case of
-    OfflinePages.SavePageResult2.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    Failure attempting to move a file while publishing downloaded page.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RedirectResult" enum="OfflinePagesRedirectResult"
-    expires_after="2016-08-25">
-  <obsolete>
-    Removed 8/2016. Use OfflinePages.RequestResult instead.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Result of automatic redirect to offline version of the page or back. Emitted
-    exactly once when offline-to-online or online-to-offline redirect is
-    determined to be needed and conveys the outcome of redirect.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RedirectToOfflineCount" units="count"
-    expires_after="2016-06-30">
-  <obsolete>
-    Removed 6/2016. Refactored into OfflinePages.RedirectResult.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Number of times an offline copy was loaded instead when the user is trying
-    to load the online version of a saved page and there is no network
-    connection.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RedirectToOnlineCount" units="count"
-    expires_after="2016-06-30">
-  <obsolete>
-    Removed 6/2016. Refactored into OfflinePages.RedirectResult.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Number of times an online version was loaded instead when the user is trying
-    to load the offline copy of a saved page and there is network connection.
-    connection.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RequestJob.IntentDataChangedAfterValidation"
-    enum="BooleanChanged" expires_after="M77">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Records whether the content read from intent URI (file:// or content://)
-    changed after the initial validation that was done to route the request when
-    the intent was received. This is recorded at the time that Offline Page
-    Request Handler tried to read the data, in preparation to show an offline
-    page to a user.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RequestJob.OpenFileErrorCode"
-    enum="NetErrorCodes" expires_after="2018-08-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Positive net error code for opening the underlying file to serve the offline
-    page, including net::OK.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RequestJob.RangeHeader" enum="BooleanExists"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Track whether the range header is provided when an offline page is served.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RequestJob.ReadFileErrorCode"
-    enum="NetErrorCodes" expires_after="M77">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Positive net error code for the failure to read the underlying file to serve
-    the offline page. net::OK is not included.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.RequestJob.SeekFileErrorCode"
-    enum="NetErrorCodes" expires_after="M77">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Positive net error code for the failure to seek the underlying file to serve
-    the offline page. net::OK is not included.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SavedPageCount" units="pages"
-    expires_after="2018-02-08">
-  <obsolete>
-    Removed as of 2/2018. Replaced by OfflinePages.SavedPageCountUponQuery.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Number of saved pages restored from the offline pages metadata store when it
-    is logged.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SavePage.FreeSpaceMB" units="MB"
-    expires_after="2018-03-30">
-  <obsolete>
-    Removed as of 03/2018. Replaced by similar metric
-    OfflinePages.StorageInfo.InternalFreeSpaceMB.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The amount of free space available, in megabytes, on the user's device after
-    the page is saved.
-
-    Note that before M52 this operation was started before save operation.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SavePage.FreeSpacePercentage" units="%"
-    expires_after="2016-05-18">
-  <obsolete>
-    Removed as of 5/2016. Marginal applicability.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    The percentage of free space available on the user's device when the page is
-    being saved.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SavePageCount"
-    enum="OfflinePagesNamespaceEnumeration" expires_after="M85">
-  <obsolete>
-    Removed on 04/2020. The same information can be obtained from
-    OfflinePages.SavePageResult2.* (from each namespace suffix).
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Counts the number of times an offline page is saved. Events are reported per
-    offline pages namespace.
-  </summary>
-</histogram>
-
-<histogram base="true" name="OfflinePages.SavePageResult"
-    enum="OfflinePagesSavePageResult" expires_after="M85">
-  <obsolete>
-    Removed on 04/2020. Replaced with OfflinePages.SavePageResult2.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>Result of saving an offline copy for a page.</summary>
-</histogram>
-
-<histogram name="OfflinePages.ShowOfflinePageOnBadNetwork" enum="Boolean"
-    expires_after="2016-06-30">
-  <obsolete>
-    Removed 6/2016. Refactored into OfflinePages.RedirectResult.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether an offline page is shown, instead of error page, when the network is
-    disconnected or poor condition.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SQLStorage.CreateDirectoryResult"
-    enum="PlatformFileError" expires_after="2019-03-07">
-  <obsolete>
-    Removed 3/2019.
-  </obsolete>
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    If the directory to store the SQLite database file does not exist, it is
-    created. This is recorded every time the database is opened, even if the
-    directory already exists, in which case it's reported as FILE_OK.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.SQLStorage.TimeFromCloseToOpen" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 8/2019. No longer needed.
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Tracks the time between store closing and reopening again. The store is
-    meant to close itself after a period of inactivity. We are trying to assess
-    how much time the store is unloaded from memory vs. time it is loaded and
-    not used. This event will be reported when the store is opened after being
-    closed within the same lifetime of Chrome.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.TotalPageSize" units="MB"
-    expires_after="2018-03-30">
-  <obsolete>
-    Removed as of 03/2018. Replaced by similar metric
-    OfflinePages.StorageInfo.TotalArchiveSize.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Total size of all the offline pages saved by the user.
-
-    This value is recorded whenever the number of pages change, meaning after a
-    page is added or removed. If pages are removed in bulk, this value will be
-    reported only once.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.TotalPageSizePercentage" units="%"
-    expires_after="2016-05-18">
-  <obsolete>
-    Removed as of 5/2016. Marginal applicability.
-  </obsolete>
-  <owner>fgorski@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Total size of all the offline pages saved by the user as a percentage of
-    total storage size.
-
-    This value is recorded whenever the number of pages change, meaning after a
-    page is added or removed.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Wakeup.BatteryPercentage" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Percentage of battery remaining when the offline page background loading
-    task wakes up to check for work.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Wakeup.ConnectedToPower" enum="BooleanConnected"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Whether the device is plugged in when the offline page background load task
-    wakes up to check or work.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Wakeup.DelayTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Time delay from a dinosaur page to connection being available.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePages.Wakeup.NetworkAvailable"
-    enum="NetworkConnectionType" expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <owner>jianli@chromium.org</owner>
-  <summary>
-    Which network is available (if any) when the offling page background loading
-    task wakes up to check for work.
-  </summary>
-</histogram>
-
-<histogram
-    name="OfflinePages.WebsiteSettings.ConnectedWhenOpenOnlineButtonClicked"
-    enum="BooleanConnected" expires_after="M78">
-  <obsolete>
-    Removed as of 8/2019. No longer needed.
-  </obsolete>
-  <owner>carlosk@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Indicates whether the browser was connected when Open online button was
-    clicked on Page Info popup, which causes a reload of an offline page to
-    online version.
-  </summary>
-</histogram>
-
-<histogram name="OfflinePolicy.SuccessfulResourceLoadPercentage" units="%"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When a page is loaded in offline mode, the percentage of resources on that
-    page that were successfully loaded.
-  </summary>
-</histogram>
-
-<histogram name="OffscreenCanvas.TextMetrics.MeasureText" units="microseconds"
-    expires_after="2019-08-14">
-  <obsolete>
-    Removed 2019/08, this metrics doesn't reflect the measurement speed because
-    it is dependent on the length of text.
-  </obsolete>
-  <owner>yiyix@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    Time spent in microseconds to perform calls to measure TextMetrics for
-    OffscreenCanvas. It's measured each time TextMetrics is called.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.AggressiveHistoryURLProviderFieldTrialBeacon"
-    enum="OmniboxAggressiveHistoryURLProviderFieldTrialBeacon"
-    expires_after="2013-04-16">
-  <obsolete>
-    Aggressive HistoryURL provider field trial deleted in spring 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    A number that indicates what omnibox ranking behavior the user is seeing as
-    part of the OmniboxAggressiveHistoryURLProvider field trial
-    (OmniboxAggressiveHistoryURLProvider).
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.AnswerInSuggestShown"
-    enum="SuggestionAnswerOptionalType" expires_after="M83">
-  <obsolete>
-    Removed in August 2020.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>chrome-android-omnibox-team@google.com</owner>
-  <summary>
-    Records number of times an Answer is presented as one of the Omnibox
-    Suggestions at the time the user exited the omnibox. Exiting the omnibox
-    includes navigating (to entered text or any suggestion), pressing the system
-    back key, clearing omnibox, blanking screen / locking the phone (whether
-    intentionally or due to inactivity), or closing the Chrome app. This metric
-    is logged every time the omnibox is exited, including when no answer is
-    present in the list of suggestions.
-
-    Nota bene: in some circumstances this histogram is double counting on
-    purpose. Scenarios cover repetitive actions that expose same answer
-    suggestion, ie. leave-enter-leave application, or leave-enter-clear where no
-    new suggestion fetches are done.
-
-    This histogram assumes that no more than 1 AiS suggestion is shown at a
-    time, which was enforced by the backend at the time the histogram was
-    created. Additional histogram/s may be required to properly track how
-    frequently answers are shown in general - and in what quantity.
-
-    This histogram is related to Omnibox.SuggestionUsed.AnswerInSuggest.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.CharTypedToRepaintLatency.Composited" units="ms"
-    expires_after="2017-08-21">
-  <obsolete>
-    This became the new implementation of Omnibox.CharTypedToRepaintLatency as
-    of 08/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    A refinement of the Omnibox.CharTypedToRepaintLatency metric that attempts
-    to more accurately track the latency by measuring until the point when the
-    compositor has actually put pixels on the screen. In particular, this will
-    capture the time used to also paint the Omnibox result views as a result of
-    the character insertion, which is not covered by
-    Omnibox.CharTypedToRepaintLatency. If there are multiple keystrokes before a
-    paint, logs the time since the earliest one.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.EditUrlSuggestionAction"
-    enum="OmniboxEditUrlSuggestionAction" expires_after="M85">
-  <obsolete>
-    Removed 06/2020. Use &quot;Omnibox.EditUrlSuggestion.*&quot; user actions
-    instead.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mdjones@chromium.org</owner>
-  <owner>fgorski@chromium.org</owner>
-  <owner>ender@chromium.org</owner>
-  <summary>
-    The action performed on the edit-URL omnibox suggestion that contains the
-    &quot;what you typed&quot;/current URL. If visible, this is the first
-    suggestion.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.EnteredKeywordMode" enum="OmniboxEnteredKeywordMode"
-    expires_after="2018-10-31">
-  <obsolete>
-    Removed 10/2018 and replaced with &quot;Omnibox.EnteredKeywordMode2&quot;.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The number of times users enter keyword hint mode &quot;Search ___
-    for:&quot; and how.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.FocusToOpenTime" units="ms" expires_after="2014-05-01">
-  <obsolete>
-    Replaced with Omnibox.FocusToOpenTimeAnyPopupState in April 2014.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The length of time between when a user focused on the omnibox and opened an
-    omnibox match (which could be what they typed or a suggestion).
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.FocusToOpenTimeAnyPopupState" units="ms"
-    expires_after="2016-08-12">
-  <obsolete>
-    Replaced with Omnibox.FocusToOpenTimeAnyPopupState2 in August, 2016.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The length of time between when a user focused on the omnibox and opened an
-    omnibox match (which could be what they typed or a suggestion). This is
-    recorded regardless of whether the omnibox dropdown (a.k.a. popup) is open.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.FocusToOpenTimeAnyPopupState2" units="ms"
-    expires_after="2017-01-20">
-  <obsolete>
-    Replaced with Omnibox.FocusToOpenTimeAnyPopupState3 in January, 2017, which
-    only differs in the bucketing and range.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The length of time between when a user focused on the omnibox and opened an
-    omnibox match (which could be what they typed or a suggestion). This is
-    recorded regardless of whether the omnibox dropdown (a.k.a. popup) is open.
-    It is not recorded if a match is opened without triggering a focus event,
-    e.g., when a user drags a URL to the omnibox to navigate.
-
-    To know how common this last condition is, compare the total count of this
-    histogram to the total number of omnibox events.
-
-    Android started logging this in M76.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.HardwareKeyboardModeEnabled" enum="BooleanEnabled"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-07-15
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>pkl@chromium.org</owner>
-  <summary>
-    iOS: Records whether a hardware keyboard is used to input text. This is
-    recorded each time a UIKeyboardWillChangeFrameNotification is sent while
-    editing the omnibox text.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.HasLegalDefaultMatchWithoutCompletion" enum="Boolean"
-    expires_after="2015-01-27">
-  <obsolete>
-    Removed 2015-01-27
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Whether there was at least one legal default match without an
-    |inline_autocompletion|. Recorded every time
-    AutocompleteResult::SortAndCull() is called, which could happen multiple
-    times on each keystroke.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.HistoryQuickHistoryIDSetFromWords" units="ms"
-    expires_after="M86">
-  <obsolete>
-    Removed in August 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Times URLIndexPrivateData::HistoryIDSetFromWords(), which is called by the
-    omnibox's HistoryQuick provider.
-    URLIndexPrivateData::HistoryIDSetFromWords() can be called multiple times
-    per keystroke due to, for example, the cursor being in the middle of the
-    input string or SearchProvider's calls to Classify().
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.LocalHistoryZeroSuggest.MaxMatchesCount" units="count"
-    expires_after="M80">
-  <obsolete>
-    Made obsolete in July 2020 for the M86 Milestone.
-  </obsolete>
-  <owner>mahmadi@chromium.org</owner>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    The maximum number of matches returned by the provider. Triggered when
-    zero-prefix suggestions are enabled and requested as a result of user focus
-    into the Omnibox or the Realbox on the NTP.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.LocalHistoryZeroSuggest.SearchTermsSeenCount"
-    units="count" expires_after="M80">
-  <obsolete>
-    Made obsolete in July 2020 for the M86 Milestone.
-  </obsolete>
-  <owner>mahmadi@chromium.org</owner>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    The number of search terms examined until the maximum possible matches are
-    fulfilled. Used to determine the upper bound of search terms to query from
-    the keyword search terms database. Triggered when zero-prefix suggestions
-    are enabled and requested as a result of user focus into the Omnibox or the
-    Realbox on the NTP.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.MatchStability.AsyncMatchChange" units="position"
-    expires_after="2019-11-10">
-  <obsolete>
-    Removed 2019-11-10. Replaced by Omnibox.MatchStability.AsyncMatchChange2.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    This histogram was buggy and the data should be disregarded.
-
-    The original intent was to count asynchronous match updates for each
-    position. The implementation had a bug, and it overcounted.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.PhysicalWebProvider.SuggestionUsedWithoutOmniboxFocus"
-    enum="Boolean" expires_after="2018-04-17">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Records a boolean value indicating whether the Physical Web provider was
-    invoked by focusing the omnibox during the current omnibox session. This is
-    unexpected; it's probably a bug somwhere. Recorded when the user selects an
-    omnibox suggestion. Does not record when the Physical Web omnibox provider
-    is disabled.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.PhysicalWebProviderMatches" units="units"
-    expires_after="2018-04-17">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    The number of matches returned by PhysicalWebProvider. Emitted when the
-    omnibox is first focused, unless the user is in incognito mode. Capped at
-    10.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ProgressBarBreakPointUpdateCount"
-    units="break point updates" expires_after="2017-05-23">
-  <obsolete>
-    Obsolete 05/16/2017. Data is unused (crbug.com/719801).
-  </obsolete>
-  <owner>kkimlabs@chromium.org</owner>
-  <summary>
-    The number of progress bar break point updates from page load started to
-    page load finished.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ProgressBarUpdateCount" units="frame updates"
-    expires_after="2017-05-23">
-  <obsolete>
-    Obsolete 05/16/2017. Data is unused (crbug.com/719801).
-  </obsolete>
-  <owner>kkimlabs@chromium.org</owner>
-  <summary>
-    The number of progress bar frame updates from page load started to page load
-    finished. If there is no animation, this matches
-    Omnibox.ProgressBarBreakPointUpdateCount. Note that there can be additional
-    updates after page load finished, animating to 100%, but this histogram
-    doesn't include them.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ProviderTime" units="ms" expires_after="2015-06-17">
-  <obsolete>
-    Removed 2015-06-12. Replaced by Omnibox.ProviderTime2.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The length of time taken by the named provider&quot;s synchronous pass.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.QueryBookmarksTime" units="units"
-    expires_after="2013-04-16">
-  <obsolete>
-    Removed 2012-11-14. Replaced by Omnibox.ProviderTime.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time the HistoryContentProvider takes to perform a bookmark search.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.QueryGeolocationAcquisitionTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019 for M-78.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>stkhapugin@chromium.org</owner>
-  <summary>
-    The elapsed time to acquire the location sent in the X-Geo header for an
-    Omnibox query.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.QueryGeolocationHorizontalAccuracy" units="meters"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019 for M-78.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>stkhapugin@chromium.org</owner>
-  <summary>
-    The estimated horizontal accuracy of the location sent in the X-Geo header
-    for an Omnibox query.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.QueryIosLocationAuthorizationStatus"
-    enum="IosLocationAuthorizationStatus" expires_after="M86">
-  <obsolete>
-    Removed in August 2020
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>stkhapugin@chromium.org</owner>
-  <summary>
-    For iOS, whether the application is authorized to use location services when
-    the user enters a search query into the Omnibox.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.QueryTime" units="ms" expires_after="2015-06-17">
-  <obsolete>
-    Removed 2015-06-12. Replaced by Omnibox.QueryTime2.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Time it takes for the omnibox to become responsive to user input after the
-    user has typed N characters. This measures the time it takes to start all
-    the asynchronous autocomplete providers (but not wait for them to finish).
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.RichEntity.DecorationType"
-    enum="SuggestionEntityDecorationType" expires_after="M84">
-  <obsolete>
-    Removed in August 2020.
-  </obsolete>
-  <owner>ender@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>chrome-android-omnibox-team@google.com</owner>
-  <summary>
-    Records, for each entity suggestion (people, music, ...) whether it was
-    decorated with image / color / icon at the time the user exited the omnibox.
-    Exiting the omnibox includes navigation (url or query), pressing back key,
-    locking the phone, clearing the omnibox, closing Chrome, or just screen
-    blacking out due to prolonged inactivity.
-
-    This metric is currently only recorded on Android, though it could be added
-    to the other platforms.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.RichEntityShown" units="count" expires_after="M84">
-  <obsolete>
-    Removed in August 2020.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>chrome-android-omnibox-team@google.com</owner>
-  <summary>
-    Records number of presented Rich Entity suggestions at the time the user
-    exited the omnibox. Exiting the omnibox includes navigating (to entered text
-    or any suggestion), pressing the system back key, clearing omnibox, blanking
-    screen / locking the phone (whether intentionally or due to inactivity), or
-    closing the Chrome app. This metric is logged every time the omnibox is
-    exited, including when no entities are present in the list of suggestions.
-
-    Nota bene: in some circumstances this histogram is double counting on
-    purpose. Scenarios cover repetitive actions that expose same entity
-    suggestions, ie. leave-enter-leave application, or leave-enter-clear where
-    no new suggestion fetches are done.
-
-    This histogram is related to Omnibox.SuggestionUsed.RichEntity.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SaveStateForTabSwitch.UserInputInProgress"
-    units="count" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 for M-78.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    When a user switches tabs, whether the omnibox had an edit in progress.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SearchEngine" enum="OmniboxSearchEngine"
-    expires_after="2014-02-28">
-  <obsolete>
-    Made obsolete around Chrome 32. Use Omnibox.SearchEngineType instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The id of search engine that was used for search in omnibox. See
-    src/chrome/browser/search_engines/template_url_prepopulate_data.cc for more
-    info.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SearchProvider.AddHistoryResultsTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019 for M-78.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Time it takes to add all the raw history results to the list of matches.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SearchProvider.ConvertResultsTime" units="ms"
-    expires_after="2018-08-09">
-  <obsolete>
-    Deleted in August 2018 in M-70.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Time it takes to convert all the results to matches and add them to a map,
-    to keep the most relevant match for each result.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SearchProvider.GetMostRecentKeywordTermsDefaultProviderTime"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Deleted in August 2018 in M-70.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Time it takes for the omnibox to search the previous query history database
-    for queries that start with the omnibox text.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SuggestionUsed.IconOrFaviconType"
-    enum="SuggestionIconOrFaviconType" expires_after="M83">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>ender@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    Counts how often omnibox suggestions are used, and in the case a regular
-    search / url (not an Answer, Entity or any other specialized) suggestion was
-    selected - records how the suggestion was decorated.
-
-    This histogram is related to Omnibox.IconOrFaviconShown.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SuggestionUsed.NearbyURLCount" units="URLs"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed in M58, replaced with Omnibox.SuggestionUsed.NearbyURLCount.AtFocus
-    and Omnibox.SuggestionUsed.NearbyURLCount.AtMatchCreation.
-  </obsolete>
-  <summary>
-    The number of nearby Physical Web URLs when the user focused the omnibox.
-    Recorded when the user accepts an omnibox suggestion, regardless of whether
-    the suggestion came from PhysicalWebProvider. Capped at 50.
-
-    In M57, the values recorded by this histogram were determined to be bugged.
-    It's believed that it was recording uninitialized values due to a corner
-    case on Android that allows an omnibox suggestion to be selected without
-    first focusing the omnibox. In addition to the new histograms,
-    Omnibox.PhysicalWebProvider.SuggestionUsedWithoutOmniboxFocus was added to
-    detect this case. https://crbug.com/691059
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SuggestionUsed.NearbyURLCount.AtFocus" units="URLs"
-    expires_after="2018-04-17">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    The number of nearby Physical Web URLs when Physical Web Provider was last
-    focused (i.e., the start of the current session). Recorded when the user
-    accepts an omnibox suggestion, regardless of whether the suggestion came
-    from PhysicalWebProvider. Capped at 50.
-
-    Does not record if the omnibox was not focused during the current session.
-    Omnibox.PhysicalWebProvider.SuggestionUsedWithoutOmniboxFocus records true
-    when we hit this case.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SuggestionUsed.NearbyURLCount.AtMatchCreation"
-    units="URLs" expires_after="2018-04-17">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    The number of nearby Physical Web URLs when Physical Web Provider last
-    constructed matches. Recorded when the user accepts an omnibox suggestion,
-    regardless of whether the suggestion came from PhysicalWebProvider. Capped
-    at 50.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.SuggestionUsed.RichEntity" enum="BooleanUsage"
-    expires_after="M84">
-  <obsolete>
-    Removed in August 2020.
-  </obsolete>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>chrome-android-omnibox-team@google.com</owner>
-  <summary>
-    Whether a Rich Entity omnibox suggestion was selected when the user used the
-    omnibox to go somewhere.
-
-    This histogram is related to Omnibox.RichEntityShown.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.Search.Experimental.ForegroundToFirstMeaningfulPaint.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from the page first appearing in the foreground to its
-    first meaningful paint. Only recorded on navigations that use a prerender
-    that is to a search query suggestion selected from the omnibox.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.Search.ForegroundToFirstContentfulPaint.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from the page first appearing in the foreground to its
-    first contentful paint. Only recorded on navigations that use a prerender
-    that is to a search query suggestion selected from the omnibox.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.Search.NavigationToFirstForeground.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from a page being navigated to in prerender to it first
-    showing up in foreground. Only recorded on navigations that used a prerender
-    that was to a search query suggestion selected from the omnibox. This is
-    only recorded on pages that experience a first contentful paint.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.URL.Experimental.ForegroundToFirstMeaningfulPaint.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from the page first appearing in the foreground to its
-    first meaningful paint. Only recorded on navigations that use a prerender
-    that is to a URL suggestion selected from the omnibox.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.URL.ForegroundToFirstContentfulPaint.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from the page first appearing in the foreground to its
-    first contentful paint. Only recorded on navigations that use a prerender
-    that is to a URL suggestion selected from the omnibox.
-  </summary>
-</histogram>
-
-<histogram
-    name="Omnibox.SuggestionUsed.URL.NavigationToFirstForeground.Prerender"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Prerender was retired from the code long ago; this histogram was finally
-    removed in July 2020.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Measures the time from a page being navigated to in prerender to it first
-    showing up in foreground. Only recorded on navigations that used a prerender
-    that was to a URL suggestion selected from the omnibox. This is only
-    recorded on pages that experience a first contentful paint.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Omnibox.TimeUntilFirst" units="ms"
-    expires_after="2020-01-01">
-  <obsolete>
-    Removed as of 12/2019
-  </obsolete>
-  <owner>mdjones@chromium.org</owner>
-  <owner>lzbylut@google.com</owner>
-  <summary>
-    The amount of time that passes in ms between the user focusing the omnibox
-    and performing some action on Android. This is only recorded the first time
-    the user performs this action per omnibox focus event. Other
-    Omnibox.TimeUntilFirst.* events are not recorded past the first event.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.URLNavigationTimeToRedirectToHTTPS" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in 06/2020 for M-85.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>cthomp@chromium.org</owner>
-  <summary>
-    The amount of time, in milliseconds, between the start of a typed URL
-    navigation in the omnibox (the user typing a URL to completion, or selecting
-    a URL from the inline autocomplete or dropdown) and the start of a redirect
-    upgrading the URL to HTTPS. This is only recorded when the upgraded URL is
-    the same except for the scheme and the addition/removal of a
-    &quot;www.&quot; prefix.
-
-    To calculate the percentage of HTTP URL navigations that have been upgraded
-    in this way, divide the count of this histogram by the count for HTTP in
-    Omnibox.URLNavigationScheme.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ZeroSuggest.Eligible.OnFocus"
-    enum="ZeroSuggestEligibleOnFocus" expires_after="M80">
-  <obsolete>
-    Removed 05/2019 because histogram was not recorded in every circumstance.
-    Superseded by Omnibox.ZeroSuggest.Eligible.OnFocusV2.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Whether the user has settings configured so that the current page URL can be
-    sent to the suggest server to request contextual suggestions. For example,
-    this is only supported for users who have Google as their default search
-    engine (unmodified version of Google), have search suggest enabled, are
-    signed-in and syncing without a custom passphrase, and don't have an
-    incognito window open. There are other criteria too. Recorded on focus in
-    the omnibox if there is default search provider and we've constructed a
-    suggest URL.
-
-    Some additional guidelines: if an incognito window is open, all focus events
-    will go into the &quot;generally ineligible&quot; bucket. Likewise, if the
-    current page is a search results page, we don't allow contextual suggestions
-    either so focus events on those pages go in the &quot;generally
-    ineligible&quot; bucket. The difference between &quot;eligible&quot; and
-    &quot;generally eligible but not this time&quot; depends only the properties
-    of the current URL.
-
-    Recorded regardless of whether contextual or non-contextual zero suggest is
-    currently enabled on the user's platform. However, if zero suggest (in all
-    forms) is entirely disabled, the user will be perpetually ineligible.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ZeroSuggest.Eligible.RemoteNoUrl.OnNTP.OnFocus"
-    enum="ZeroSuggestEligibleOnFocusForRemoteNoUrlOnNTP"
-    expires_after="2020-09-01">
-  <obsolete>
-    Removed from code as of M87 / September 2020. This is no longer useful.
-  </obsolete>
-  <owner>ender@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Whether the user is eligible to receive personalized zero suggestions on the
-    NTP. This histogram is updated only when the user focuses the omnibox on the
-    NTP and is emitted only once even if multiple criteria make a user
-    ineligible. Consult the source code to learn more about the precedence of
-    these values.
-
-    This metric is recorded for all contexts (including users non-syncing, in
-    incognito mode, or using different search engines) and targets specifically
-    eligibility in the current situation.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ZeroSuggest.Eligible.RemoteNoUrl.OnNTP.OnProfileOpen"
-    enum="ZeroSuggestEligibleOnFocusForRemoteNoUrlOnNTP"
-    expires_after="2020-09-01">
-  <obsolete>
-    Removed from code as of M87 / September 2020. This is no longer useful.
-  </obsolete>
-  <owner>ender@chromium.org</owner>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <summary>
-    Whether the user is eligible to receive personalized zero suggestions on the
-    NTP. This histogram is updated every time Chrome registers a profile change.
-
-    This metric is recorded for all contexts (including users non-syncing, in
-    incognito mode, or using different search engines) and targets overall
-    profile eligibility to receive zero-prefix query suggestions on a New Tab
-    Page.
-  </summary>
-</histogram>
-
-<histogram name="Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual"
-    units="units" expires_after="M85">
-  <obsolete>
-    Obsolete as of M85. Added back in 2013 (https://crrev.com/23600051), this is
-    no longer useful.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <owner>jdonnelly@chromium.org</owner>
-  <owner>hfung@chromium.org</owner>
-  <summary>
-    The number of most visited suggestions returned when ZeroSuggest would have
-    triggered. The suggestions appear when the user has focused but not modified
-    the omnibox.
-  </summary>
-</histogram>
-
-<histogram name="OmniboxViewViews.SendTabToSelf"
-    enum="SendTabToSelfClickResult" expires_after="M78">
-  <obsolete>
-    Obsolete because of using suffixes.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    Whether the user has clicked the item when it is shown&quot; Logged when the
-    share option is shown in the omnibox context menu&quot;
-  </summary>
-</histogram>
-
-<histogram name="OOBE.NetworkErrorShown.Supervised" enum="NetworkErrorType"
-    expires_after="M85">
-  <obsolete>
-    Obsolete as of M85. Supervised screen has gone so this metric became
-    obsolete.
-  </obsolete>
-  <owner>raleksandrov@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Number of times error screen has appeared during supervised user creation.
-  </summary>
-</histogram>
-
-<histogram name="OOBE.RecommendApps.Fetcher.ResponseSize" units="KB"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed as of 08/27/2020. No longer needed to track size of a response.
-  </obsolete>
-  <owner>raleksandrov@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <owner>chromesky-eng@google.com</owner>
-  <summary>The size of the recommend-apps JSON response.</summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintCache.FetchedHint.TimeToExpiration"
-    units="seconds" expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    The remaining time a fetched hint that was loaded for use has before it
-    expires and is removed from the hint cache store.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintCache.HasHint.AtCommit"
-    enum="BooleanAvailable" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records when the optimization guide hint cache has a hint entry for a URL's
-    host at commit time.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintCache.HasHint.BeforeCommit"
-    enum="BooleanAvailable" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records when the optimization guide hint cache has a hint entry for a URL's
-    host before commit time (e.g., at original navigation time or redirected
-    navigation time).
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintCache.HostMatch.AtCommit"
-    enum="BooleanMatched" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records when the optimization guide hint cache has a loaded hint entry
-    matching a URL's host at commit time. This is recorded regardless of whether
-    an associated preview type is allowed for the navigation or not. If no
-    associated preview type is allowed, the hint will not be loaded from a
-    backing store, so this will only capture matches for in-memory hints.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintCache.PageMatch.AtCommit"
-    enum="BooleanMatched" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records when the optimization guide hint cache has a loaded page hint for a
-    URL at commit time. This is recorded regardless of whether an associated
-    preview type is allowed for the navigation or not. If no associated preview
-    type is allowed, the hint will not be loaded from a backing store, so this
-    will only capture matches for in-memory hints.
-  </summary>
-</histogram>
-
-<histogram
-    name="OptimizationGuide.HintCacheStore.OnLoadHint.FetchedHintExpired"
-    enum="BooleanExpired" expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records that a fetched hint loaded from the store has expired. If expired,
-    the hint is not provided.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.Hints.NavigationHostCoverage.AtCommit"
-    enum="BooleanCovered" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records once per navigation if the host that was navigated to was included
-    in a hints fetch request in the last 7 days, even if no hints were returned,
-    or had a hint served via the Optimization Hints component at commit.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.Hints.NavigationHostCoverage.BeforeCommit"
-    enum="BooleanCovered" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>sophiechang@chromium.org</owner>
-  <owner>mcrouse@chromium.org</owner>
-  <summary>
-    Records once per navigation if the host that was navigated to was included
-    in a hints fetch request in the last 7 days, even if no hints were returned,
-    or had a hint served via the Optimization Hints component before commit.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch"
-    enum="BooleanCovered" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records when hints fetching is enabled whether the HTTPS host being
-    navigated to was included in a hints fetch request and any hints returned
-    have not since expired. Captured at navigation start so it will not include
-    hints fetched based on the current navigation.
-  </summary>
-</histogram>
-
-<histogram
-    name="OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch.AtCommit"
-    enum="BooleanCovered" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records whether the host being navigated to was included in a hints fetch
-    request and any hints returned have not since expired. Captured after a
-    navigation is committed in order to determine if the fetch attempt made at
-    navigation start succeeded or not.
-  </summary>
-</histogram>
-
-<histogram
-    name="OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch.BeforeCommit"
-    enum="BooleanCovered" expires_after="2020-04-30">
-  <obsolete>
-    Obsolete as of 04/2020 since this histogram no longer makes sense with the
-    current request flow.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records whether the host being navigated to was included in a hints fetch
-    request and any hints returned have not since expired. Captured at
-    navigation start so will not include any newly fetched hints for this
-    navigation.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintsFetcher.WasHostCoveredByFetch"
-    enum="Boolean" expires_after="M79">
-  <obsolete>
-    Removed as of 08/2019
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records whether the host being navigated to was included in a hints fetch
-    and any hints returned have not since expired.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.HintsLoadedPercentage" units="%"
-    expires_after="M79">
-  <obsolete>
-    Removed as of 08/2019
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    The percentage (0-100) of hints loaded over all attempted page loads between
-    component updates. Recorded when the OptimizationGuideService receives a
-    component with a new version.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.PredictionModelStore.OnLoadCollided"
-    enum="BooleanLoadCollided" expires_after="M81">
-  <obsolete>
-    Removed as of 01/2020 since it rarely ever happens that there is a load
-    collision.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    For each load of a prediction model from the OptimizationGuideStore, reports
-    whether the load collided with an update being made to the store.
-  </summary>
-</histogram>
-
-<histogram name="OptimizationGuide.PredictionModelVersion"
-    units="version number" expires_after="2020-05-30">
-  <obsolete>
-    Removed as of 05/2020 to in favor of recording the version on update and on
-    load.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>sophiechang@chromium.org</owner>
-  <summary>
-    Records the version of the prediction model being updated and stored in the
-    prediction model store and made available for use. Recorded only if the
-    model is valid and successfully loaded into memory for use.
-  </summary>
-</histogram>
-
-<histogram name="OriginChip.Pressed" units="units" expires_after="2015-02-12">
-  <obsolete>
-    Removed with CL 731423002. OriginChip has been removed.
-  </obsolete>
-  <owner>gbillock@chromium.org</owner>
-  <summary>The number of clicks on the origin chip.</summary>
-</histogram>
-
-<histogram name="OriginTrials.FeatureEnabled" enum="OriginTrialEnableResult"
-    expires_after="2016-07-21">
-  <obsolete>
-    Obsolete as of Chrome 54. Sort of replaced by OriginTrials.ValidationResult.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>iclelland@chromium.org</owner>
-  <summary>
-    Counts the results of origin trial checks to enable experimental features.
-    The result for each feature check is counted at most once per execution
-    context (e.g. page, worker).
-  </summary>
-</histogram>
-
-<histogram name="OriginTrials.FeatureEnabled.MessageGenerated"
-    enum="OriginTrialMessageGeneratedResult" expires_after="2016-07-21">
-  <obsolete>
-    Obsolete as of Chrome 54.
-  </obsolete>
-  <owner>chasej@chromium.org</owner>
-  <owner>iclelland@chromium.org</owner>
-  <summary>
-    Counts how often an error message is generated for each origin trial check
-    to enable an experimental feature.
-  </summary>
-</histogram>
-
-<histogram name="OSCrypt.EncryptionKeyLookupError" units="units"
-    expires_after="M81">
-  <obsolete>
-    Obsolete as of Chrome M81.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Error code returned by SecKeychainFindGenericPassword when the encryption
-    key is retrieved.
-  </summary>
-</histogram>
-
-<histogram name="OSCrypt.EncryptionKeyOverwritingPreventions" units="units"
-    expires_after="2018-11-22">
-  <obsolete>
-    Obsolete as of Chrome 72.
-  </obsolete>
-  <owner>tsabolcec@google.com</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of times that Chrome prevented overwriting the encryption key in
-    a row. This metric is logged once on startup.
-  </summary>
-</histogram>
-
-<histogram name="OSCrypt.FindPasswordAgain" enum="FindPasswordResult"
-    expires_after="M81">
-  <obsolete>
-    Obsolete as of Chrome M81.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Result of the second call to SecKeychainFindGenericPassword when the
-    encryption key was not found but was expected to be there.
-  </summary>
-</histogram>
-
-<histogram name="OSCrypt.GetEncryptionKeyAction" enum="GetEncryptionKeyAction"
-    expires_after="M81">
-  <obsolete>
-    Obsolete as of Chrome M81.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Action taken when retrieving the encryption key from the Keychain. This
-    metric is logged once on startup.
-  </summary>
-</histogram>
-
-<histogram name="OSX.BluetoothAvailability" enum="BluetoothAvailability"
-    expires_after="2018-08-30">
-  <obsolete>
-    Obsolete as of Chrome 73. This has been replaced by Bluetooth.Availability.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The availability and capabilities of the Bluetooth driver on OSX devices.
-    This metric is logged on startup.
-  </summary>
-</histogram>
-
-<histogram name="OSX.CatSixtyFour" enum="CatSixtyFour"
-    expires_after="2015-03-25">
-  <obsolete>
-    Obsolete as of Chrome 43. See OmahaProxy for more relevant statistics.
-  </obsolete>
-  <owner>mark@chromium.org</owner>
-  <summary>The cat's flavor and how many bits there are in it.</summary>
-</histogram>
-
-<histogram name="OSX.FastUserSwitch" enum="OSXFastUserSwitchEvent"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>Records the Fast User Switching events that occur.</summary>
-</histogram>
-
-<histogram name="OSX.Fullscreen.Enter" enum="OSXFullscreenParameters"
-    expires_after="2014-10-27">
-  <obsolete>
-    Removed as of Chrome 40. See OSX.Fullscreen.Enter.Style,
-    OSX.Fullscreen.Enter.WindowLocation and
-    OSX.Settings.ScreensHaveSeparateSpaces.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    This event is recorded each time a user triggers fullscreen for a browser
-    window. The value's bits reflect different parameters. Bit 0: Fullscreen
-    entry mechanism (AppKit vs Immersive). Bit 1: Whether the window was on the
-    primary screen (Primary vs. Secondary). Bit 2: Whether displays have
-    separate spaces options is enabled (Seperate vs Shared). Bit 3: Whether
-    there are multiple screens.
-  </summary>
-</histogram>
-
-<histogram name="OSX.Fullscreen.ToolbarStyle" enum="OSXFullscreenToolbarStyle"
-    expires_after="2018-11-19">
-  <obsolete>
-    Removed as of 11/2018.
-  </obsolete>
-  <owner>spqchan@chromium.org</owner>
-  <summary>
-    This event is recorded each time a user triggers fullscreen and when the
-    fullscreen toolbar is updated with a new style.
-  </summary>
-</histogram>
-
-<histogram name="OSX.InstallationFilesystem" enum="OSXFilesystem"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>Records the filesystem type that the app lives on.</summary>
-</histogram>
-
-<histogram name="OSX.KeychainReauthorizeIfNeeded" units="count"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020 August.
-  </obsolete>
-  <owner>kerrnel@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    The number of previous times that the keychain reauthorization did not
-    complete, when run during the main browser launch.
-  </summary>
-</histogram>
-
-<histogram name="OSX.KeychainReauthorizeIfNeededAtUpdate" units="count"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020 August.
-  </obsolete>
-  <owner>kerrnel@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    The number of previous times that the keychain reauthorization did not
-    complete, when run at update time.
-  </summary>
-</histogram>
-
-<histogram name="OSX.KeychainReauthorizeIfNeededAtUpdateSuccess" units="count"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020 August.
-  </obsolete>
-  <owner>kerrnel@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    How many times the keychain reauthorization ran before finally succeeding,
-    when run at update time.
-  </summary>
-</histogram>
-
-<histogram name="OSX.KeychainReauthorizeIfNeededSuccess" units="count"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020 August.
-  </obsolete>
-  <owner>kerrnel@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    How many times the keychain reauthorization ran before finally succeeding,
-    when run during the main browser launch.
-  </summary>
-</histogram>
-
-<histogram base="true" name="OSX.OtherInstances" units="units"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    Records how many other instances of this binary are running at startup.
-  </summary>
-</histogram>
-
-<histogram name="OSX.OtherInstancesCheckResult"
-    enum="OSXOtherInstancesCheckResult" expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    The result of the update process's check for other instances of Chrome.
-  </summary>
-</histogram>
-
-<histogram name="OSX.RendererHost.SurfaceWaitTime" units="ms"
-    expires_after="2015-11-24">
-  <obsolete>
-    Removed as of 11/2015.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    This event records the amount of time that the browser process main thread
-    blocks, waiting for a frame with the right dimensions to arrive from the gpu
-    process.
-  </summary>
-</histogram>
-
-<histogram name="OSX.SharedMemory.Mechanism" enum="OSXSharedMemoryMechanism"
-    expires_after="2016-03-24">
-  <obsolete>
-    Removed as of Chrome 51 since Mach has become the default mechanism.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    A histogram entry is emitted each time a base::SharedMemory object is
-    constructed. The value of the entry indicates the mechanism used to back the
-    shared memory region.
-  </summary>
-</histogram>
-
-<histogram name="OSX.StagingDirectoryLocation" enum="OSXStagingDirectoryStep"
-    expires_after="2019-02-16">
-  <obsolete>
-    Removed as of 02/2019 in favor of StagingDirectoryLocation2.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>Records first staging directory location that works.</summary>
-</histogram>
-
-<histogram name="OSX.StagingDirectoryLocation2" enum="OSXStagingDirectoryStep"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    Records, during Chrome startup, the first staging directory location that
-    works. This is for the change to the updating system.
-  </summary>
-</histogram>
-
-<histogram name="OSX.StartupUpdateState" enum="OSXStartupUpdateState"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed 2020 January.
-  </obsolete>
-  <owner>avi@chromium.org</owner>
-  <owner>rsesek@chromium.org</owner>
-  <owner>mark@chromium.org</owner>
-  <summary>
-    Records, during Chrome startup, the state of any staged updates.
-  </summary>
-</histogram>
-
-<histogram name="OutOfProcessHeapProfiling.ProfiledProcess.Type"
-    enum="HeapProfilingProcessType" expires_after="M77">
-  <obsolete>
-    Replaced with HeapProfiling.ProfiledProcess.Type.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    One metric is emitted every 24-hours after Chrome is launched for every
-    process that is being profiled. The timer is reset if Chrome exits.
-  </summary>
-</histogram>
-
-<histogram name="OutOfProcessHeapProfiling.ProfilingMode"
-    enum="HeapProfilingMode" expires_after="M77">
-  <obsolete>
-    Replaced with HeapProfiling.ProfilingMode.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    One metric is emitted every 24-hours after Chrome is launched for every
-    Chrome instance that is using out of process heap profiling. The timer is
-    reset if Chrome exits.
-  </summary>
-</histogram>
-
-<histogram name="OutOfProcessHeapProfiling.RecordTrace.Success"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Replaced with HeapProfiling.RecordTrace.Success.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The metric is emitted each time Chrome attempts to record a memory-infra
-    trace to upload an out-of-process heap-profiling memory dump.
-  </summary>
-</histogram>
-
-<histogram name="OutOfProcessHeapProfiling.UploadTrace.Size" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Replaced with HeapProfiling.UploadTrace.Size.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The metric is emitted each time Chrome uploads a trace. It reflects the
-    uncompressed size of the trace.
-  </summary>
-</histogram>
-
-<histogram name="OutOfProcessHeapProfiling.UploadTrace.Success"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Replaced with HeapProfiling.UploadTrace.Success.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The metric is emitted each time Chrome uploads a trace. It reflects whether
-    the upload was successful.
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Cancelled" enum="NavigationDirection"
-    expires_after="2017-03-02">
-  <obsolete>
-    Removed as of Chrome 59 in favour of Overscroll.Cancelled3.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Overscroll gestures that were aborted before they were completed.
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Completed" enum="OverscrollMode"
-    expires_after="2015-04-14">
-  <obsolete>
-    Removed as of Chrome 44 in favour of Overscroll.Cancelled and
-    Overscroll.Navigated2.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>mfomitchev@chromium.org</owner>
-  <summary>
-    Completed overscroll gestures.
-
-    An overscroll gesture starts when user scrolls past the edge of the web page
-    and continues scrolling in the same direction. An overscroll gesture is
-    completed when user stops scrolling (e.g. by lifting the fingers from the
-    touchscreen or touchpad).
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Navigated" enum="OverscrollMode"
-    expires_after="2015-04-14">
-  <obsolete>
-    Removed as of Chrome 44 to switch to NavigationDirection enum.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>mfomitchev@chromium.org</owner>
-  <summary>
-    Navigations that were triggered due to completed overscroll gesture. Note
-    that not all completed overscroll gestures trigger a navigation.
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Navigated2" enum="NavigationDirection"
-    expires_after="2017-03-02">
-  <obsolete>
-    Removed as of Chrome 59 in favour of Overscroll.Navigated3.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>mfomitchev@chromium.org</owner>
-  <summary>
-    Navigations that were triggered due to completed overscroll gesture. Note
-    that not all completed overscroll gestures trigger a navigation.
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Started" enum="OverscrollMode"
-    expires_after="2015-04-14">
-  <obsolete>
-    Removed as of Chrome 44 to switch to NavigationDirection enum.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>mfomitchev@chromium.org</owner>
-  <summary>
-    Overscroll gestures initiated by the user. Note that not all overcroll
-    gestures started are completed (e.g. the overscroll gesture is aborted if
-    user clicks or presses a key during the gesture).
-  </summary>
-</histogram>
-
-<histogram name="Overscroll.Started2" enum="NavigationDirection"
-    expires_after="2017-03-02">
-  <obsolete>
-    Removed as of Chrome 59 in favour of Overscroll.Started3.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <owner>mfomitchev@chromium.org</owner>
-  <summary>
-    Overscroll gestures initiated by the user. Note that not all overscroll
-    gestures started are completed (e.g. the overscroll gesture is aborted if
-    user clicks or presses a key during the gesture).
-  </summary>
-</histogram>
-
-<histogram name="Ozone.TouchNoiseFilter.FarApartTapDistance"
-    units="squared pixels" expires_after="M85">
-  <obsolete>
-    Removed Nov 2019
-  </obsolete>
-  <owner>pkotwicz@google.com</owner>
-  <summary>
-    The squared distance between taps which occur in quick succession. Only
-    reported when the taps are far apart and touch noise filtering is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Ozone.TouchNoiseFilter.HorizontallyAlignedDistance"
-    units="pixels" expires_after="M85">
-  <obsolete>
-    Removed Nov 2019
-  </obsolete>
-  <owner>pkotwicz@google.com</owner>
-  <summary>
-    The horizontal distance from a &quot;touch press&quot; to the closest other
-    touch. Only reported if there are two or more fingers onscreen and touch
-    noise filtering is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Ozone.TouchNoiseFilter.TimeSinceLastNoiseOccurrence"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed Nov 2019
-  </obsolete>
-  <owner>pkotwicz@google.com</owner>
-  <summary>
-    The amount of time between noisy touches. The amount of time since Chrome
-    startup is recorded for the first noisy touch after startup.
-  </summary>
-</histogram>
-
-<histogram name="Ozone.TouchNoiseFilter.TouchesAtSinglePositionDuration"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed Nov 2019
-  </obsolete>
-  <owner>pkotwicz@google.com</owner>
-  <summary>
-    The time between taps which occur in quick succession at the same screen
-    location. Only reported when touch noise filtering is enabled.
-  </summary>
-</histogram>
-
-<histogram name="PageImportanceSignals.HadFormInteraction.OnCommitLoad"
-    enum="HadFormInteraction" expires_after="M77">
-  <obsolete>
-    Removed In June 2019.
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Number of pages that had any HTML form interaction before next page load.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.Background" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted due to being backgrounded.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.ClientRedirect" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a client side redirect (Javascript navigation).
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.Close" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by the user closing the tab or browser.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.ForwardBackNavigation"
-    units="ms" expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a forward or back navigation.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.NewNavigation" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a new navigation.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.Other" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted. The abort cause is unknown.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.Reload" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a reload.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.AbortTiming.Stop" units="ms"
-    expires_after="2016-12-01">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.AbortTiming equivalent.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by the user pressing stop.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.AbortTiming.UnknownNavigation" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    We now have sufficient infrastructure to always characterize aborts that
-    resulted in new navigations.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a navigation with unknown transition type.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PageLoad.AdPaintTiming.NavigationToFirstContentfulPaint" units="ms"
-    expires_after="2020-07-31">
-  <obsolete>
-    Removed 07/2020. Replaced with
-    PageLoad.Clients.Ads.AdPaintTiming.NavigationToFirstContentfulPaint2; see
-    http://crbug.com/1103782.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Records the time from frame navigation start to FirstContentfulPaint of each
-    ad frame that receives a FirstContentfulPaint. The time could be quite
-    large, as some ads don't paint until they're scrolled into view. But the
-    metric is still useful in aggregate.
-
-    Recorded for all ad frames with non-zero bytes or cpu usage that receive a
-    FirstContentfulPaint. Recorded when the ad frame or page is destroyed.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.Aggregate.Network" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Network.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of the resources loaded for all of the ad frames on the
-    page that loaded over the network.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.Aggregate.PercentNetwork" units="%"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.PercentNetwork.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The percentage of bytes loaded for all ad frames that were loaded over the
-    network.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.Aggregate.Total" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.Aggregate.Total.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of the resources loaded for all of the ad frames on the
-    page.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.PerFrame.Network" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Network.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of the resources loaded for an ad frame from the network.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.PerFrame.PercentNetwork" units="%"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.PercentNetwork.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The percentage of bytes loaded for a single ad frame that were loaded over
-    the network.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.AdFrames.PerFrame.Total" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.AdFrames.PerFrame.Total.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of the resources loaded for an ad frame.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.FullPage.Network" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with PageLoad.Clients.Ads.Bytes.FullPage.Network.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of all of the page's resources that loaded over the
-    network.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.FullPage.Network.PercentAds" units="%"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.FullPage.Network.PercentAds.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The percentage of bytes loaded for the page (from the network) that came
-    from resource loads in ad frames (from the network).
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.FullPage.Total" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with PageLoad.Clients.Ads.Bytes.FullPage.Total.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of all of the page's resources.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.FullPage.Total.PercentAds" units="%"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.FullPage.Total.PercentAds.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The percentage of bytes loaded for the page that came from resource loads in
-    ad frames.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Bytes.NonAdFrames.Aggregate.Total" units="KB"
-    expires_after="2019-01-17">
-  <obsolete>
-    Removed 01/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.NonAdFrames.Aggregate.Total.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The size (in KB) of all of the page's resources except for those loaded in
-    ad frames.
-
-    Only recorded if the page has at least one identified ad frame. Bytes are
-    measured as over-the-wire (e.g., compressed) response body KBs and do not
-    include header bytes. An ad frame consists of the identified ad frame and
-    all of its children (which may also be ads, but are counted as part of the
-    ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd"
-    enum="DidNavigateToAd" expires_after="2018-07-13">
-  <obsolete>
-    Removed In July 2018, metric was buggy for subresource filter ads.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    When a frame that is (or previously was) an ad frame renavigates, record
-    whether it renavigated to an ad frame or a non-ad frame.
-
-    An ad frame consists of the identified ad frame and all of its children. Its
-    children (which may also be ads) are not counted when they renavigate.
-
-    This metric is recorded as the event happens. Note that this is unlike most
-    other Clients.Ads metrics, which are recorded when the page load is
-    complete.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.All.Navigations.NonAdFrameRenavigatedToAd"
-    enum="DidNavigateToAd" expires_after="M80">
-  <obsolete>
-    Removed In July 2018.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    When a frame that has never been part of an ad frame renavigates, record
-    whether it renavigated to an ad frame or a non-ad frame.
-
-    This metric is recorded as the event happens. Note that this is unlike most
-    other Clients.Ads metrics, which are recorded when the page load is
-    complete.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.All.ParentExistsForSubFrame"
-    enum="ParentFrameKnown" expires_after="2018-09-21">
-  <obsolete>
-    Removed in September 2018.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records whether or not a parent frame is found for a subframe that finishes
-    navigating.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound"
-    enum="ContentResourceType2" expires_after="2018-09-20">
-  <obsolete>
-    Removed in September 2018. At time of deprecation: Subframe 80%, Script
-    6.5%, Images 10%, and XHR was 3%.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records the content::ResourceType when a resource finishes loading but the
-    ads metrics aren't aware of a committed frame for the resource.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame.Visibility"
-    enum="AdFrameVisibility" expires_after="2020-01-23">
-  <obsolete>
-    Removed 01/19.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Whether or not the ad frame had a display: none style set, meaning it was
-    not visible to the user. Only recorded for ad frames with non-zero total
-    bytes. Recorded when the page is destroyed or navigated.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.Google.FrameCounts.MainFrameParent.AdFrames"
-    units="Frames" expires_after="M80">
-  <obsolete>
-    Removed In May 2017.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of frames (with parent frame of main frame) that are on the page
-    identified as Google Ad Frames.
-
-    Only recorded if the page has at least one identified ad frame. Child frames
-    of an ad frame are not included in the count.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.Google.FrameCounts.MainFrameParent.PercentAdFrames"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed In May 2017.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The percentage of frames (with parent frame of main frame) on the page that
-    are identified as Google Ad Frames.
-
-    Only recorded if the page has at least one identified ad frame. An ad frame
-    consists of the identified ad frame and all of its children (which may also
-    be ads, but are counted as part of the ancestor ad frame).
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.Google.FrameCounts.MainFrameParent.TotalFrames"
-    units="Frames" expires_after="M80">
-  <obsolete>
-    Removed In May 2017.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of frames (with parent frame of main frame) on the page.
-
-    Only recorded if the page has at least one identified ad frame.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.Google.Navigations.AdFrameRenavigatedToAd"
-    enum="DidNavigateToAd" expires_after="M80">
-  <obsolete>
-    Removed In July 2017. Use
-    PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd instead.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    When a frame that is (or previously was) an ad frame renavigates, record
-    whether it renavigated to an ad frame or a non-ad frame.
-
-    An ad frame consists of the identified ad frame and all of its children. Its
-    children (which may also be ads) are not counted when they renavigate.
-
-    This metric is recorded as the event happens. Note that this is unlike most
-    other Clients.Ads metrics, which are recorded when the page load is
-    complete.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd"
-    enum="DidNavigateToAd" expires_after="M80">
-  <obsolete>
-    Removed In July 2017. Use
-    PageLoad.Clients.Ads.All.Navigations.NonAdFrameRenavigatedToAd instead.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    When a frame that has never been part of an ad frame renavigates, record
-    whether it renavigated to an ad frame or a non-ad frame.
-
-    This metric is recorded as the event happens. Note that this is unlike most
-    other Clients.Ads metrics, which are recorded when the page load is
-    complete.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Google.ParentExistsForSubFrame"
-    enum="ParentFrameKnown" expires_after="2017-07-14">
-  <obsolete>
-    Removed In July 2017. Use PageLoad.Clients.Ads.All.ParentExistsForSubFrame
-    instead.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records whether or not a parent frame is found for a subframe that finishes
-    navigating.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound"
-    enum="ContentResourceType2" expires_after="2017-07-14">
-  <obsolete>
-    Removed In July 2017. Use
-    PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound instead.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records the content::ResourceType when a resource finishes loading but the
-    ads metrics aren't aware of a committed frame for the resource.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Resources.Bytes.Ads" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed March 2019 in favor of PageLoad.Clients.Ads.Resources.Bytes.Ads2.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Total number of network bytes that went towards loading ad resources for a
-    single page over it's entire lifetime. This includes resources that did not
-    finish or were canceled. Only recorded for pages with non-zero ad bytes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Resources.Bytes.TopLevelAds" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 02/2019. Replaced with
-    PageLoad.Clients.Ads.Bytes.MainFrame.Ads.Network.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Total number of network bytes that were used to load top-level ad resources
-    on the page. This includes resources that did not finish or were canceled.
-    Only recorded for pages with non-zero ad bytes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Resources.Bytes.Total" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 01/19. Replaced with PageLoad.Clients.Ads.Bytes.FullPage.Network.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Total number of network bytes that were used to load resources on the page.
-    This includes resources that did not finish loading or were canceled. Only
-    recorded for pages with non-zero ad bytes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.Ads.Resources.Bytes.Unfinished" units="KB"
-    expires_after="2019-09-05">
-  <obsolete>
-    Removed 04/2019 in favor of PageLoad.Experimental.Bytes.Unfinished.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    Total number of network bytes that were used to load resources that did not
-    finish loading on the page (e.g. ongoing video). This includes resource
-    loads that were canceled or resource loads that were ongoing when the page
-    was destroyed. Only recorded for pages with non-zero ad bytes.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe"
-    units="scorex10" expires_after="2019-09-10">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.Clients.AMP.LayoutInstability.CumulativeShiftScore.Subframe
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>skobes@chromium.org</owner>
-  <summary>
-    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
-    during the session, in the AMP subframe. Recorded for same-document
-    navigations.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe.FullNavigation"
-    units="scorex10" expires_after="2019-09-10">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.Clients.AMP.LayoutInstability.CumulativeShiftScore.Subframe.FullNavigation
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>skobes@chromium.org</owner>
-  <summary>
-    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
-    during the session, in the AMP subframe. Recorded for non-same-document
-    navigations.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed July 2019 in favor of FirstInputDelay4.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation, in an AMP subframe document. Recorded on first page
-    interaction. See https://goo.gl/tr1oTZ for a detailed explanation. Excludes
-    scrolls. Only same-document navigations are included.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe.FullNavigation"
-    units="ms" expires_after="M78">
-  <obsolete>
-    Removed July 2019 in favor of FirstInputDelay4.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation, in an AMP subframe document. Recorded on first page
-    interaction. See https://goo.gl/tr1oTZ for a detailed explanation. Excludes
-    scrolls. Only non-same-document navigations are included.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.PaintTiming.InputToLargestContentPaint.Subframe"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The time from user input to largest &quot;contentful&quot; paint in an AMP
-    subframe document. Only same-document navigations are included.
-
-    Excludes any content painted after user input. The value is recorded at the
-    end of each page load unless there is an abort or user input before text or
-    image paint. See http://bit.ly/fcp_plus_plus for details.
-
-    Will be zero or near-zero in cases where the AMP subframe document was
-    prerendered.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.AMP.PaintTiming.InputToLargestContentPaint.Subframe.FullNavigation"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 7/2019.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The time from user input to largest &quot;contentful&quot; paint in an AMP
-    subframe document. Only non-same-document navigations are included.
-
-    Excludes any content painted after user input. The value is recorded at the
-    end of each page load unless there is an abort or user input before text or
-    image paint. See http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.AMP.SameDocumentView"
-    enum="PageLoadMetricsAMPViewType" expires_after="M77">
-  <obsolete>
-    Removed 5/2019
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>Count of same document page views for AMP pages.</summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.CompressionRatio"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    100 times the ratio of network bytes received to network bytes the user
-    would have seen without data reduction proxy (not including headers) in a
-    page load that had its main resource loaded through data reduction proxy.
-    Recorded as a percent if the data reduction proxy saved the user data.
-    Recorded per page load when the user navigates away, hides the tab, or
-    backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.CompressionRatio2"
-    units="%" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    100 times the ratio of network bytes received to network bytes the user
-    would have seen without data reduction proxy (not including headers) in a
-    page load that had its main resource loaded through data reduction proxy.
-    Recorded as a percent if the data reduction proxy saved the user data.
-    Recorded per page load when the user navigates away, hides the tab, or
-    backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Inflation"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the data
-    reduction proxy inflated for the user in a page load that had its main
-    resource was loaded through data reduction proxy. Recorded per page load
-    when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Inflation2"
-    units="KB" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the data
-    reduction proxy inflated for the user in a page load that had its main
-    resource was loaded through data reduction proxy. Recorded per page load
-    when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.InflationPercent"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The inflation in network kilobytes (not including headers) the user saw due
-    to using data reduction proxy in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded as a percent when the user saw
-    inflated data. Recorded per page load when the user navigates away, hides
-    the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.InflationPercent2"
-    units="%" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The inflation in network kilobytes (not including headers) the user saw due
-    to using data reduction proxy in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded as a percent when the user saw
-    inflated data. Recorded per page load when the user navigates away, hides
-    the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.NonProxied"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes that were not fetched through the data
-    reduction proxy (not including headers) in a page load that had its main
-    resource was loaded through data reduction proxy. Recorded per page load
-    when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.NonProxied2"
-    units="KB" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes that were not fetched through the data
-    reduction proxy (not including headers) in a page load that had its main
-    resource was loaded through data reduction proxy. Recorded per page load
-    when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Original"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the user would
-    have seen without using data reduction proxy in a page load that had its
-    main resource was loaded through data reduction proxy. Recorded per page
-    load when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Original2"
-    units="KB" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the user would
-    have seen without using data reduction proxy in a page load that had its
-    main resource was loaded through data reduction proxy. Recorded per page
-    load when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.PercentProxied"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The percent of network kilobytes (not including headers) in a page load that
-    went through data reduction proxy when the main resource was loaded through
-    data reduction proxy. Recorded per page load when the user navigates away,
-    hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.PercentProxied2"
-    units="%" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The percent of network kilobytes (not including headers) in a page load that
-    went through data reduction proxy when the main resource was loaded through
-    data reduction proxy. Recorded per page load when the user navigates away,
-    hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Proxied"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes that were fetched through the data reduction
-    proxy (not including headers) in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded per page load when the user
-    navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Proxied2"
-    units="KB" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes that were fetched through the data reduction
-    proxy (not including headers) in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded per page load when the user
-    navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Savings"
-    units="KB" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the data
-    reduction proxy saved the user in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded per page load when the user
-    navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.Bytes.Network.Savings2"
-    units="KB" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that the data
-    reduction proxy saved the user in a page load that had its main resource was
-    loaded through data reduction proxy. Recorded per page load when the user
-    navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.CompletedResources.Network.PercentProxied"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed 10/2018
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The percent of completed resources loaded from network in a page load that
-    use data reduction proxy when the main resource was loaded through data
-    reduction proxy. Recorded per page load when the user navigates away, hides
-    the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.DataReductionProxy.Experimental.CompletedResources.Network2"
-    units="%" expires_after="M84">
-  <obsolete>
-    Removed 05/2020
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Records info about the completed resources loaded from network in a page
-    load that use data reduction proxy when the main resource was loaded through
-    data reduction proxy. Recorded per page load when the user navigates away,
-    hides the tab, or backgrounds the app. The number of proxies, non-proxied,
-    percent of proxied are recorded as suffixes.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.DelayNavigation.Delay.Actual" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The actual delay added to page loads by DelayNavigationThrottle, for page
-    loads that started in the foreground and reached first paint in the
-    foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.DelayNavigation.Delay.Delta" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The absolute delta between the specified and actual delays added to main
-    frame navigations by DelayNavigationThrottle, for page loads that started in
-    the foreground and reached first paint in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.DelayNavigation.Delay.Specified" units="ms"
-    expires_after="2018-03-08">
-  <obsolete>
-    Removed March 2018
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The specified delay added to main frame navigations by
-    DelayNavigationThrottle, for page loads that started in the foreground and
-    reached first paint in the foreground.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.FontPreload.LayoutInstability.CumulativeShiftScore"
-    units="scorex10" expires_after="2020-08-31">
-  <obsolete>
-    Removed in August 2020 as the behavior is launched
-  </obsolete>
-  <owner>xiaochengh@chromium.org</owner>
-  <owner>rendering-core-dev@chromium.org</owner>
-  <summary>
-    This metrics measures PageLoad.LayoutInstability.CumulativeShiftScore when
-    the first rendering cycle has been delayed in favor of font preloading
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.FontPreload.PaintTiming.NavigationToLargestImagePaint"
-    units="ms" expires_after="2020-08-31">
-  <obsolete>
-    Removed in August 2020 as the behavior is launched
-  </obsolete>
-  <owner>xiaochengh@chromium.org</owner>
-  <owner>rendering-core-dev@chromium.org</owner>
-  <summary>
-    This metrics measures
-    PageLoad.Experimental.PaintTiming.NavigationToLargestImagePaint when the
-    first rendering cycle has been delayed in favor of font preloading
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.FontPreload.PaintTiming.NavigationToLargestTextPaint"
-    units="ms" expires_after="2020-08-31">
-  <obsolete>
-    Removed in August 2020 as the behavior is launched
-  </obsolete>
-  <owner>xiaochengh@chromium.org</owner>
-  <owner>rendering-core-dev@chromium.org</owner>
-  <summary>
-    This metrics measures
-    PageLoad.Experimental.PaintTiming.NavigationToLargestTextPaint when the
-    first rendering cycle has been delayed in favor of font preloading
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.GoogleCaptcha.Events"
-    enum="GoogleCaptchaEvent" expires_after="2018-05-02">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>mdw@chromium.org</owner>
-  <summary>Events related to Google CAPTCHA pages being seen by users.</summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.LoFi.Experimental.Bytes.Network.LoFi"
-    units="KB" expires_after="M77">
-  <obsolete>
-    Functionality removed in M77.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network kilobytes (not including headers) that LoFi resources
-    used in a page load that had at least one LoFi resource. Recorded per page
-    load when the user navigates away, hides the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.LoFi.Experimental.CompletedResources.Network.LoFi"
-    units="KB" expires_after="M78">
-  <obsolete>
-    Functionality removed in M77.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of network LoFi resources in a page load that had at least one
-    LoFi resource. Recorded per page load when the user navigates away, hides
-    the tab, or backgrounds the app.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.MultiTabLoading.NumTabsWithInflightLoad"
-    units="tabs" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Records the number of tabs with inflight loading activities. Recorded when a
-    new page load starts.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ServiceWorker.PageTransition"
-    enum="CorePageTransition" expires_after="2018-06-26">
-  <obsolete>
-    Removed June 2018 (M69) in favor of
-    PageLoad.Clients.ServiceWorker2.PageTransition.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The core transition type for main frame page loads controlled by a service
-    worker.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.SubresourceFilter.ActivationDecision"
-    enum="SubresourceFilterActivationDecision" expires_after="2018-05-18">
-  <obsolete>
-    Removed May 2018 (M68) in favor of
-    SubresourceFilter.PageLoad.ActivationDecision
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Records the policy decision to activate subresource filtering for a page
-    load. 'Activated' indicates that subresource filtering was activated. All
-    other reasons indicate that subresource filtering was not activated. Page
-    loads where subresource filtering was activated ('Activated') and at least
-    one subresource matched the subresource filter are counted in
-    PageLoad.Clients.SubresourceFilter.Count.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.SubresourceFilter.Count" enum="Boolean"
-    expires_after="2018-05-18">
-  <obsolete>
-    Removed May 2018 (M68) in favor of
-    SubresourceFilter.PageLoad.NumSubresourceLoads.MatchedRules (e.g. by looking
-    at 0 and non-zero buckets).
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Records 'true' for page loads where the subresource filter matched a
-    subresource loaded by the page. Includes dryrun matches. To compute the
-    percentage of total page loads affected by subresource filtering, divide by
-    the sum of counts for (PageLoad.ParseTiming.NavigationToParseStart +
-    PageLoad.ParseTiming.NavigationToParseStart.Background).
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.ThirdParty.Frames.NavigationToFirstContentfulPaint"
-    units="ms" expires_after="2021-11-01">
-  <obsolete>
-    Removed in 12/2019.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    The time from navigation start to the first contentful paint of third-party
-    frames on pages. Note that this can be significantly delayed due to lazy
-    loading.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Clients.ThirdParty.Frames.NavigationToFirstContentfulPaint2"
-    units="ms" expires_after="2020-12-04">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>johnidel@chromium.org</owner>
-  <summary>
-    The time from navigation start to the first contentful paint of third-party
-    (third party in respect to eTLD+1) frames on pages. Note that this can be
-    significantly delayed due to lazy loading.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.CookieRead" units="Count"
-    expires_after="2021-07-01">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that read cookies either via
-    resource request headers or document.cookie.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.CookieWrite" units="Count"
-    expires_after="2021-07-01">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that changed cookies either via
-    resource response headers or document.cookie.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.LocalStorageAccess"
-    units="Count" expires_after="2021-07-01">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that access local storage via
-    window.localStorage.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.Read" units="Count"
-    expires_after="2021-07-01">
-  <obsolete>
-    Renamed to PageLoad.Clients.ThirdParty.Origins.CookieRead.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that read cookies either via
-    resource request headers or document.cookie.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.SessionStorageAccess"
-    units="Count" expires_after="2021-07-01">
-  <obsolete>
-    Removed in 01/2020.
-  </obsolete>
-  <owner>yaoxia@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that access session storage via
-    window.sessionStorage.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Clients.ThirdParty.Origins.Write" units="Count"
-    expires_after="2021-07-01">
-  <obsolete>
-    Renamed to PageLoad.Clients.ThirdParty.Origins.CookieWrite.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of third party origins on a page that changed cookies either via
-    resource response headers or document.cookie.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.CSSTiming.Parse.BeforeFirstContentfulPaint"
-    units="ms" expires_after="2018-05-30">
-  <obsolete>
-    Removed in May 2018 (M69).
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time spent parsing author style sheets before the first contentful
-    paint.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.CSSTiming.ParseAndUpdate.BeforeFirstContentfulPaint"
-    units="ms" expires_after="2018-05-30">
-  <obsolete>
-    Removed in May 2018 (M69).
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The sum of CSSTiming.Update and CSSTiming.Parse variants for this page load.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.CSSTiming.Update.BeforeFirstContentfulPaint"
-    units="ms" expires_after="2018-05-30">
-  <obsolete>
-    Removed in May 2018 (M69).
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time spent in Document::updateStyle before the first contentful paint.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.DocumentTiming.NavigationToFirstLayout" units="ms"
-    expires_after="2020-07-26">
-  <obsolete>
-    Removed 12/2019. Use NavigationToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first layout is performed, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.EventCounts" enum="PageLoadEvent"
-    expires_after="2015-10-19">
-  <obsolete>
-    deprecated in favor of PageLoad.Events.*
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Captures counts of various page load events. These are enumerated in the
-    enum page_load_metrics::PageLoadEvent, and include events like 'page load
-    aborted before first layout'
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Events.Committed" enum="CommittedLoadEvent"
-    expires_after="2015-12-24">
-  <obsolete>
-    Removed in favor of PageLoad.Timing2.NavigationToCommit and
-    PageLoad.AbortTiming.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Captures counts of load events post-commit, on relevant page loads (i.e.
-    http/https, not same-page, not an error page). These events include aborts
-    before first layout and successful first layouts. Note that the event
-    'Committed load started' when segmented by background/foreground specifies
-    whether the eventually committed load started in the background or
-    foreground, not whether we backgrounded before the actual commit event. This
-    is because we don't have all the data to filter relevant page loads on
-    provisional loads.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Events.InternalError" enum="InternalErrorLoadEvent"
-    expires_after="2016-07-27">
-  <obsolete>
-    Removed in favor of PageLoad.Internal.ErrorCode.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Counts of various internal error conditions in the page_load_metrics system.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Events.Provisional" enum="ProvisionalLoadEvent"
-    expires_after="2016-02-08">
-  <obsolete>
-    Removed Feb 2016 in favor of PageLoad.AbortTiming and
-    PageLoad.Timing2.NavigationToFailedProvisionalLoad. Note that the
-    corresponding background enumerations are no longer being tracked in the
-    timing histograms.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Captures counts of provisional load events. These include aborted, failed,
-    and successful (committed) provisional loads.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.Experimental.AbortTiming.ClientRedirect"
-    units="ms" expires_after="2017-02-22">
-  <obsolete>
-    Removed in favor of PageLoad.Internal.ClientRedirect.*.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    This metric is still experimental and not yet ready to be relied upon.
-    Measures the time from navigation start to the time the page load was
-    aborted by a client side redirect (Javascript navigation).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.Bytes.Cache" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.Bytes.Cache2.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of prefiltered (e.g., compressed) response body KiloBytes loaded
-    from the cache via the browser process for a page load. Recorded when the
-    page load is terminated. Only recorded for complete resources.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.Bytes.Total" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.Bytes.Total2.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of prefiltered (e.g., compressed) response body KiloBytes loaded
-    via the browser process for a page load. Does not include any header or
-    overhead bytes. Recorded when the page load is terminated. Only recorded for
-    complete resources.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.Cache.RequestPercent.ParseStop"
-    units="%" expires_after="2018-01-17">
-  <obsolete>
-    Removed Jan 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The percent of resources loaded from cache for the given page load. Recorded
-    at the end of HTML parsing.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.Cache.TotalRequests.ParseStop"
-    units="requests" expires_after="2018-01-17">
-  <obsolete>
-    Removed Jan 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of resources a given page finished loading from cache at parse
-    stop.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.CompletedResources.Cache"
-    units="resources" expires_after="M77">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.CompletedResources.Cache2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of completed resources loaded from the cache via the browser
-    process for a page load. Recorded when the page load is terminated.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.CompletedResources.Total"
-    units="resources" expires_after="M80">
-  <obsolete>
-    Removed in favor of PageLoad.Experimental.CompletedResources.Total2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The total number of completed resources loaded via the browser process for a
-    page load. Recorded when the page load is terminated.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.LayoutStability.JankScore"
-    units="scorex10" expires_after="M80">
-  <obsolete>
-    Removed 7/2019, replaced by PageLoad.LayoutInstability.CumulativeShiftScore
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>skobes@chromium.org</owner>
-  <summary>
-    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
-    on the page (including all subframes) during the session.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.LayoutStability.JankScore.MainFrame"
-    units="scorex10" expires_after="2019-09-10">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>skobes@chromium.org</owner>
-  <summary>
-    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
-    in the main frame during the session.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.NavigationToInteractive" units="ms"
-    expires_after="2020-07-26">
-  <obsolete>
-    Removed 1/2020.
-  </obsolete>
-  <owner>dproy@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Measures Time to Interactive, a metric based on main thread and network
-    heuristics to approximate the point in time when the page feels interactive
-    to the user. See https://goo.gl/TFw6xz for detailed explanation. This
-    histogram uses First Meaningful Paint as the lower bound for quiescent
-    windows.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PageTiming.FirstPaintToFirstBackground"
-    units="ms" expires_after="2017-02-28">
-  <obsolete>
-    Removed in favor of PageLoad.PageTiming.ForegroundDuration.AfterPaint.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the total time the page load was active after first paint, up until
-    being backgrounded, prior to the page load terminating. Recorded only for
-    page loads that started in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PageTiming.FirstPaintToPageEnd"
-    units="ms" expires_after="2017-02-28">
-  <obsolete>
-    Removed in favor of PageLoad.PageTiming.ForegroundDuration.AfterPaint.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the total time the page load was active after first paint, for page
-    loads that spend the entire time in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PageTiming.NavigationToFirstBackground"
-    units="ms" expires_after="2017-02-28">
-  <obsolete>
-    Removed in favor of PageLoad.PageTiming.ForegroundDuration.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the total time the page load was active, up until being
-    backgrounded, for page loads that started in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PageTiming.NavigationToPageEnd"
-    units="ms" expires_after="2017-02-28">
-  <obsolete>
-    Removed in favor of PageLoad.PageTiming.ForegroundDuration.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the total time the page load was active, for page loads that spend
-    the entire time in the foreground.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintSignalStatus"
-    enum="FirstMeaningfulPaintSignalStatus" expires_after="M80">
-  <obsolete>
-    Removed in favor of
-    PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintSignalStatus2.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the user had any interaction on the page (except mouse move) after
-    first paint, and whether the user left the page before network stable or
-    not.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintSignalStatus2"
-    enum="FirstMeaningfulPaintSignalStatus" expires_after="M80">
-  <obsolete>
-    Removed as of 05/17/2017.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the user had any interaction on the page (except mouse move) after
-    first paint, and whether the user left the page before network stable or
-    not. Not logged if page load was aborted before first paint.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintToNetworkStable"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed as of 05/17/2017.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Measures the time between when the first meaningful paint
-    (http://bit.ly/ttfmp-doc) was computed to have happened, and when we
-    actually logged the metric.
-
-    This metric is useful in helping us tweak when FirstMeaningfulPaintDetector
-    should stop observing layout operations.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.ForegroundToFirstMeaningfulPaint"
-    units="ms" expires_after="2020-09-27">
-  <obsolete>
-    Removed in Sep 2020.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from a background tab being switched to the foreground to
-    the time the first meaningful paint is performed, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.LargestContentPaint.AllFrames.ContentType"
-    enum="LargestContentType" expires_after="M80">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.PaintTiming.LargestContentfulPaint.ContentType
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>npm@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures whether the largest content paint, whose timestamp is measured by
-    PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaintAllFrames,
-    comes from text or image. This value is recorded whenever
-    PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaintAllFrames
-    is recorded.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.LargestContentPaint.ContentType"
-    enum="LargestContentType" expires_after="M80">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.PaintTiming.LargestContentfulPaint.MainFrame.ContentType
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>npm@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures whether the largest content paint, whose timestamp is measured by
-    PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaint, comes
-    from text or image. This value is recorded whenever
-    PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaint is
-    recorded.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaint"
-    units="ms" expires_after="2020-01-20">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.PaintTiming.NavigationToLargestContentfulPaint.MainFrame
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    largest content (text or image) is first painted, for main frame documents.
-    Excludes any content painted after user input. The value is recorded at the
-    end of each page load unless there is an abort or user input before text or
-    image paint. See http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.NavigationToLargestContentPaint.AllFrames"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 7/2019, replaced by
-    PageLoad.PaintTiming.NavigationToLargestContentfulPaint
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    largest content (text or image) is first painted, for main frame documents.
-    Excludes any content painted after user input. The value is recorded at the
-    end of each page load unless there is an abort or user input before text or
-    image paint. Compared with NavigationToLargestContentPaint, this is the
-    aggregate results from all frames, while NavigationToLargestContentPaint is
-    only for main frame. See http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.NavigationToLargestImagePaint"
-    units="ms" expires_after="2020-04-23">
-  <obsolete>
-    Removed Mar 2020 in favor of
-    PageLoad.PaintTiming.NavigationToLargestContentfulPaint.
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    largest image is first painted after fully loaded, for main frame documents.
-    The value is recorded at the end of each page load. See
-    http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.PaintTiming.NavigationToLargestTextPaint"
-    units="ms" expires_after="2020-07-26">
-  <obsolete>
-    Removed Mar 2020 in favor of
-    PageLoad.PaintTiming.NavigationToLargestContentfulPaint.
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    largest text is first painted, for main frame documents. The value is
-    recorded at the end of each page load. See http://bit.ly/fcp_plus_plus for
-    details.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PaintTiming.NavigationToLastImagePaint"
-    units="ms" expires_after="2019-04-23">
-  <obsolete>
-    Removed Mar 2019
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    last image is first painted after fully loaded, for main frame documents.
-    The value is recorded at the end of each page load. See
-    http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.PaintTiming.NavigationToLastTextPaint"
-    units="ms" expires_after="2019-04-23">
-  <obsolete>
-    Removed Mar 2019
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    last text is first painted, for main frame documents. The value is recorded
-    at the end of each page load. The value is recorded at the end of each page
-    load. See http://bit.ly/fcp_plus_plus for details.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.ParseDuration.CachedPercent.0-50"
-    units="ms" expires_after="2018-01-17">
-  <obsolete>
-    Removed Jan 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The parse duration of the page load where 0-50% of all subresources (loaded
-    during parsing) were served from the HTTP cache (including 304s).
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.ParseDuration.CachedPercent.51-100"
-    units="ms" expires_after="2018-01-17">
-  <obsolete>
-    Removed Jan 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The parse duration of the page load where 51-100% of all subresources
-    (loaded during parsing) were served from the HTTP cache (including 304s).
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.Renderer.FirstMeaningfulPaintDetector.FirstMeaningfulPaintOrdering"
-    enum="FirstMeaningfulPaintOrdering" expires_after="M80">
-  <obsolete>
-    Renamed to
-    PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.FirstMeaningfulPaintOrdering
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the two variants of First Meaningful Paint reported different
-    values, and if so, which one was reported first.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Experimental.Renderer.FirstMeaningfulPaintDetector.HadNetworkQuiet"
-    enum="NetworkQuietStatus" expires_after="M80">
-  <obsolete>
-    Renamed to
-    PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.HadNetworkQuiet
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Recorded when the page load reached network 0-quiet (no active network
-    connection for 0.5 seconds), or network 2-quiet (no more than 2 active
-    network connections for 2 seconds).
-    PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintSignalStatus2
-    histogram gives the fraction of page loads that had network 2-quiet, so it
-    can be used as a baseline.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.TimeToInteractiveStatus"
-    enum="TimeToInteractiveStatus" expires_after="2020-07-26">
-  <obsolete>
-    Removed 1/2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>dproy@chromium.org</owner>
-  <summary>
-    Records whether the Time To Interactive metric was reported for the page
-    load, or why it wasn't if not. See https://goo.gl/TFw6xz for definition of
-    Time to Interactive.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Experimental.TotalRequests.ParseStop"
-    units="requests" expires_after="2018-01-17">
-  <obsolete>
-    Removed Jan 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of resources a given page finished loading at parse stop.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.FrameCounts.AdFrames.PerFrame.CrossOrigin"
-    enum="CrossOriginAd" expires_after="2018-04-30">
-  <obsolete>
-    Removed April 2018, replaced by OriginStatus.
-  </obsolete>
-  <owner>ericrobinson@chromium.org</owner>
-  <summary>
-    For each identified ad frame, whether the origin of the ad matches the
-    origin of the main frame.
-
-    An ad frame consists of the identified ad frame and all of its children
-    (which may also be ads, but are counted as part of the ancestor ad frame).
-    Frames of zero bytes (e.g., never had a document or their document was
-    doc.written and no sub-resources were loaded) are not counted.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PageLoad.FrameCounts.AdFrames.PerFrame.SizeIntervention"
-    enum="AdFrameSizeInterventionStatus" expires_after="2020-01-29">
-  <obsolete>
-    Removed July 2019 in Issue 962616.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Whether or not the ad frame would have triggered the Adframe size
-    intervention. This is determined by checking if a frame does not have a user
-    gesture when its size exceeds 1050 kilobytes. Only recorded for ad frames
-    with non-zero total bytes. Recorded for each frame when the page is
-    destroyed or navigated.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PageLoad.FrameCounts.AdFrames.PerFrame.SizeIntervention.MediaStatus"
-    enum="AdFrameMediaStatus" expires_after="2020-02-22">
-  <obsolete>
-    Removed July 2019 in Issue 962616.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Whether or not the ad frame that would have triggered the Adframe size
-    intervention had media playing at any point in its lifetime. An adframe will
-    trigger the intervention if it does not have a user gesture when its size
-    exceeds 1050 kilobytes. Recorded for each offending frame when the page is
-    destroyed or navigated.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PageLoad.FrameCounts.AdFrames.PerFrame.SmallestDimension"
-    units="pixels" expires_after="2020-01-30">
-  <obsolete>
-    Removed 01/2020. Available in UKM via AdFrameLoad.Visibility.FrameHeight and
-    AdFrameLoad.Visibility.FrameWidth.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The smallest dimension of a root ad frame in pixels. Only recorded for ad
-    frames with non-zero total bytes. Recorded when the page is destroyed or
-    navigated. Display none iframes will not always update their size because
-    they lack a content view. This uses the last size of frame before it was set
-    to display: none.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PageLoad.FrameCounts.AdFrames.PerFrame.SqrtNumberOfPixels"
-    units="pixels" expires_after="2021-01-30">
-  <obsolete>
-    Removed 10/20.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The square root of the area of a root adframe in pixels. Only recorded for
-    ad frames with non-zero total bytes. Recorded when the page is destroyed or
-    navigated. Display none iframes will not always update their size because
-    they lack a content view. This uses the last size of frame before it was set
-    to display: none.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.FrameCounts.AnyParentFrame.AdFrames"
-    units="Ad frames" expires_after="M80">
-  <obsolete>
-    Removed 09/2019 in favor of PageLoad.FrameCounts.AdFrames.Total.
-  </obsolete>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    The number of frames on the page that have loaded more than 0 bytes of
-    content.
-
-    For pages with zero ad frames, the other PageLoad.Clients.Ads metrics are
-    not recorded unless otherwise specified.
-
-    Child frames of an ad frame are not included in the count.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.HeavyAds.ComputedType"
-    enum="HeavyAdStatus" expires_after="2020-08-05">
-  <obsolete>
-    Removed 09/2018 in favor of PageLoad.HeavyAds.ComputedType2.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records heavy ad type for each ad frame, as determined by the first
-    threshold hit (see FrameData::HeavyadStatus). This is recorded regardless of
-    feature flag or other conditions that prevent the heavy ad intervention from
-    occuring. Recored for all ad frames with non-zero bytes. Recorded when the
-    ad frame destroyed or when the page is destroyed.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PageLoad.HeavyAds.InterventionType"
-    enum="HeavyAdStatus" expires_after="2020-08-05">
-  <obsolete>
-    Removed 09/2018 in favor of PageLoad.HeavyAds.InterventionType2.
-  </obsolete>
-  <owner>johnidel@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records the type of heavy ad unloaded by the heavy ad intervention. Heavy ad
-    type is determined by the first threshold hit. This is not recorded for ad
-    frames that are considered heavy but did not fufill other criteria for the
-    intervention. This includes the feature being enabled and being below the
-    per-origin intervention cap.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputDelay" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of
-    PageLoad.InteractiveTiming.FirstInputDelay2 which correctly excludes some
-    scrolling cases that were previously not excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation. See https://goo.gl/tr1oTZ for a detailed explanation.
-    In ms.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.InteractiveTiming.FirstInputDelay.SkipFilteringComparison"
-    units="ms" expires_after="2020-02-23">
-  <obsolete>
-    Removed January 2020 as the SkipTouchFilter experiment is completed.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    This metric will be used to compare first inputs during the
-    SkipTouchEventFilter experiment.
-
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation. Recorded on first page interaction. See
-    https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputDelay2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of
-    PageLoad.InteractiveTiming.FirstInputDelay3 which brings the metric more in
-    line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation. Recorded on first page interaction. See
-    https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputDelay3" units="ms"
-    expires_after="2020-05-24">
-  <obsolete>
-    Removed in July 2019 in favor of PageLoad.InteractiveTiming.FirstInputDelay4
-    which includes input events which were filtered previously.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures First Input Delay, the duration between the hardware timestamp and
-    the start of event processing on the main thread for the first meaningful
-    input per navigation. Recorded on first page interaction. See
-    https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputTimestamp" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of
-    PageLoad.InteractiveTiming.FirstInputTimestamp2 which correctly excludes
-    some scrolling cases that were previously not excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    first meaningful input per navigation. See https://goo.gl/tr1oTZ for a
-    detailed explanation. In ms.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.InteractiveTiming.FirstInputTimestamp.SkipFilteringComparison"
-    units="ms" expires_after="2020-02-23">
-  <obsolete>
-    Removed January 2020 as the SkipTouchFilter experiment is completed.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    This metric will be used to compare first inputs during the
-    SkipTouchEventFilter experiment.
-
-    The duration between navigation start and the hardware timestamp of the
-    first meaningful input per navigation. Recorded on first page interaction.
-    See https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputTimestamp2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of
-    PageLoad.InteractiveTiming.FirstInputTimestamp3 which brings the metric more
-    in line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    first meaningful input per navigation. Recorded on first page interaction.
-    See https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.FirstInputTimestamp3" units="ms"
-    expires_after="2020-05-24">
-  <obsolete>
-    Removed in July 2019 in favor of
-    PageLoad.InteractiveTiming.FirstInputTimestamp4 which includes input events
-    which were filtered previously.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    first meaningful input per navigation. Recorded on first page interaction.
-    See https://goo.gl/tr1oTZ for a detailed explanation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.InputDelay" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of PageLoad.InteractiveTiming.InputDelay2
-    which correctly excludes some scrolling cases that were previously not
-    excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between the hardware timestamp and the start of event
-    processing on the main thread for a meaningful input. In ms.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.InputDelay2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of PageLoad.InteractiveTiming.InputDelay3
-    which brings the metric more in line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between the hardware timestamp and the start of event
-    processing on the main thread for a meaningful input. Excludes scrolls.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.InputTimestamp" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of
-    PageLoad.InteractiveTiming.InputTimestamp2 which correctly excludes some
-    scrolling cases that were previously not excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of a
-    meaningful input. In ms.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.InputTimestamp2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of
-    PageLoad.InteractiveTiming.InputTimestamp3 which brings the metric more in
-    line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of a
-    meaningful input. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputDelay" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of
-    PageLoad.InteractiveTiming.LongestInputDelay2 which correctly excludes some
-    scrolling cases that were previously not excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Measures longest Input Delay, the longest duration between the hardware
-    timestamp and the start of event processing on the main thread for the
-    meaningful input per navigation. In ms.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputDelay2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of
-    PageLoad.InteractiveTiming.LongestInputDelay3 which brings the metric more
-    in line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures longest Input Delay, the longest duration between the hardware
-    timestamp and the start of event processing on the main thread for the
-    meaningful input per navigation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputDelay3" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed in October 2019 in favor of LongestInputDelay4, which updates naming
-    to be consistent with LongestInput UKM.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures longest Input Delay, the longest duration between the hardware
-    timestamp and the start of event processing on the main thread for the
-    meaningful input per navigation. Excludes scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputTimestamp" units="ms"
-    expires_after="2019-01-23">
-  <obsolete>
-    Removed on January 2019 in favor of
-    PageLoad.InteractiveTiming.LongestInputTimestamp2 which correctly excludes
-    some scrolling cases that were previously not excluded from this metric.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    meaningful input with longest queuing delay per navigation. In ms.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputTimestamp2" units="ms"
-    expires_after="2020-01-23">
-  <obsolete>
-    Removed on February 2019 in favor of
-    PageLoad.InteractiveTiming.LongestInputTimestamp3 which brings the metric
-    more in line with the EventTiming API.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    meaningful input with longest queuing delay per navigation. Excludes
-    scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.InteractiveTiming.LongestInputTimestamp3" units="ms"
-    expires_after="2020-02-23">
-  <obsolete>
-    Removed in October 2019 in favor of LongestInputTimestamp4, which updates
-    naming to be consistend with LongestInput UKMs.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The duration between navigation start and the hardware timestamp of the
-    meaningful input with longest queuing delay per navigation. Excludes
-    scrolls.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Internal.ClientRedirectDelayAfterPaint" units="ms"
-    expires_after="2016-07-18">
-  <obsolete>
-    Removed in favor of PageLoad.Internal.ClientRedirect.FirstPaintToNavigation
-    and PageLoad.Internal.ClientRedirect.NavigationWithoutPaint.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The delay between first paint and a client-side redirection. This metric is
-    only intended to help in choosing a heuristic delay to distinguish between
-    client-side redirects and other client initiated navigations, and will be
-    deprecated in M54. Please contact bmcquade@chromium.org before using this
-    metric.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Internal.CommitToComplete.NoTimingIPCs" units="ms"
-    expires_after="2016-10-17">
-  <obsolete>
-    Removed on 10/14/2016. No longer needed.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    The delay between commit and completion, for page loads that did not receive
-    any timing IPCs. This metric is only intended to help understand the cases
-    where committed page loads don't receive timing IPCs. Please contact
-    bmcquade@chromium.org before using this metric.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Internal.InteractiveToInteractiveDetection"
-    units="ms" expires_after="M77">
-  <obsolete>
-    Removed 1/2020.
-  </obsolete>
-  <owner>dproy@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Measures time delta between Time to Interactive and when we can detect TTI.
-    TTI cannot be detected in real time - we have to wait sufficiently long to
-    determine main thread and network quiescence. See https://goo.gl/TFw6xz for
-    detailed explanation of Time to Interactive. This histogram uses First
-    Meaningful Paint as the lower bound for quiescent windows.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Internal.PaintTiming.HadUserInputBeforeFirstMeaningfulPaint"
-    enum="HadUserInput" expires_after="M78">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the user had any interaction on the page before
-    FirstMeaningfulPaint. Recorded when the page load reaches network idle.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.FirstMeaningfulPaintOrdering"
-    enum="FirstMeaningfulPaintOrdering" expires_after="M78">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the two variants of First Meaningful Paint reported different
-    values, and if so, which one was reported first.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.HadNetworkQuiet"
-    enum="NetworkQuietStatus" expires_after="M78">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Recorded when the page load reached network 0-quiet (no active network
-    connection for 0.5 seconds), or network 2-quiet (no more than 2 active
-    network connections for 2 seconds).
-    PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintSignalStatus2
-    histogram gives the fraction of page loads that had network 2-quiet, so it
-    can be used as a baseline.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Internal.Renderer.PaintTiming.SwapTimeDelta"
-    units="ms" expires_after="2018-05-18">
-  <obsolete>
-    deprecated May 2018: The swap-timestamp comes from a different process, and
-    comparing that with the paint-time (which is from the local process) does
-    not produce a reliable metric.
-  </obsolete>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    Records the delta between the renderer timestamp and swap timestamp for
-    first paint, first contentful paint, first meaningful paint, first text
-    paint, and first image paint. The renderer timestamp is recorded on the
-    Paint path, while the swap timestamp is the result of a CC SwapPromise
-    (queued on the Paint path) either being successfully fulfilled, or broken in
-    cases where the swap did not occur. As we switch to using the swap
-    timestamps in place of their renderer counterparts, this metric allows us to
-    see the discrepancies between the two timestamps.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.LayoutInstability.CumulativeShiftScore.AfterBackForwardCache"
-    units="scorex10" expires_after="2021-06-30">
-  <obsolete>
-    Removed in 07/2020 due to misspelling. Use
-    PageLoad.LayoutInstability.CumulativeShiftScore.AfterBackForwardCacheRestore
-    instead.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>bfcache-dev@chromium.org</owner>
-  <summary>
-    Measures the cumulative layout shift score (bit.ly/3fQz29y) that has
-    occurred on the page (including all subframes) after the page is restored
-    from the back-forward cache. Recorded when the user navigates away or closes
-    the page after the page was restored from back-forward cache.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame.AfterBackForwardCache"
-    units="scorex10" expires_after="2021-06-30">
-  <obsolete>
-    Removed in 07/2020 due to misspelling. Use
-    PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame.AfterBackForwardCacheRestore
-    instead.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>bfcache-dev@chromium.org</owner>
-  <summary>
-    Measures the cumulative layout shift score (bit.ly/3fQz29y) that has
-    occurred in the main frame after the page is restored from the back-forward
-    cache. Recorded when the user navigates away or closes the page after the
-    page was restored from back-forward cache.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.PaintTiming.NavigationToFirstTextPaint" units="ms"
-    expires_after="2018-12-05">
-  <obsolete>
-    Discontinued Nov 2018 because data is no longer being used.
-  </obsolete>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first non-blank text is painted, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing.NavigationToDOMContentLoadedEventFired"
-    units="ms" expires_after="2015-09-30">
-  <obsolete>
-    deprecated in favor of PageLoad.Timing2.*
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    DOMContentLoaded event is fired, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing.NavigationToFirstLayout" units="ms"
-    expires_after="2015-09-30">
-  <obsolete>
-    deprecated in favor of PageLoad.Timing2.*
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first layout is performed, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing.NavigationToLoadEventFired" units="ms"
-    expires_after="2015-09-30">
-  <obsolete>
-    deprecated in favor of PageLoad.Timing2.*
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    load event is fired, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.DOMLoadingToDOMContentLoadedEventFired"
-    units="ms" expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.DocumentTiming.ParseDuration
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from when DOM loading occurs (the time that HTML parsing
-    begins) to the time the DOMContentLoaded event is fired, for main frame
-    documents. This is equivalent to the time that the HTML document resource
-    was being parsed.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.DOMLoadingToFirstContentfulPaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.ParseStartToFirstContentfulPaint
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from when DOM loading occurs (the time that HTML parsing
-    begins) to first &quot;contentful&quot; paint.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ForegroundToFirstPaint" units="ms"
-    expires_after="2016-07-27">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.ForegroundToFirstPaint
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Measures the time from a background tab being switched to the foreground to
-    the time the first paint is performed, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToCommit" units="ms"
-    expires_after="2016-10-17">
-  <obsolete>
-    Removed in favor of PageLoad.ParseTiming.NavigationToParseStart
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    navigation committed, for main frame documents.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToDOMContentLoadedEventFired"
-    units="ms" expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of
-    PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    DOMContentLoaded event is fired, for main frame documents. This metric is
-    being phased out in favor of the PageLoad.DocumentTiming equivalent and will
-    be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFailedProvisionalLoad" units="ms"
-    expires_after="2017-02-22">
-  <obsolete>
-    deprecated in favor of PageLoad.PageTiming.NavigationToFailedProvisionalLoad
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>shivanisha@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    provisional load failed. Only measures provisional loads that failed in the
-    foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstBackground" units="ms"
-    expires_after="2016-10-14">
-  <obsolete>
-    deprecated in favor of PageLoad.AbortTiming.Background.*
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    user first backgrounds the tab. Only measures navigations that started in
-    the foreground.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstContentfulPaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.NavigationToFirstContentfulPaint
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time from navigation start to first &quot;contentful&quot; paint. This
-    metric is being phased out in favor of the PageLoad.PaintTiming equivalent
-    and will be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstForeground" units="ms"
-    expires_after="2017-02-22">
-  <obsolete>
-    deprecated in favor of PageLoad.PageTiming.NavigationToFirstForeground
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    user first foregrounds an initially backgrounded tab. Only measures
-    navigations that started in the background.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstImagePaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.NavigationToFirstImagePaint
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first image is painted, for main frame documents. For images that render
-    progressively, this is recorded as soon as any image pixels have been drawn.
-    This metric is being phased out in favor of the PageLoad.PaintTiming
-    equivalent and will be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstLayout" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.DocumentTiming.NavigationToFirstLayout
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first layout is performed, for main frame documents. This metric is being
-    phased out in favor of the PageLoad.DocumentTiming equivalent and will be
-    deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstPaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.NavigationToFirstPaint
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first paint is performed, for main frame documents. This metric is being
-    phased out in favor of the PageLoad.PaintTiming equivalent and will be
-    deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToFirstTextPaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.NavigationToFirstTextPaint
-  </obsolete>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first non-blank text is painted, for main frame documents. This metric is
-    being phased out in favor of the PageLoad.PaintTiming equivalent and will be
-    deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.NavigationToLoadEventFired" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.DocumentTiming.NavigationToLoadEventFired
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    load event is fired, for main frame documents. This metric is being phased
-    out in favor of the PageLoad.DocumentTiming equivalent and will be
-    deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ParseBlockedOnScriptLoad" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.ParseTiming.ParseBlockedOnScriptLoad
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time that the HTML parser spent blocked on the load of scripts,
-    for main frame documents that started parsing.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ParseBlockedOnScriptLoad.ParseComplete"
-    units="ms" expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.ParseTiming.ParseBlockedOnScriptLoad
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time that the HTML parser spent blocked on the load of scripts,
-    for main frame documents that finished parsing. This metric is being phased
-    out in favor of the PageLoad.ParseTiming equivalent and will be deprecated
-    in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite"
-    units="ms" expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of
-    PageLoad.ParseTiming.ParseBlockedOnScriptLoadFromDocumentWrite
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time that the HTML parser spent blocked on the load of scripts
-    inserted from document.write, for main frame documents that started parsing.
-  </summary>
-</histogram>
-
-<histogram
-    name="PageLoad.Timing2.ParseBlockedOnScriptLoadFromDocumentWrite.ParseComplete"
-    units="ms" expires_after="M80">
-  <obsolete>
-    deprecated in favor of
-    PageLoad.ParseTiming.ParseBlockedOnScriptLoadFromDocumentWrite
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time that the HTML parser spent blocked on the load of scripts
-    inserted from document.write, for main frame documents that finished
-    parsing. This metric is being phased out in favor of the
-    PageLoad.ParseTiming equivalent and will be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ParseDuration" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.ParseTiming.ParseDuration
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time that the HTML parser was active, for main frame documents
-    that finished parsing. This metric is being phased out in favor of the
-    PageLoad.ParseTiming equivalent and will be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageLoad.Timing2.ParseStartToFirstContentfulPaint" units="ms"
-    expires_after="2016-09-26">
-  <obsolete>
-    deprecated in favor of PageLoad.PaintTiming.ParseStartToFirstContentfulPaint
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from when the HTML parser started, to when the page first
-    paints content. This metric is being phased out in favor of the
-    PageLoad.PaintTiming equivalent and will be deprecated in M54.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.MhtmlGeneration.PopupOverlaySkipped"
-    enum="BooleanSkipped" expires_after="2018-08-30">
-  <obsolete>
-    Removed 6/2019. No longer used.
-  </obsolete>
-  <owner>jianli@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Recorded when the popup overlays are removed from MHTML serialization.
-  </summary>
-</histogram>
-
-<histogram name="PaintHolding.CommitTrigger" enum="PaintHoldingCommitTrigger"
-    expires_after="M80">
-  <obsolete>
-    Replaced by PaintHolding.CommitTrigger2 in M-79
-  </obsolete>
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records the reason that a commit was triggered, to enable research into
-    which event (non-same-origin, FCP, timeout, etc) led to the first commit.
-  </summary>
-</histogram>
-
-<histogram name="PaintHolding.InputTiming" enum="PaintHoldingInputTiming"
-    expires_after="M80">
-  <obsolete>
-    Replaced with PaintHolding.InputTiming2 in M-79.
-  </obsolete>
-  <owner>schenney@chromium.org</owner>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    Records whether or not input arrived before the first commit.
-  </summary>
-</histogram>
-
-<histogram name="Parser.AppendBytesDelay" units="ms" expires_after="2017-08-12">
-  <obsolete>
-    Removed Aug 2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The delay from when bytes are received on the main thread to when the
-    BackgroundHTMLParser starts tokenizing them. Always a shorter time than the
-    time emitted to Parser.PreloadTokenizeDelay.
-  </summary>
-</histogram>
-
-<histogram name="Parser.ChunkEnqueueTime" units="ms" expires_after="2017-05-03">
-  <obsolete>
-    Removed May 2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time it takes to enqueue a ParsedChunk onto the shared parser queue.
-  </summary>
-</histogram>
-
-<histogram name="Parser.DiscardedTokenCount" units="tokens"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed Feb 2020
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of speculative tokens discarded by the parser when a rewind is
-    needed.
-  </summary>
-</histogram>
-
-<histogram name="Parser.PeakPendingChunkCount" units="chunks"
-    expires_after="2017-08-12">
-  <obsolete>
-    Removed Aug 2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The maximum number of pending Chunks in the ParsedChunkQueue after the
-    parser is detached.
-  </summary>
-</histogram>
-
-<histogram name="Parser.PeakPendingTokenCount" units="tokens"
-    expires_after="2017-08-12">
-  <obsolete>
-    Removed Aug 2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The maximum number of pending tokens in the ParsedChunkQueue after the
-    parser is detached.
-  </summary>
-</histogram>
-
-<histogram name="Parser.PreloadTokenizeDelay" units="ms"
-    expires_after="2017-05-03">
-  <obsolete>
-    Removed May 2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The delay from when bytes are received on the main thread to when they are
-    tokenized and preloads are sent back to the main parser. Always a greater
-    time than the time emitted to Parser.AppendBytesDelay.
-  </summary>
-</histogram>
-
-<histogram name="PartitionAlloc.CommittedSize" units="MB" expires_after="M77">
-  <obsolete>
-    Removed as of 07/2019. Use Memory.Renderer.* and
-    Memory.Experimental.Renderer2.* instead.
-  </obsolete>
-  <owner>haraken@chromium.org</owner>
-  <summary>
-    The committed memory size in PartitionAlloc. The value is reported when we
-    see the highest memory usage we've ever seen in the renderer process.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmark.Count" units="bookmarks"
-    expires_after="2017-12-15">
-  <obsolete>
-    Removed 2017-12 by PartnerBookmark.Count2.
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    The number of partner bookmark entries. Note that zero would be
-    under-represented because reading is throttled if the last result is zero.
-    Logged when using the bookmark, not skipped (PartnerBookmark.Skipped ==
-    False), and at most once per cold start. Note that the distribution is
-    weighted by bookmark usage.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmark.Null" enum="BooleanNull"
-    expires_after="2018-04-13">
-  <obsolete>
-    No longer recorded as of Apr 2018
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    Whether there's no partner bookmark provider. By default, the system image
-    contains a dummy partner bookmarks provider that provides zero entries.
-    Logged when using the bookmark, not skipped (PartnerBookmark.Skipped ==
-    False), and at most once per cold start.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmark.Skipped" enum="BooleanSkipped"
-    expires_after="2018-04-13">
-  <obsolete>
-    No longer recorded as of Apr 2018
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    Whether reading of partner bookmark is skipped. Logged when using the
-    bookmark, and at most once per cold start.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmark.TimeSinceLastEmptyRead" units="ms"
-    expires_after="2017-12-19">
-  <obsolete>
-    Removed 2017-12. Use PartnerBookmark.TimeSinceLastEmptyRead2.
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    When trying to load the partner bookmarks, if no partner bookmark is read
-    last time, record the time elapsed since then. It is recorded no matter
-    whether loading would be skipped.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmark.TimeSinceLastEmptyRead2" units="seconds"
-    expires_after="2018-04-13">
-  <obsolete>
-    No longer recorded as of Apr 2018
-  </obsolete>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    When trying to load the partner bookmarks, if no partner bookmark is read
-    last time, record the time elapsed since then. It is recorded no matter
-    whether loading would be skipped.
-  </summary>
-</histogram>
-
-<histogram name="PartnerBookmarksFaviconThrottle.NumEntries" units="entries"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-07. See crbug.com/975263 for wrap-up analysis.
-  </obsolete>
-  <owner>tedchoc@chromium.org</owner>
-  <owner>wychen@chromium.org</owner>
-  <summary>
-    Number of elements read from the partner bookmarks favicon cache, recorded
-    once per cold start when reading partner bookmarks. Only recorded on
-    Android.
-  </summary>
-</histogram>
-
-<histogram name="PasswordGeneration.PresaveConflict"
-    enum="PasswordGenerationPresaveConflict" expires_after="M83">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Records whether there is a username conflict with existing credentials when
-    the user clicks 'Generate Password'.
-  </summary>
-</histogram>
-
-<histogram name="PasswordGeneration.UserEvent"
-    enum="PasswordGenerationUserEvent" expires_after="2018-10-19">
-  <obsolete>
-    Removed 10/2018 in favor of PasswordGeneration.UserDecision.
-  </obsolete>
-  <owner>ioanap@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records user-triggered events related to a generated password. Each event is
-    logged at most once per lifetime of the generated password.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AboutBlankPasswordSubmission"
-    enum="BooleanMainFrame" expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>battre@chromium.org</owner>
-  <summary>
-    Records attempts to submit a password on a form in an about:blank frame,
-    indicating whether this attempt is for a main frame or subframe. Recorded
-    once per form submission.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountChooserDialog"
-    enum="AccountChooserDismissalReason" expires_after="2016-11-15">
-  <obsolete>
-    Removed as of Chrome 56. See the histograms for one and more accounts.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>The dismissal reason of the account chooser.</summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountChooserDialogAccounts" units="accounts"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>The number of accounts displayed in the account chooser.</summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountChooserDialogEmptyAvatars"
-    units="avatars" expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The count of the placeholder avatars shown in the account chooser.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountChooserDialogUsability"
-    enum="AccountChooserUsabilityState" expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Whether the account chooser includes an empty username or any duplicates
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountsPerSite" units="units"
-    expires_after="M79">
-  <obsolete>
-    Removed in M79 in favor of PasswordManager.AccountsPerSiteHiRes.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of accounts stored per site in the password manager (one event
-    per site)
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AccountsReusingPassword" units="accounts"
-    expires_after="M81">
-  <obsolete>
-    Removed 2020/02 because it's unused.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>engedy@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records, for each account, the number of other accounts (across all sites
-    and usernames) that reuse the same password. Only non-blacklisted,
-    HTML-form-based accounts are considered.
-
-    For each account, samples will only be recorded into the histograms that
-    have the first suffix corresponding to whether that account was saved on a
-    secure website or not. The second suffix is used to further categorize the
-    other accounts that reuse the same password based on how they relate to the
-    account in question, and whether they are secure. The number of other
-    accounts in each category will be reported into histogram with the
-    respective second suffixes.
-
-    Metrics are collected once per browser start-up. In case of multiple
-    profiles, the counts are for the profile for which a WebContents is first
-    created.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ActionsTaken"
-    enum="PasswordManagerActionsTaken" expires_after="2013-10-04">
-  <obsolete>
-    Removed as of Chrome 32. See PasswordManagerActionsTakenWithPsl
-  </obsolete>
-  <summary>
-    Stats documenting how we handle every form containing a password, bucketed
-    by the actions taken.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ActionsTakenOnNonSecureForm"
-    enum="PasswordManagerActionsTakenV3" expires_after="2020-03-22">
-  <obsolete>
-    Removed as of 12/10/2019.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Stats documenting how we handle every form containing a password on a
-    non-secure page, bucketed by the actions taken.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ActionsTakenV3"
-    enum="PasswordManagerActionsTakenV3" expires_after="2020-05-24">
-  <obsolete>
-    Removed as of 12/10/2019.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Stats documenting how we handle every form containing a password, bucketed
-    by the actions taken.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ActionsTakenWithPsl"
-    enum="PasswordManagerActionsTakenWithPsl" expires_after="2014-03-24">
-  <obsolete>
-    Removed as of 3/18/2014. See PasswordManagerActionsTakenV3.
-  </obsolete>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Stats documenting how we handle every form containing a password, bucketed
-    by the actions taken.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AffiliationDummyData.RequestResultCount"
-    units="results" expires_after="M80">
-  <obsolete>
-    No longer recorded as of May 2015.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    The number of facets affiliated with a dummy Web facet, according to the
-    affiliation information retrieved from the cache. Recorded for each dummy
-    Web facet, once shortly after start-up, and then periodically every hour;
-    but only if getting affiliations succeeded for the Web facet.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AffiliationDummyData.RequestSuccess"
-    enum="BooleanSuccess" expires_after="M80">
-  <obsolete>
-    No longer recorded as of May 2015.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Whether or not affiliations of a dummy Web facet could be successfully
-    retrieved from the cache. Recorded for each dummy Web facet, once shortly
-    after start-up, and then periodically every hour.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AllowToCollectURLBubble.UIDismissalReason"
-    enum="PasswordManagerAllowToCollectURLBubble.UIDismissalReason"
-    expires_after="2015-02-27">
-  <obsolete>
-    The bubble isn't shown anymore. Become obsolete in Feb. 2015.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>Why was &quot;Allow to collect URL?&quot; bubble closed?</summary>
-</histogram>
-
-<histogram name="PasswordManager.Android.ExportPasswordsProgressBarUsage"
-    enum="PasswordManagerAndroidExportPasswordsProgressBarUsage"
-    expires_after="M77">
-  <obsolete>
-    No longer recorded as of June 2019.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records what happened to the progress bar during exporting passwords when
-    its dismissal was requested.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.Android.PasswordSearchTriggered"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    No longer recorded as of June 2019.
-  </obsolete>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Records whether a user triggered the search function while visiting the
-    password preferences page on Android.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.AutocompletePopupSuppressedByGeneration"
-    enum="BooleanSuppressed" expires_after="2019-02-14">
-  <obsolete>
-    Removed February 2019.
-  </obsolete>
-  <owner>gcasto@chromium.org</owner>
-  <summary>
-    If the password manager UI was suppressed because generation UI was already
-    being displayed for the same field.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BlacklistedDuplicates"
-    units="duplicated forms" expires_after="M73">
-  <obsolete>
-    Corresponding clean-up logic got introduced in M70 and has run its course.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    The number of duplicates forms from the password store. Recorded once for
-    the profile on startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BlacklistedSites" units="units"
-    expires_after="M76">
-  <obsolete>
-    Removed in M76 in favor of PasswordManager.BlacklistedSitesHiRes.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The total number of sites that the user has blacklisted in the password
-    manager's profile-scoped store. Recorded by iterating over stored passwords
-    once per run of Chrome.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BlacklistedSites.NeedNormalization"
-    enum="BooleanNeedsNormalization" expires_after="M80">
-  <obsolete>
-    Corresponding clean-up logic got introduced in M76 and has run its course.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records once on startup whether the blacklisted sites in the password store
-    need to be normalized.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordManager.BlacklistedSites.NeedRemoveBlacklistDuplicates"
-    enum="BooleanNeedsDeDuplication" expires_after="M73">
-  <obsolete>
-    Corresponding clean-up logic got introduced in M70 and has run its course.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records once on startup whether the blacklisted sites in the password store
-    need to be cleared of duplications.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BlacklistedSites.NeedToBeCleaned"
-    enum="BooleanNeedsClearing" expires_after="2018-08-21">
-  <obsolete>
-    Removed August 2018.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records once on startup whether the blacklisted sites in the password store
-    need to be updated to remove username/password. Can be removed around Chrome
-    M69 (https://crbug.com/817754).
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BlacklistedSites.PreventedAddingDuplicates"
-    enum="BooleanAddingBlacklistedDuplicatesPrevented"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed April 2019.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Boolean indicating whether adding a blacklist entry was prevented due to an
-    already existing entry. Recorded after every blacklist site submission.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordManager.BubbleSuppression.AccountsWithSuppressedBubble"
-    units="accounts" expires_after="M86">
-  <obsolete>
-    Removed as of 07/2020.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of accounts that do not trigger password save prompts anymore.
-    The count is recorded once per browser start-up. (In case of multiple
-    profiles, the counts are for the profile that first has a WebContents
-    created.)
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.BubbleSuppression.DomainsWithSuppressedBubble"
-    units="accounts" expires_after="M86">
-  <obsolete>
-    Removed as of 07/2020.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of domains for which at least one account exists that does not
-    trigger password save prompts anymore. The count is recorded once per
-    browser start-up. (In case of multiple profiles, the counts are for the
-    profile that first has a WebContents created.)
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.DeleteCorruptedPasswordsResult"
-    enum="DeleteCorruptedPasswordsResult" expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records the result of removing passwords that cannot be decrypted when
-    retrieving passwords from LoginDatabase. Called for Mac users for each
-    profile.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordManager.EmptyUsernames.FormWithoutUsernameFieldIsPasswordChangeForm"
-    enum="PasswordManagerEmptyUsernamePasswordChangeForm" expires_after="M78">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>msramek@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    When parsing a password form, and no username field is detected, whether
-    this was a password change form.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.EmptyUsernames.OfferedToSave"
-    enum="PasswordManagerShowEmptyUsername" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    When offering to save a password, whether the username is empty.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.EmptyUsernames.ParsedUsernameField"
-    enum="PasswordManagerEmptyUsernameField" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    When parsing a password form, whether a username field is detected.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.EmptyUsernames.PasswordFieldCount"
-    units="units" expires_after="2018-09-06">
-  <obsolete>
-    Removed as of 09/2018. The investigation this metric was supporting has been
-    concluded in 2016.
-  </obsolete>
-  <owner>msramek@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of password fields for password forms that do not have a username
-    field. This is recorded every time such a password form is successfully
-    parsed. Note that the parsing is attempted when the form is encountered (i.e
-    when the document is loaded) and also when it is submitted.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.EmptyUsernames.TextAndPasswordFieldCount"
-    units="units" expires_after="2018-09-06">
-  <obsolete>
-    Removed as of 09/2018. The investigation this metric was supporting has been
-    concluded in 2016.
-  </obsolete>
-  <owner>msramek@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The total number of text and password fields for password forms that do not
-    have a username field. This is recorded every time such a password form is
-    successfully parsed. Note that the parsing is attempted when the form is
-    encountered (i.e when the document is loaded) and also when it is submitted.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>msramek@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Number of password forms with empty username in the Login Database for which
-    there is not another password form from the same realm with a nonempty
-    username. In other words, number of password forms with empty username which
-    we do not suspect to be reauthentication forms.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ExportedPasswordsPerUserInCSV" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 2019/07. Password exporting has been rolled out.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>The number of passwords exported in CSV format per user.</summary>
-</histogram>
-
-<histogram name="PasswordManager.ExportPasswordsToCSVResult"
-    enum="ExportPasswordsResult" expires_after="M80">
-  <obsolete>
-    Removed as of 2019/07. Password exporting has been rolled out.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>The success or error type of exporting passwords into CSV.</summary>
-</histogram>
-
-<histogram name="PasswordManager.GetMediated" enum="CredentialManagerGetResult"
-    expires_after="2017-05-22">
-  <obsolete>
-    Removed as of 05/2017. This metric has been replaced by
-    PasswordManager.MediationOptional.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Tracks result of navigator.credentials.get() with unmediated=false. That is
-    the result of account chooser.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.GetUnmediated"
-    enum="CredentialManagerGetResult" expires_after="2017-05-22">
-  <obsolete>
-    Removed as of 05/2017. This metric has been replaced by
-    PasswordManager.MediationSilent.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Tracks result of navigator.credentials.get() with unmediated=true. That is
-    the result of auto sign-in.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.HttpCredentialsWithConflictingHttpsCredential"
-    units="saved credentials" expires_after="M72">
-  <obsolete>
-    Removed as of M72. Superseded by PasswordManager.HttpCredentials.
-  </obsolete>
-  <owner>gemene@google.com</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Number of HTTP credentials, with HSTS enabled as given in the histogram
-    suffix, for which a conflicting (i.e.same host and username, but different
-    password) HTTPS credential exists. Recorded once for the profile on startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.HttpCredentialsWithEquivalentHttpsCredential"
-    units="saved credentials" expires_after="M72">
-  <obsolete>
-    Removed as of M72. Superseded by PasswordManager.HttpCredentials.
-  </obsolete>
-  <owner>gemene@google.com</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Number of HTTP credentials, with HSTS enabled as given in the histogram
-    suffix, for which an equivalent (i.e. same host, username and password)
-    HTTPS credential exists. Recorded once for the profile on startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.HttpCredentialsWithoutMatchingHttpsCredential"
-    units="saved credentials" expires_after="M72">
-  <obsolete>
-    Removed as of M72. Superseded by PasswordManager.HttpCredentials.
-  </obsolete>
-  <owner>gemene@google.com</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Number of HTTP credential, with HSTS enabled as given in the histogram
-    suffix, for which no HTTPS credential for the same username exists. Recorded
-    once for the profile on startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.IE7LookupResult" enum="IE7LookupResultStatus"
-    expires_after="2018-07-20">
-  <obsolete>
-    Removed as of 07/2018. This metric was deleted at
-    https://chromium-review.googlesource.com/c/chromium/src/+/1131495.
-  </obsolete>
-  <summary>
-    The result of importing passwords stored in IE7 into Chrome's password
-    store.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.InfoBarResponse" enum="InfoBarResponse"
-    expires_after="2016-03-10">
-  <obsolete>
-    Removed as of 03/2016. This metric has been replaced by
-    PasswordManager.UIDismissalReason.
-  </obsolete>
-  <summary>
-    The distribution of responses to the &quot;Do you want Chrome to remember
-    this password&quot;? info bar prompt.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.InvalidtHttpsCredentialsNeedToBeCleared"
-    enum="BooleanNeedsClearing" expires_after="M73">
-  <obsolete>
-    Corresponding clean-up logic got introduced in M71 and has run its course.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records once on startup whether forms with wrong signon_realm created by
-    HTTP to HTTPS migration need to be removed. See https://crbug.com/881731 for
-    more details.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed as of 09/2016.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    After migration from the Mac Keychain fails, records the number of passwords
-    in the Keychain owned by Chrome but not accessible by it.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.KeychainMigration.NumFailedPasswords"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    After migration from the Mac Keychain fails, records the number of passwords
-    in the Chrome Password Manager database for which the corresponding values
-    in the Keychain are not accessible by Chrome.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.KeychainMigration.NumPasswordsOnFailure"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    After migration from the Mac Keychain fails, records the number of passwords
-    in the Chrome Password Manager database to be migrated. As there is no
-    partial migration, it's the total number of passwords in the DB.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.KeychainMigration.Status"
-    enum="KeychainMigrationStatus" expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The status of passwords migration from the Keychain. It's recorded shortly
-    after startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.KWalletDeserializationStatus"
-    enum="BooleanSuccess" expires_after="M80">
-  <obsolete>
-    Removed as of 07/2019.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>cfroussios@chromium.org</owner>
-  <summary>
-    The success or failure of deserializing PasswordForms in KWallet. Failure
-    either indicates corrupted data or the presense of bugs in the
-    deserialization code.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LinuxBackendMigration.Adoption"
-    enum="LinuxPasswordsMigrationToEncryptionStatus" expires_after="2020-10-01">
-  <obsolete>
-    Removed as of Sept 2020.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Whether the password store has been migrated to an encrypted login database.
-    This is recorded on startup, before any migration attempts.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LinuxBackendMigration.AttemptResult"
-    enum="LinuxPasswordsMigrationToEncryptionStatus" expires_after="2020-10-01">
-  <obsolete>
-    Removed as of Sept 2020.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Whether the password store has been migrated to an encrypted login database.
-    This is recorded at the end of a migration attempt.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LinuxBackendMigration.TimeIntoEncrypted"
-    units="units" expires_after="2020-04-01">
-  <obsolete>
-    Removed 02/2020.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time it took to read credentials from the native backend and write them
-    into the encrypted login database. This is logged once per migration
-    (normally once per client), at the end of copying into the database. The
-    migration is triggered on the first operation to the password store.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LinuxBackendMigration.TimeIntoNative"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time it took to read credentials from the unencrypted login database and
-    insert them into the native backend. This is logged once per migration
-    (normally once per client), at the end of copying into the backend. The
-    migration is triggered on the first operation to the password store.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LinuxBackendStatistics" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    Information about usage of password storage backends on Linux. It also
-    includes whether a command line flag for a specific backend is given.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.LoginDatabaseFailedVersion" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The version of LoginDatabase if the migration to a new one failed.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.MultiAccountPasswordUpdateAction"
-    enum="MultiAccountUpdateBubbleUserAction" expires_after="2018-03-29">
-  <obsolete>
-    Removed 03/2018 in favor of PasswordManager.UpdateUIDismissalReason.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    A user action when a password update bubble with multiple accounts is shown.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.NumFormsExtractedIOS" units="forms"
-    expires_after="2020-09-27">
-  <obsolete>
-    Removed as of 09/2020.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <owner>kazinova@google.com</owner>
-  <summary>
-    Records the number of password forms extracted by PasswordFormHelper at the
-    moment of submission. This metric is needed to check the assumption that
-    received and parsed message contains only one form at a a time.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.NumPasswordsDeletedByBulkDelete" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Number of passwords deleted when the user chooses to clear passwords via the
-    clear browsing data UI.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.NumPasswordsDeletedDuringRollback"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed as of 06/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Number of passwords deleted when browsing data is cleared during rollback.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.NumPasswordsDeletedWhenBlacklisting"
-    units="units" expires_after="2015-08-19">
-  <obsolete>
-    Removed as of 08/2015.
-  </obsolete>
-  <summary>
-    When the user chooses to never remember passwords for a form, we remove all
-    previously saved credentials for that form. This is the count of those
-    credentials.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.Onboarding.ResultOfSavingFlow"
-    enum="PasswordManagerOnboardingResultOfSavingFlow"
-    expires_after="2020-09-27">
-  <obsolete>
-    Removed as of 04/2020.
-  </obsolete>
-  <owner>achulkov@google.com</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Result of the combined saving flow consisting of the potentially shown
-    onboarding dialog and the save infobar. Recorded when the user is prompted
-    to save their password.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.Onboarding.ResultOfSavingFlowAfterOnboarding"
-    enum="PasswordManagerOnboardingResultOfSavingFlow"
-    expires_after="2020-05-24">
-  <obsolete>
-    Removed as of 04/2020.
-  </obsolete>
-  <owner>achulkov@google.com</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Result of the combined saving flow consisting of the shown onboarding dialog
-    and the save infobar. Recorded when the user is propmpted to save their
-    password only if the onboarding was actually shown.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.Onboarding.State"
-    enum="PasswordManagerOnboardingState" expires_after="2020-09-27">
-  <obsolete>
-    Removed as of 04/2020.
-  </obsolete>
-  <owner>achulkov@google.com</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    The current state of showing the password manager onboarding to the user.
-    Recorded on startup.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.Onboarding.UIDismissalReason"
-    enum="PasswordManagerOnboardingUIDismissalReason"
-    expires_after="2020-07-26">
-  <obsolete>
-    Removed as of 04/2020.
-  </obsolete>
-  <owner>achulkov@google.com</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Reason of dismissal of the password manager onboarding dialog. Recorded when
-    the user is propmpted to save their password and the dialog is shown.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist"
-    enum="Boolean" expires_after="2017-05-18">
-  <obsolete>
-    Removed as of May 17 2017. Replaced by
-    PasswordProtection.RequestOutcome.ProtectedPasswordEntry.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    A password reuse is an event when the user typed a string that is equal to a
-    saved password on another domain, and this saved password is called reused
-    password.
-
-    This metric shows whether a password reuse happens on a page whose main
-    frame url matches CSD whitelist.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.PasswordUpdatedWithManualFallback"
-    enum="BooleanPasswordSavedWithFallback" expires_after="2018-05-24">
-  <obsolete>
-    Removed as of 05/2018.
-  </obsolete>
-  <owner>kolos@chromium.org</owner>
-  <summary>
-    Measures whether users update passwords with automatic prompt or manual
-    fallback.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.PresavedUpdateUIDismissalReason"
-    enum="PasswordManagerUIDismissalReason" expires_after="M83">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    Why was the update password UI closed when a generated password caused a
-    conflict?
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.PslDomainMatchTriggering"
-    enum="PasswordManagerPslDomainMatchTriggering" expires_after="M81">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Breakdown on trigger rate of providing a password form autofill entry based
-    on matching stored information using the public suffix list (PSL) for
-    possible matches. In addition, this metric also counts cases where a
-    existing federated entry was successfully matched via PSL. For example, this
-    includes cases where an existing federated credential for
-    https://example.com was used for https://subdomain.example.com.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.QueryingSuppressedAccountsFinished"
-    enum="Boolean" expires_after="2019-04-02">
-  <obsolete>
-    Removed 03/2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Records, for each password form seen by the password manager, whether the
-    PasswordStore responded quickly enough so that
-    PasswordManager.SuppressedAccount histogram samples could be computed.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.RemovedCorruptedPasswords" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Collects positive number of inaccessible passwords that were successfully
-    deleted when retrieving them from the database. Recorded for Mac users.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SavePasswordPromptDisappearedQuickly"
-    enum="Boolean" expires_after="2016-03-10">
-  <obsolete>
-    Removed as of 03/2016.
-  </obsolete>
-  <summary>
-    Indicates whether the save password prompt disappeared in less than one
-    second. This most likely indicates that the prompt was dismissed
-    automatically, e.g. due to a page navigation, before the user was able to
-    respond to the infobar.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SavePasswordPromptDisplayed" enum="Boolean"
-    expires_after="2016-03-10">
-  <obsolete>
-    Removed as of 03/2016.
-  </obsolete>
-  <summary>Indicates whether the save password prompt was displayed.</summary>
-</histogram>
-
-<histogram name="PasswordManager.SavePasswordPromptResponse"
-    enum="SavePasswordPromptResponseType" expires_after="2016-03-10">
-  <obsolete>
-    Removed as of 03/2016.
-  </obsolete>
-  <summary>
-    Breakdown of which response the user selected from the save password prompt.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SendPasswordFormToBrowserProcess"
-    enum="SendPasswordFormToBrowserProcess" expires_after="M74">
-  <obsolete>
-    Removed 03/2019.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>miniailau@google.com</owner>
-  <summary>
-    Measures sending/not sending password forms to the browser process by
-    PasswordAutofillAgent::SendPasswordForms.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SettingsReconciliation.InitialAndFinalValues"
-    enum="PasswordManagerPreferencesInitialAndFinalValues"
-    expires_after="2017-06-20">
-  <obsolete>
-    Removed 06/2017
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Tracks the pair of initial values and pair of final values for the legacy
-    preference for controlling the Chrome Password Manager and the new
-    preference for controlling Smart Lock on Android. A single sample is
-    recorded after sync has merged last snapshot and finished initialization for
-    sync users, and on profile initialization for non-sync users.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SettingsReconciliation.InitialValues"
-    enum="PasswordManagerPreferencesInitialValues" expires_after="2017-06-20">
-  <obsolete>
-    Removed 06/2017
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Tracks the pair of initial values for both for the legacy preference for
-    controlling the Chrome Password Manager and new preference for controlling
-    Smart Lock on Android. Sample is recorded on every profile initialization
-    before reconciliation logic is taken place, e.g. when user logs in to
-    browser, on a startup of a browser.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordManager.ShouldBlockPasswordForSameOriginButDifferentScheme"
-    enum="BooleanBlocked" expires_after="M78">
-  <obsolete>
-    Removed as of M78. PasswordManager.ProvisionalSaveFailure contains strictly
-    more information.
-  </obsolete>
-  <owner>jdoerrie@chromium.org</owner>
-  <summary>
-    This metric is recorded every time Chrome detects a password form
-    submission. The credential might be proposed to be saved, or it might be
-    blocked. It is blocked if the previously detected password form submission
-    was successful, and the current submission is from a URL with the same
-    origin, but a different and insecure scheme. That is, if the previously
-    provisionally saved credential is for https://example.com, a new credential
-    for http://example.com would be blocked. More details can be found in the
-    doc associated with http://crbug.com/571580.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ShouldShowAutoSignInFirstRunExperience"
-    enum="BooleanPending" expires_after="M77">
-  <obsolete>
-    Removed 06/2019
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Records if the user still has to click through the first run experience to
-    benefit from auto sign-in behavior. Recorded on every start-up.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ShouldShowPromptComparison"
-    enum="ShouldShowPromptResults" expires_after="M70">
-  <obsolete>
-    Removed 08/2018 because the decision this should have helped with is now
-    moot. See https://crbug.com/871509#c3.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    Records results of the new and the old algorithm for detecting whether to
-    show a password prompt to the user. Recorded on each password form
-    successful submission.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ShowAllSavedPasswordsAcceptedContext"
-    enum="ShowAllSavedPasswordsContext" expires_after="2020-09-30">
-  <obsolete>
-    Removed 08/2020.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Recorded when the &quot;Show all saved passwords&quot; fallback is accepted.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ShowAllSavedPasswordsShownContext"
-    enum="ShowAllSavedPasswordsContext" expires_after="2020-09-30">
-  <obsolete>
-    Removed 08/2020.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Recorded when the &quot;Show all saved passwords&quot; fallback is shown.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.ShowedFormNotSecureWarningOnCurrentNavigation"
-    enum="BooleanShown" expires_after="2018-05-04">
-  <obsolete>
-    Removed 05/2018 because the feature never launched.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Recorded (at most once per main-frame navigation) when a password form shows
-    a warning that the form is not secure.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SignInPromo"
-    enum="PasswordBubbleSignInPromoDismissalReason" expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    User action on the Chrome Sync promo that appears in the password bubble.
-    The promo offers to sign in to Chrome.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SignInPromoCountTilClick" units="units"
-    expires_after="2016-12-16">
-  <obsolete>
-    Removed as of 12/16/16. New statistic is
-    PasswordManager.SignInPromoCountTil*.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of times the Sign In promo in the password bubble was shown
-    before user clicked on it.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SignInPromoCountTilNoThanks" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of times the Sign In promo in the password bubble was shown
-    before user clicked on &quot;No thanks&quot;.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SignInPromoCountTilSignIn" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of times the Sign In promo in the password bubble was shown
-    before user clicked on &quot;Sign in&quot;.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SignInPromoDismissalCount" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/19.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of times the Sign In promo in the password bubble was implcitly
-    dismissed. Recorded each time the promo is implicitly dismissed.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePasswordImportedFromCSVResult"
-    enum="BooleanSuccess" expires_after="2017-09-20">
-  <obsolete>
-    Removed as of 14 September 2017, due to being no longer useful.
-  </obsolete>
-  <owner>xunlu@chromium.org</owner>
-  <summary>
-    Whether password manager stored passwords imported from CSV file
-    successfully.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePerformance.AddLogin" units="units"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed as of October 2019
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time (ms) it takes for the synchronous part of the AddLogin on the
-    PasswordStore to complete.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePerformance.GetLogin" units="units"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed as of October 2019
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time (ms) it takes for the synchronous part of the GetLogin on the
-    PasswordStore to complete.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePerformance.GetLogins" units="units"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed as of October 2019
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time (ms) it takes for the synchronous part of the GetLogins on the
-    PasswordStore to complete.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePerformance.RemoveLogin" units="units"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed as of October 2019
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time (ms) it takes for the synchronous part of the RemoveLogin on the
-    PasswordStore to complete.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StorePerformance.UpdateLogin" units="units"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed as of October 2019
-  </obsolete>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    The time (ms) it takes for the synchronous part of the UpdateLogin on the
-    PasswordStore to complete.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.StoreReadyWhenWiping" enum="Boolean"
-    expires_after="2018-08-28">
-  <obsolete>
-    Removed since August 28, 2018, due to removing the corresponding feature.
-  </obsolete>
-  <summary>
-    When the user logs in with their sync credential, PasswordManager checks if
-    there are any outdated copies of it in the password store, in order to purge
-    them. This histogram records whether password store data are ready during
-    this check.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SubmitNavigatesToDifferentDomain"
-    enum="PostSubmitNavigation" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <summary>
-    Indicates whether submitting a password login form changes the registry
-    controlled domain of the main frame.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SuggestionClicked"
-    enum="PasswordSuggestionType" expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The type of password suggestion on iOS displayed in the keyboard accessory.
-    Recorded for each tap on the suggestion.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SuggestionShown" enum="PasswordSuggestionType"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The type of password suggestions on iOS displayed in the keyboard accessory.
-    Recorded each time the password suggestion is shown.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SuppressedAccount"
-    enum="PasswordManagerSuppressedAccountCrossActionsTaken"
-    expires_after="2019-04-02">
-  <obsolete>
-    Removed 03/2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Records, for each password form seen by the password manager, whether there
-    were `suppressed` credentials, meaning stored credentials that were not
-    filled because they were for an origin that was similar to, but not exactly
-    (or PSL) matching the origin of the observed form (see the suffix
-    description for the possible classes of such near-matches). If there were
-    such credentials, the histogram also records whether the username and
-    password of such suppressed credentials matched those submitted.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.SyncCredentialFiltered"
-    enum="CredentialFilteredType" expires_after="2019-02-25">
-  <obsolete>
-    Password manager no longer supports this behavior and the code that could
-    generate values in this histogram is gone as of M74.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    This histogram is reported for those forms on accounts.google.com, on which
-    Chrome is forced by Finch/flags during autofilling to remove sync
-    credentials from password store results. It reports true if sync credentials
-    were indeed removed from the store results, and false if there were no sync
-    credentials in the results to begin with.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.TimeReadingExportedPasswords" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 2019/07. Password exporting has been rolled out.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <owner>cfroussios@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    The time it takes to fetch and serialise the passwords for export.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.TimesGeneratedPasswordUsed" units="units"
-    expires_after="2014-11-18">
-  <obsolete>
-    Removed as of 11/11/14. New statistic is
-    PasswordManager.TimesPasswordUsed.AutoGenerated.
-  </obsolete>
-  <summary>
-    The number of times each generated password has been used to log in.
-    Recorded by iterating over stored passwords once per run. This information
-    is persisted and synced.
-  </summary>
-</histogram>
-
-<histogram base="true" name="PasswordManager.TotalAccounts" units="units"
-    expires_after="M76">
-  <obsolete>
-    Removed in M76 in favor of PasswordManager.TotalAccountsHiRes.ByType.
-  </obsolete>
-  <owner>battre@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The number of accounts stored in the password manager (across all sites),
-    split by whether created by the user or generated by Chrome, and further by
-    whether the user used sync with custom passphrase or not.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.UpdatePasswordSubmissionEvent"
-    enum="UpdatePasswordSubmissionEvent" expires_after="2018-03-29">
-  <obsolete>
-    Removed 03/2018 in favor of PasswordManager.UpdateUIDismissalReason.
-  </obsolete>
-  <owner>dvadym@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    The password submission event happened when the user changes their password
-    on a website, say foo.com or types new password on a sign-in form for saved
-    credential (which might mean that the password was changed in a different
-    browser). The later case called password overriding. This histogram measures
-    whether the user has any passwords saved in the Chrome password manager for
-    foo.com or the password was overriden on sign-in form, and what action the
-    user performed on the offered bubble. It's recorded when the bubble is
-    closed.
-  </summary>
-</histogram>
-
-<histogram name="PasswordManager.UserStoredPasswordWithInvalidSSLCert"
-    enum="Boolean" expires_after="2016-07-14">
-  <obsolete>
-    Removed 07/2016 because this information is no longer stored in
-    PasswordForm. See also http://crbug.com/413020.
-  </obsolete>
-  <owner>xunlu@chromium.org</owner>
-  <owner>gcasto@chromium.org</owner>
-  <summary>
-    Whether saved password for HTTPS site had a valid SSL cert when the password
-    was saved.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.CacheVerdictDuration" units="ms"
-    expires_after="2020-01-01">
-  <obsolete>
-    Removed since caching is not the root cause of time out issue.
-  </obsolete>
-  <owner>xinghuilu@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time it takes for PasswordProtectionService to cache a verdict.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.ChromeSettingsAction"
-    enum="PasswordProtectionWarningAction" expires_after="M83">
-  <obsolete>
-    Removed since 03/2020 due to no usage.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>bdea@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records how a user interacts with the chrome://settings page that displays
-    the password protection warning. Logged when the page is shown and when the
-    user chooses to change their password on the page.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.DomFeatureParsing" enum="BooleanSuccess"
-    expires_after="M78">
-  <obsolete>
-    Removed in M78. The DOM features always parsed successfully, so this
-    histogram wasn't useful.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether the DOM features were parsed successfully when returned from
-    the renderer. This is logged on every PhishGuard ping.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.GetCachedVerdictDuration" units="ms"
-    expires_after="2020-01-01">
-  <obsolete>
-    Removed since caching is not the root cause of time out issue.
-  </obsolete>
-  <owner>xinghuilu@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time it takes for PasswordProtectionService to get a cached verdict.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.InterstitialActionByUserNavigation"
-    enum="PasswordProtectionWarningAction" expires_after="2019-01-04">
-  <obsolete>
-    Removed 2019-01 due to lack of usage. https://crbug.com/915894
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    When user manually navigates to chrome://reset-password page, records how
-    this user interacts with this page. Logged when the interstitial is shown
-    and when the user chooses to change their password.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="PasswordProtection.NumberOfCachedVerdictBeforeShutdown" units="count"
-    expires_after="2018-07-26">
-  <obsolete>
-    Removed since 07/2018 due to lack of usage.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Number of password protection verdicts stored in content settings of a
-    profile before this profile is destructed.
-  </summary>
-</histogram>
-
-<histogram
-    name="PasswordProtection.NumberOfVerdictsMigratedDuringInitialization"
-    units="verdicts" expires_after="M80">
-  <obsolete>
-    Removed in M71+.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    We start changing the way of caching password protection verdicts in M69.
-    This histogram counts the number of verdicts migrated to the new way during
-    initialization of PasswordProtectionService. It helps determine when we can
-    remove migration code.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.PasswordReuseEventVerdict"
-    enum="PasswordProtectionVerdict" expires_after="2017-05-16">
-  <obsolete>
-    Removed since May 12 2017. Replaced by
-    PasswordProtection.Verdict.ProtectedPasswordEntry.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Verdict types returned by Safe Browsing server for password reuse events.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.ReferrerChainSize" units="referrers"
-    expires_after="M71">
-  <obsolete>
-    Removed September 18 2018. This wasn't being used, and can be recreated on
-    the backend if needed.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The referrer chain size of a password protection request. This is recorded
-    when Chrome receives a verdict for this request.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.UnfamiliarLoginPageVerdict"
-    enum="PasswordProtectionVerdict" expires_after="2017-05-16">
-  <obsolete>
-    Removed since May 12 2017. Replaced by
-    PasswordProtection.Verdict.PasswordFieldOnFocus.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Verdict types returned by Safe Browsing server for unfamiliar login pages.
-  </summary>
-</histogram>
-
-<histogram name="PasswordProtection.UserClickedThroughSafeBrowsingInterstitial"
-    enum="BooleanClickedThroughSBInterstitial" expires_after="2018-07-26">
-  <obsolete>
-    Removed since 07/2018 due to lack of usage.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Whether the user has clicked through the Safe Browsing interstitial before
-    the password protection ping is triggered on the same page. Logged right
-    before password protection ping is sent.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when CanMakePayment was not called by the
-    merchant.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CanMakePayment.Usage"
-    enum="CanMakePaymentUsage" expires_after="2017-08-10">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the merchant used the CanMakePayment method during a Payment
-    Request.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CanMakePayment.Used.EffectOnShow"
-    enum="PaymentRequestCanMakePaymentEffectOnShow" expires_after="2017-08-10">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    The effect of the CanMakePayment return value on whether Show was called.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when CanMakePayment was called by the
-    merchant and returned false.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when CanMakePayment was called by the
-    merchant and returned true.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.Completed" enum="BooleanHit"
-    expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>When the merchant has processed the user's Payment Request.</summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.Initiated" enum="BooleanHit"
-    expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>When a Payment Request gets initiated by the user.</summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.PayClicked" enum="BooleanHit"
-    expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    When the user clicks the &quot;pay&quot; button in the Payment Request UI.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.ReceivedInstrumentDetails"
-    enum="BooleanHit" expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    When the browser retrieves the instrument details from the payment app to
-    complete a purchase.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.Shown" enum="BooleanHit"
-    expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    When the Payment Request UI gets shown after initialization.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.CheckoutFunnel.SkippedShow"
-    enum="BooleanSkipped" expires_after="2017-08-09">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    When the Payment Request UI gets skipped to go directly to the payment app.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.NumberOfSelectionAdds" units="units"
-    expires_after="2020-07-26">
-  <obsolete>
-    Removed 09/2020. Made decision in issue 1128111 to remove unused payment
-    sheet histograms.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <owner>web-payments-team@google.com</owner>
-  <summary>
-    The number of times the user added an entry during a Payment Request.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.NumberOfSelectionChanges" units="units"
-    expires_after="2020-07-26">
-  <obsolete>
-    Removed 09/2020. Made decision in issue 1128111 to remove unused payment
-    sheet histograms.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <owner>web-payments-team@google.com</owner>
-  <summary>
-    The number of times the user changed an entry during a Payment Request.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.NumberOfSelectionEdits" units="units"
-    expires_after="2020-09-01">
-  <obsolete>
-    Removed 09/2020. Made decision in issue 1128111 to remove unused payment
-    sheet histograms.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <owner>web-payments-team@google.com</owner>
-  <summary>
-    The number of times the user edited an entry during a Payment Request.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.RequestedInformation"
-    enum="PaymentRequestRequestedInformation" expires_after="2017-08-08">
-  <obsolete>
-    M62+ Included in PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Tracks what user information is required by merchants to complete a Payment
-    Request.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.SelectedPaymentMethod"
-    enum="PaymentRequestPaymentMethods" expires_after="2017-08-15">
-  <obsolete>
-    M62+ Included in PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Tracks what payment method was used to complete a transaction in Payment
-    Request.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when the user did not have a complete
-    suggestion offered for each requested information.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    Replaced by PaymentRequest.NumberOfSuggestionsShown.PaymentMethod on July
-    19th 2017.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when the user did not have a a form of
-    payment on file when the Payment Request was shown.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.UserDidNotHaveSuggestionsForEverything.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when the user did not have suggestions
-    offered for each requested information.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M80">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when the user had at least one complete
-    suggestion offered for each requested information.
-  </summary>
-</histogram>
-
-<histogram name="PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="2017-07-19">
-  <obsolete>
-    Replaced by PaymentRequest.NumberOfSuggestionsShown.PaymentMethod on July
-    19th 2017.
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <summary>
-    Whether the flow was completed when the user had a form of payment on file
-    when the Payment Request was shown.
-  </summary>
-</histogram>
-
-<histogram
-    name="PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion"
-    enum="PaymentRequestFlowCompletionStatus" expires_after="M85">
-  <obsolete>
-    M62+ Part of PaymentRequest.Events
-  </obsolete>
-  <owner>danyao@chromium.org</owner>
-  <owner>web-payments-team@google.com</owner>
-  <summary>
-    Whether the flow was completed when the user had suggestions offered for
-    each requested information.
-  </summary>
-</histogram>
-
-<histogram name="PDF.AnnotationType" enum="ChromePDFViewerAnnotationType"
-    expires_after="M81">
-  <obsolete>
-    Removed in February 2020.
-  </obsolete>
-  <owner>hnakashima@chromium.org</owner>
-  <summary>
-    Tracks documents opened in the PDF viewer that displayed one or more pages
-    with the given annotation type.
-  </summary>
-</histogram>
-
-<histogram name="PDF.DocumentFeature" enum="PDFFeatures" expires_after="M82">
-  <obsolete>
-    Removed in March 2020.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Tracks which features are used by documents opened in the PDF viewer, logged
-    when the document finishes loading.
-  </summary>
-</histogram>
-
-<histogram name="PDF.FileSizeInKB" units="KB" expires_after="M77">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>The size of PDF documents opened in the PDF viewer.</summary>
-</histogram>
-
-<histogram name="PDF.IsFontSubstituted" enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <summary>
-    Measures if PDFs opened in the PDF viewer require fonts to be substituted.
-    This is logged whenever a document is opened in the PDF viewer.
-  </summary>
-</histogram>
-
-<histogram name="PDF.IsLinearized" enum="Boolean" expires_after="2020-01-26">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>hnakashima@chromium.org</owner>
-  <summary>
-    Measures if PDFs opened in the PDF viewer are Linearized PDFs. This is
-    logged whenever a document is opened in the PDF viewer.
-  </summary>
-</histogram>
-
-<histogram name="Pepper.BrokerAction" enum="PepperBrokerAction"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 5/2019.
-  </obsolete>
-  <owner>raymes@chromium.org</owner>
-  <summary>
-    Counts various actions related to the Pepper Broker interface.
-  </summary>
-</histogram>
-
-<histogram name="Pepper.SecureOrigin.MediaStreamRequest" enum="BooleanSecure"
-    expires_after="2017-08-03">
-  <obsolete>
-    Removed as of 8/2017.
-  </obsolete>
-  <owner>raymes@chromium.org</owner>
-  <summary>
-    Whether a Pepper media stream request (mic/cam access) comes from a plugin
-    in a secure or an insecure origin.
-  </summary>
-</histogram>
-
-<histogram name="Performance.MeasureParameter.EndMark"
-    enum="PerformanceMeasureParameterType" expires_after="2019-06-01">
-  <obsolete>
-    Removed as of June 2019.
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <summary>
-    The count of possible incoming values to the endMark parameter in
-    performance.measure(). The purpose is to investigate how much the change of
-    API of User Timing L3 will impact the real world use cases. This histogram
-    was deprecated in 05/2018 and re-reenabled in 11/2018. The re-enabled
-    histogram adds the counting of undefined, null, number and unprovided, to
-    the original navigation-timing names, object and string. This value is
-    recorded at each call to performance.measure().
-  </summary>
-</histogram>
-
-<histogram name="Performance.MeasureParameter.StartMark"
-    enum="PerformanceMeasureParameterType" expires_after="2019-06-01">
-  <obsolete>
-    Removed as of June 2019.
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <summary>
-    The count of possible incoming values to the startMark parameter in
-    performance.measure(). The purpose is to investigate how much the change of
-    API of User Timing L3 will impact the real world use cases. This histogram
-    was deprecated in 05/2018 and re-reenabled in 11/2018. The re-enabled
-    histogram adds the counting of undefined, null, number and unprovided, to
-    the original navigation-timing names, object and string. This value is
-    recorded at each call to performance.measure().
-  </summary>
-</histogram>
-
-<histogram name="PerformanceManager.AgentsByTime" units="units"
-    expires_after="2020-12-04">
-  <obsolete>
-    Removed 2020-11.
-  </obsolete>
-  <owner>bokan@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Tracks the total number of agents hosted by the browser by time. An entry in
-    bucket N corresponds to N agents being hosted across all live renderer
-    process for 1 second. Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="PerformanceManager.AgentsPerRendererByTime" units="units"
-    expires_after="2020-12-04">
-  <obsolete>
-    Removed 2020-11.
-  </obsolete>
-  <owner>bokan@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Tracks the number of agents hosted per renderer by time. An entry in bucket
-    N corresponds to N agents being hosted by a renderer process for 1 second.
-    Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="PerformanceManager.AgentsUniqueByTime" units="units"
-    expires_after="2020-12-04">
-  <obsolete>
-    Removed 2020-11.
-  </obsolete>
-  <owner>bokan@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>platform-architecture-dev@chromium.org</owner>
-  <summary>
-    Tracks the number of unique agents hosted by the browser by time. An entry
-    in bucket N corresponds to N unique agents being hosted across all live
-    renderer process for 1 second. Unique means that the agent count would
-    remain the same if they were in one process (i.e. they have different
-    protocol+site). Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram
-    name="PerformanceManager.BrowsingInstancePluralityVisibilityState.ByPageTime"
-    enum="BrowsingInstancePluralityVisibilityState" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2020-01-06 as this was only added for a brief exploration.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    Tracks the plurality and visibility state of all BrowsingInstances over
-    time. An entry in each bucket corresponds to a page in a BrowsingInstance
-    being in that state for one second. This is effectively &quot;page
-    seconds&quot; of time spent in each state. Recorded on state changes and
-    every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram
-    name="PerformanceManager.BrowsingInstancePluralityVisibilityState.ByTime"
-    enum="BrowsingInstancePluralityVisibilityState" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2020-01-06 as this was only added for a brief exploration.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    Tracks the plurality and visibility state of all BrowsingInstances over
-    time. An entry in each bucket corresponds to a BrowsingInstance being in
-    that state for one second. Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram
-    name="PerformanceManager.FrameSiteInstanceProcessRelationship.ByProcess"
-    enum="FrameSiteInstanceProcessRelationship" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-06-04 in favour of variant 2.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    Tracks the types of frames that are being hosted by a process over its
-    entire lifetime. An entry in the
-    &quot;AllFramesHaveDistinctSiteInstances&quot; means that the process only
-    ever hosted frames with distinct site instances over its entire lifetime.
-    Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram
-    name="PerformanceManager.FrameSiteInstanceProcessRelationship.ByTime"
-    enum="FrameSiteInstanceProcessRelationship" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-06-04 in favour of variant 2.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    Tracks the types of frames that are being hosted by a process, aggregated
-    over time. Each entry in each bucket corresponds to a process being in that
-    state for one second. Recorded on state changes and every 5 minutes.
-  </summary>
-</histogram>
-
-<histogram name="PerformanceMonitor.SystemMonitor.DiskIdleTime" units="%"
-    expires_after="2019-07-01">
-  <obsolete>
-    Expired on 2019-07-01.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    Average percentage of time during which the disk has been idle, logged at
-    regular intervals. If the system has multiple disks then this is the average
-    value for all of them. Windows only.
-  </summary>
-</histogram>
-
-<histogram name="PerformanceMonitor.SystemMonitor.FreePhysMemory" units="MB"
-    expires_after="2019-07-01">
-  <obsolete>
-    Expired on 2019-07-01.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The amount of free physical memory available, logged at regular intervals.
-    Windows only.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Action.InsecureOrigin" enum="PermissionAction"
-    expires_after="M85">
-  <obsolete>
-    Removed on 2020-06-19 as most permissions are no longer exposed to insecure
-    origins to begin with, and even those few that are recorded no useful data
-    any longer.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>engedy@chromium.org</owner>
-  <owner>hkamila@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Tracks whether a permission was granted, rejected, etc on an insecure
-    origin. The suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Action.SecureOrigin" enum="PermissionAction"
-    expires_after="M85">
-  <obsolete>
-    Removed on 2020-06-19 as most permissions are no longer exposed to insecure
-    origins to begin with, and even those few that are recorded no useful data
-    any longer.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>engedy@chromium.org</owner>
-  <owner>hkamila@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Tracks whether a permission was granted, rejected, etc on a secure origin.
-    The suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.AutoBlocker.SafeBrowsingResponse"
-    enum="SafeBrowsingResponse" expires_after="2018-03-15">
-  <obsolete>
-    Permission blacklisting was removed in M67.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Tracks the response (if received) from Safe Browsing when the API blacklist
-    is queried for an (origin, permission) pair. The response could be that the
-    origin was blacklisted, not blacklisted, or Safe Browsing timed out before a
-    response was received.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.AutoBlocker.SafeBrowsingResponseTime" units="ms"
-    expires_after="2018-03-15">
-  <obsolete>
-    Permission blacklisting was removed in M67.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Records the elapsed time between the client sending a request to Safe
-    Browsing and receiving a result, or the maximum wait time is exceeded and
-    Safe Browsing is deemed to have timed out.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Accepted.Persisted" enum="BooleanPersisted"
-    expires_after="2017-11-27">
-  <obsolete>
-    Persist toggle experiments ran from M56 to M59.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    For each granted permission prompt displayed with a persistence toggle
-    (remember my decision), records whether the persistence toggle was enabled
-    (persist) or not enabled (don't persist).
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Accepted.PriorDismissCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Accepted.PriorDismissCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt accept, records the
-    total number of prompt dismissal events for this origin since the last time
-    the user cleared their history or site data and prior to the accept. The
-    suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Accepted.PriorIgnoreCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Accepted.PriorIgnoreCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt accept, records the
-    total number of prompt ignore events for this origin since the last time the
-    user cleared their history or site data and prior to the accept. The suffix
-    of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Denied.Persisted" enum="BooleanPersisted"
-    expires_after="2017-11-27">
-  <obsolete>
-    Persist toggle experiments ran from M56 to M59.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    For each denied permission prompt displayed with a persistence toggle
-    (remember my decision), records whether the persistence toggle was enabled
-    (persist) or not enabled (don't persist).
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Denied.PriorDismissCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Denied.PriorDismissCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt deny, records the
-    total number of prompt dismissal events for this origin since the last time
-    the user cleared their history or site data and prior to the accept. The
-    suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Denied.PriorIgnoreCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Denied.PriorIgnoreCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt deny, records the
-    total number of prompt ignore events for this origin since the last time the
-    user cleared their history or site data and prior to the accept. The suffix
-    of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.DismissCount" units="units"
-    expires_after="2016-08-23">
-  <obsolete>
-    Renamed to Permissions.Prompt.Dismissed.PriorDismissCount on 17 August 2016.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt dismissal, records
-    the total number of prompt dismissal events for this origin since the last
-    time the user cleared their history or site data, inclusive of the current
-    dismissal. Every event in a bucket larger than 1 in this histogram will also
-    have an event in each smaller bucket. The suffix of the histogram indicates
-    which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Dismissed.PriorDismissCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Dismissed.PriorDismissCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt dismiss, records
-    the total number of prompt dismissal events for this origin since the last
-    time the user cleared their history or site data and prior to the dismiss.
-    The suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Dismissed.PriorIgnoreCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Dismissed.PriorIgnoreCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt dismiss, records
-    the total number of prompt ignore events for this origin since the last time
-    the user cleared their history or site data and prior to the dismiss. The
-    suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.IgnoreCount" units="units"
-    expires_after="2016-08-23">
-  <obsolete>
-    Renamed to Permissions.Prompt.Dismissed.PriorDismissCount on 17 August 2016.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt ignore, records the
-    total number of prompt ignore events for this origin since the last time the
-    user cleared their history or site data, inclusive of the current ignore.
-    Every event in a bucket larger than 1 in this histogram will also have an
-    event in each smaller bucket. The suffix of the histogram indicates which
-    particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Ignored.PriorDismissCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Ignored.PriorDismissCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt ignore, records the
-    total number of prompt dismissal events for this origin since the last time
-    the user cleared their history or site data and prior to the ignore. The
-    suffix of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.Ignored.PriorIgnoreCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Replaced by Permissions.Prompt.Ignored.PriorIgnoreCount2 on 05/2020.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    This metric, recorded at the time of a permission prompt ignore, records the
-    total number of prompt ignore events for this origin since the last time the
-    user cleared their history or site data and prior to the ignore. The suffix
-    of the histogram indicates which particular permission.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.MergedBubbleAccepted"
-    enum="PermissionRequestType" expires_after="2017-11-08">
-  <obsolete>
-    Redundant since M61 (bug 728483) as we now only merge Mic+Camera. The same
-    counts are available in Permissions.Prompt.Accepted.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Tracks acceptance of permission bubble request types that have been merged
-    into coalesced bubbles.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.MergedBubbleDenied"
-    enum="PermissionRequestType" expires_after="2017-11-08">
-  <obsolete>
-    Redundant since M61 (bug 728483) as we now only merge Mic+Camera. The same
-    counts are available in Permissions.Prompt.Denied.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Tracks denial of permission bubble request types that have been merged into
-    coalesced bubbles.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.MergedBubbleTypes"
-    enum="PermissionRequestType" expires_after="2017-11-08">
-  <obsolete>
-    Redundant since M61 (bug 728483) as we now only merge Mic+Camera. The same
-    counts are available in Permissions.Prompt.Shown.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Tracks the permission bubble request types that are being merged into
-    coalesced bubbles.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Prompt.RequestsPerPrompt" units="units"
-    expires_after="2017-11-08">
-  <obsolete>
-    Redundant since M61 (bug 728483) as we now only merge Mic+Camera. The same
-    counts are available in Permissions.Prompt.Shown.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    How many permission requests each permissions prompt shown to the user
-    contains.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Requested.CrossOrigin" enum="PermissionStatus"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017, no longer used
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <owner>keenanb@google.com</owner>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    The embedder's permission setting at the time of a cross-origin iframe
-    permission request for a given permission type. See the corresponding
-    histogram suffixes.
-
-    A request is when a website makes a permission request and the user has the
-    permission set to prompt (i.e. not blocked or allowed).
-
-    Note this is probably not the metric you want - it does not correspond to
-    the total number of times websites request a permission. Also, because
-    specific permissions have code that can automatically block or grant
-    permissions based on things like incognito, installed extensions etc., this
-    does also not correspond to the number of times users are prompted to allow
-    permissions.
-
-    See https://crbug.com/638076 for more details.
-  </summary>
-</histogram>
-
-<histogram name="Permissions.Requested.SameOrigin" enum="PermissionType"
-    expires_after="2017-02-23">
-  <obsolete>
-    Removed 02/2017, no longer used
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <owner>keenanb@google.com</owner>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    The permission type (geolocation, and such) of a same-origin permission
-    request.
-
-    A request is when a website makes a permission request and the user has the
-    permission set to prompt (i.e. not blocked or allowed).
-
-    Note this is probably not the metric you want - it does not correspond to
-    the total number of times websites request a permission. Also, because
-    specific permissions have code that can automatically block or grant
-    permissions based on things like incognito, installed extensions etc., this
-    does also not correspond to the number of times users are prompted to allow
-    permissions.
-
-    See https://crbug.com/638076 for more details.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ActivityReferral"
-    enum="PhysicalWebActivityReferer" expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Referer used by user to reach the main Physical Web Activity.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.InitialState.IosChrome"
-    enum="PhysicalWebInitialStateIosChrome" expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>Initial state of the Physical Web in Chrome for iOS.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ReferralDelay.OptInNotification" units="ms"
-    expires_after="2017-01-24">
-  <obsolete>
-    Removed 01/2017, no longer used
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Time between the most recent opt in notification update and when the user
-    arrives at the ListUrlsActivity.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ReferralDelay.StandardNotification" units="ms"
-    expires_after="2017-01-24">
-  <obsolete>
-    Removed 01/2017, no longer used
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Time between the most recent standard notification update and when the user
-    arrives at the ListUrlsActivity.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ResolveTime.Background" units="ms"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Round trip time to the metadata server for a Physical Web URL resolution
-    which the client requests during a background scan.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ResolveTime.Foreground" units="ms"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Round trip time to the metadata server for a Physical Web URL resolution
-    which the client requests during a foreground scan, that is not explicitly
-    requested via a refresh.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.ResolveTime.Refresh" units="ms"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Round trip time to the metadata server for a Physical Web URL resolution
-    which the client requests during a foreground scan, that is explicitly
-    requested via a refresh.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.RoundTripTimeMilliseconds" units="ms"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>olivierrobin@chromium.org</owner>
-  <summary>Round trip time to the metadata server for Physical web.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.State.Bluetooth" enum="BluetoothStatus"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>Whether bluetooth is on, off, or unknown.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.State.DataConnectionActive" enum="BooleanActive"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>Whether the data connection is active.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.State.LocationPermission" enum="BooleanAccepted"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>Whether location permission has been accepted.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.State.LocationServices" enum="BooleanEnabled"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>Whether location services are enabled.</summary>
-</histogram>
-
-<histogram name="PhysicalWeb.State.Preference"
-    enum="PhysicalWebPreferenceStatus" expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Whether the preference is on, off, or if the user is in an onboarding state
-    when Chrome first starts up.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.TotalUrls.OnInitialDisplay" units="urls"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    The number of URLs displayed to a user when a list of nearby URLs is first
-    displayed.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.TotalUrls.OnRefresh" units="urls"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    The number of URLs displayed to a user when a list of nearby URLs is
-    displayed after refreshing.
-  </summary>
-</histogram>
-
-<histogram name="PhysicalWeb.WebUI.ListViewUrlPosition" units="selections"
-    expires_after="2018-05-16">
-  <obsolete>
-    Obsolete 4/2018, Physical Web is disabled (crbug.com/826540).
-  </obsolete>
-  <owner>cco3@chromium.org</owner>
-  <owner>mattreynolds@chromium.org</owner>
-  <owner>mmocny@chromium.org</owner>
-  <summary>
-    Count of how many times the user selected a nearby URL at the specified
-    index in the Physical Web WebUI list view (zero-based). Capped at 50.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Cast.MeminfoMemAvailable" units="units"
-    expires_after="2018-12-05">
-  <obsolete>
-    Removed 11/2018 in favor of Platform.Cast.MeminfoMemAvailable2 with a larger
-    range.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    /proc/meminfo's 'MemAvailable' in Mbytes. Collected on Cast devices with
-    kernel version 3.14 and above and capped at 500.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Cast.MeminfoMemFreeDerived" units="units"
-    expires_after="2018-12-05">
-  <obsolete>
-    Removed 11/2018 in favor of Platform.Cast.MeminfoMemFreeDerived2 with a
-    larger range.
-  </obsolete>
-  <owner>halliwell@chromium.org</owner>
-  <summary>
-    free + buffers + cache memory in Mbytes on Cast devices, capped at 500.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.Cache_Avg" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Average size of user's Cache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.Cache_Max" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Maximum size of user's Cache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.Downloads_Avg" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Average size of user's Cache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.Downloads_Max" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Maximum size of user's Cache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.GCache_Avg" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Average size of user's GCache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.GCache_Max" units="KB"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Maximum size of user's GCache directory. Logged once a day, if disk usage is
-    high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.DiskUsage.LeastUsedAccountDays" units="days"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Days since the least frequently used account signed in. Logged once a day,
-    if disk usage is high.
-  </summary>
-</histogram>
-
-<histogram name="Platform.KernelWarningHashes" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 8/2019 due to lack of usage.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The 32-bit hash of a kernel warning. This is the hash of the
-    &quot;file:line&quot; string corresponding to the location of the warning,
-    for instance: &quot;/mnt/host/source/src/third_party/kernel/files/drivers
-    /gpu/drm/i915/intel_dp.c:351&quot; (ignore spurious spaces). The hash is
-    produced by this code: while (*string) hash = (hash &lt;&lt; 5) + hash +
-    *string++; Separately each warning is also collected (with its hash) via the
-    crash reporter, but only its first occurrence in each boot session.
-  </summary>
-</histogram>
-
-<histogram name="Platform.MountEncrypted.EncryptedFsType"
-    enum="MountEncryptedEncryptedFsType" expires_after="M85">
-  <obsolete>
-    Removed 6/2020 due to lack of usage.
-  </obsolete>
-  <owner>gwendal@chromium.org</owner>
-  <owner>sarthakkukreti@chromium.org</owner>
-  <summary>
-    Type of encrypted mount used for the encrypted stateful file system on
-    Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.ServiceFailureHashes" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 8/2019 due to lack of usage.
-  </obsolete>
-  <owner>ddavenport@chromium.org</owner>
-  <summary>
-    The 32-bit hash of the name of the service that failed. The name of the
-    service is hashed using the same algorithm as used for the hashes in
-    Platform.KernelWarningHashes. The first instance of each service failure is
-    also collected separately via the crash reporter.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap0.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap0.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap0.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap0.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap1.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap1.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap1.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap1.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap2.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap2.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap2.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap2.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap3.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap3.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap3.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Cpu.Swap3.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap0.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap0.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap0.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap0.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap1.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap1.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap1.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap1.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap2.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap2.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap2.Time3"
-    units="page faults/second" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap2.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap3.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap3.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap3.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.Scroll.Faults.Swap3.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    scroll event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap0.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap0.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap0.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap0.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap1.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap1.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap1.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap1.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap2.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap2.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap2.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap2.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap3.Time1" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap3.Time2" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap3.Time3" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Cpu.Swap3.Time4" units="%"
-    expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    CPU utilization for the specified swap group and time interval after a tab
-    switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap0.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap0.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap0.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap0.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap1.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap1.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap1.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap1.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap2.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap2.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap2.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap2.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap3.Time1"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap3.Time2"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap3.Time3"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.SwapJank.TabSwitch.Faults.Swap3.Time4"
-    units="page faults/second" expires_after="2013-10-01">
-  <obsolete>
-    Removed 9/2013 when the SwapJank64vs32Parrot experiment ended.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Page faults/second for the specified swap group and time interval after a
-    tab switch event. See src/chrome/browser/chromeos/swap_metrics.cc.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Temperature.Wifi0" units="Celsius"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    Temperature reading at wireless interface 0 collected every few seconds (may
-    vary between devices).
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Temperature.Wifi1" units="Celsius"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    Temperature reading at wireless interface 1 collected every few seconds (may
-    vary between devices).
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Temperature.Wifi2" units="Celsius"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    Temperature reading at wireless interface 2 collected every few seconds (may
-    vary between devices).
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Zone.Wifi0.States" units="Thermal state"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    State of the thermal zone of wireless interface 0 collected every second.
-    State depends on device, higher state corresponds to a higher temperature.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Zone.Wifi1.States" units="Thermal state"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    State of the thermal zone of wireless interface 1 collected every second.
-    State depends on device, higher state corresponds to a higher temperature.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Thermal.Zone.Wifi2.States" units="Thermal state"
-    expires_after="M85">
-  <obsolete>
-    Removed 09/2020
-  </obsolete>
-  <owner>mka@chromium.org</owner>
-  <summary>
-    State of the thermal zone of wireless interface 2 collected every second.
-    State depends on device, higher state corresponds to a higher temperature.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Platform.TPMForcedReboot" units="reboots" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as there is no data and no mention of it in the codebase.
-  </obsolete>
-  <owner>apronin@chromium.org</owner>
-  <owner>cros-hwsec+uma@chromium.org</owner>
-  <summary>
-    Each sample is the number of consecutive reboots performed while attempting
-    to clear a TPM (Trusted Platform Module) error.
-  </summary>
-</histogram>
-
-<histogram name="Platform.Tps65090Retries" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Retries needed to enable a FET on tps65090 (AKA tpschrome). Tps65090 is a
-    power management unit (PMU) used on many ARM Chromebooks. Until version ES7
-    was rolled into production we would sometimes run into a problem where FET1
-    (the FET used to switch on and off the backlight) wouldn't turn on properly.
-    This problem was especially prevalent when the voltage was high (like when
-    the device was plugged into the wall). Retrying by turning the FET off and
-    on again is nearly always effective, so the kernel will retry up to 5 times
-    (currently) and will also log the fact that it needed to retry. On newest
-    kernels (kernel 3.8 and up) a kernel warning will be logged with WARN_ON if
-    the FET still failed to turn on after 5 tries. Refer to the kernel warning
-    reports to find that information. For more details about this bug refer to
-    http://crbug.com/338657 and http://crosbug.com/p/16009. Note that we log
-    retries on all 7 FETs even though we've only ever seen failures of FET1.
-  </summary>
-</histogram>
-
-<histogram name="Platform.U2F.LegacyCommand" enum="Cr50U2FCommands"
-    expires_after="2021-12-21">
-  <obsolete>
-    Removed 04/2022 as it is not used since crrev.com/c/1755785 (09/2019)
-  </obsolete>
-  <owner>cylai@chromium.org</owner>
-  <owner>cros-hwsec-userland-eng+uma@google.com</owner>
-  <summary>Records occurrences of legacy U2F commands sent to cr50.</summary>
-</histogram>
-
-<histogram name="PlatformFile.FlushTime" units="ms" expires_after="2016-07-22">
-  <obsolete>
-    Removed as of 2016-07 because the histogram's purpose of adding colour to
-    the description of File::Flush() has been fulfilled.
-  </obsolete>
-  <owner>tnagel@chromium.org</owner>
-  <summary>The time it takes to run File::Flush().</summary>
-</histogram>
-
-<histogram name="PlatformFile.UnknownCreateFileErrors" units="code"
-    expires_after="2013-05-15">
-  <obsolete>
-    Removed as of 2013-05, replaced by PlatformFile.UnknownCreateFileErrorsWin
-    in chrome 29.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Errors returned by CreateFile on windows that PlatformFileError doesn't yet
-    support.
-  </summary>
-</histogram>
-
-<histogram name="PLT.Abandoned" enum="Abandoned" expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Distribution of actual finished pages, vs abandoned pages, where we needed
-    to declare a finish time prematurely since the page was being closed
-    (exited).
-  </summary>
-</histogram>
-
-<histogram name="PLT.Abandoned.NoProxy.http" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned.NoProxy.https" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned.Proxy.http" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned.Proxy.https" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionAdblock" enum="Abandoned"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by Abandoned_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionAdblockPlus" enum="Abandoned"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by Abandoned_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionWebRequest" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <summary>
-    The PLT.Abandoned histogram for pages loaded after WebRequest API was used.
-  </summary>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionWebRequestAdblock" enum="Abandoned"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by Abandoned_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionWebRequestAdblockPlus" enum="Abandoned"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by Abandoned_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_ExtensionWebRequestOther" enum="Abandoned"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by Abandoned_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.Abandoned_SpdyProxy" enum="Abandoned"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.AbandonType" enum="AbandonType" expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Diagnose why a page load was considered abandoned.</summary>
-</histogram>
-
-<histogram name="PLT.BeginToCommit" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.Timing2.NavigationToCommit instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;begin&quot; to &quot;commit.&quot; &quot;Begin&quot;==
-    &quot;request&quot; if user requested, and &quot;start&quot; otherwise.
-    &quot;Request&quot;== time when user requested document. &quot;Start&quot;==
-    time when renderer requested load of document, after any unload of last
-    document. &quot;Commit&quot;== time when renderer got first byte of
-    document.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_AfterPreconnectRequest" units="ms"
-    expires_after="2014-07-18">
-  <obsolete>
-    Removed as of http://crrev.com/392823002
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    PLT.BeginToFinish, but for pages requested just after a new preconnect
-    request.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_ContentPrefetcher" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    PLT.BeginToFinish, but for pages which contained prefetch links.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_ContentPrefetcherReferrer" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    PLT.BeginToFinish, but for pages which were referred to by pages which
-    contained prefetch links.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadNormal_ExtensionAdblock" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadNormal_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadNormal_ExtensionAdblockPlus"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadNormal_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequest"
-    units="ms" expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <summary>
-    The PLT.BeginToFinish histogram for pages loaded by following a link, after
-    WebRequest API was used.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestAdblock"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadNormal_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram
-    name="PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestAdblockPlus"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadNormal_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestOther"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadNormal_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadReload_ExtensionAdblock" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadReload_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadReload_ExtensionAdblockPlus"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadReload_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequest"
-    units="ms" expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <summary>
-    The PLT.BeginToFinish histogram for pages reloaded by JavaScript or by
-    following a link, after WebRequest API was used.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestAdblock"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadReload_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram
-    name="PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestAdblockPlus"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadReload_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestOther"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadReload_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionAdblock" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionAdblockPlus"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest"
-    units="ms" expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <summary>
-    The PLT.BeginToFinish histogram for pages loads initiated by back/forward
-    buttons, or by a change of encoding, after WebRequest API was used.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestAdblock"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram
-    name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestAdblockPlus"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestOther"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by
-    BeginToFinish_LinkLoadStaleOk_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionAdblock" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by BeginToFinish_NormalLoad_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionAdblockPlus" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by BeginToFinish_NormalLoad_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionWebRequest" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <summary>
-    The PLT.BeginToFinish histogram for pages loaded by entering a URL or a
-    search query into Omnibox, after WebRequest API was used.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionWebRequestAdblock"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by BeginToFinish_NormalLoad_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionWebRequestAdblockPlus"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by BeginToFinish_NormalLoad_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_NormalLoad_ExtensionWebRequestOther"
-    units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed 6/2014. Replaced by BeginToFinish_NormalLoad_ExtensionWebRequest.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary/>
-</histogram>
-
-<histogram name="PLT.BeginToFinish_SpdyProxy" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    Use PLT.PT_BeginToFinish_DataReductionProxy instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>PLT.BeginToFinish, but for pages fetched over a SPDY proxy.</summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinishDoc" units="units" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinishDoc_AfterPreconnectRequest" units="ms"
-    expires_after="2014-07-18">
-  <obsolete>
-    Removed as of http://crrev.com/392823002
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    PLT.BeginToFinishDoc, but for pages requested just after a new preconnect
-    request.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinishDoc_ContentPrefetcher" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    PLT.BeginToFinishDoc, but for pages which contained prefetch links.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinishDoc_ContentPrefetcherReferrer" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    PLT.BeginToFinishDoc, but for pages which were referred to by pages which
-    contained prefetch links.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFinishDoc_SpdyProxy" units="ms"
-    expires_after="2016-08-03">
-  <obsolete>
-    Use PLT.PT_BeginToFinishDoc_DataReductionProxy instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    PLT.BeginToFinshDoc, but for pages fetched over a SPDY proxy.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFirstPaint" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.PaintTiming.NavigationToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    Time from &quot;begin&quot; to &quot;first paint.&quot; &quot;Begin&quot;==
-    &quot;request&quot; if user requested, and &quot;start&quot; otherwise.
-    &quot;Request&quot;== time when user requested document. &quot;Start&quot;==
-    time when renderer requested load of document, after any unload of last
-    document. &quot;First paint&quot;== time when first paint operation was
-    performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFirstPaint_Negative" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Magnitude and difference between begin and first paint, when first_paint
-    precedes begin. This is a temporary metric used to better understand the
-    root cause of http://crbug.com/125273.
-  </summary>
-</histogram>
-
-<histogram name="PLT.BeginToFirstPaintAfterLoad" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    The first paint after load is not useful for most documents. Consider using
-    PageLoad.PaintTiming.NavigationToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    Time from &quot;big&quot; to &quot;first paint after load.&quot;
-    &quot;Begin&quot;== &quot;request&quot; if user requested, and
-    &quot;start&quot; otherwise. &quot;Request&quot;== time when user requested
-    document. &quot;Start&quot;== time when renderer requested load of document,
-    after any unload of last document. &quot;First paint after load&quot;== time
-    after onload() when first paint operation is performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.CommitToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;finish.&quot; &quot;Commit&quot;==
-    time when renderer got first byte of document. &quot;Finish&quot;==after
-    onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="PLT.CommitToFinishDoc" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.ParseTiming.ParseDuration instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;finish doc.&quot; &quot;Commit&quot;==
-    time when renderer got first byte of document. &quot;Finish doc&quot; ==
-    main document loaded, before onload(). &quot;Finish&quot;==after onload()
-    and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="PLT.CommitToFirstPaint" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.PaintTiming.ParseStartToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;first paint.&quot;
-    &quot;Commit&quot;== time when renderer got first byte of document.
-    &quot;First paint&quot;== time when first paint operation was performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.CommitToFirstPaintAfterLoad" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    The first paint after load is not useful for most documents. Consider using
-    PageLoad.PaintTiming.ParseStartToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;first paint after load.&quot;
-    &quot;Commit&quot;== time when renderer got first byte of document.
-    &quot;First paint after load&quot;== time after onload() when first paint
-    operation is performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.FinishDocToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;finish doc&quot; to &quot;finish.&quot; &quot;Finish
-    doc&quot;== main document loaded, before onload(). &quot;Finish&quot;==after
-    onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="PLT.FinishToFirstPaintAfterLoad" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    The first paint after load is not useful for most documents. Consider using
-    PageLoad.PaintTiming.NavigationToFirstContentfulPaint instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;finish &quot; to &quot;first paint after load.&quot;
-    &quot;Finish&quot;==after onload() and all resources are loaded. &quot;First
-    paint after load&quot;== time after onload() when first paint operation is
-    performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.iOS.BrowserInitiatedPageLoadTimeWithLowBattery" units="ms"
-    expires_after="2020-08-09">
-  <obsolete>
-    Experiment has ended 2020-06.
-  </obsolete>
-  <owner>djean@chromium.org</owner>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    Page load time for Browser-initiated navigations when battery level is below
-    a certain threshold (20%). Recorded when
-    CRWWebRequestController::didFinishWithURL completes successfully. iOS
-    specific.
-  </summary>
-</histogram>
-
-<histogram name="PLT.iOS.RendererInitiatedPageLoadTimeWithLowBattery"
-    units="ms" expires_after="2020-08-09">
-  <obsolete>
-    Experiment has ended 2020-06.
-  </obsolete>
-  <owner>djean@chromium.org</owner>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    Page load time for Renderer-initiated navigations when battery level is
-    below a certain threshold (20%). Recorded when
-    CRWWebRequestController::didFinishWithURL completes successfully. iOS
-    specific.
-  </summary>
-</histogram>
-
-<histogram name="PLT.LoadType" enum="LoadType" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType.*
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Probability distribution for enumerated varieties of page loads.
-  </summary>
-</histogram>
-
-<histogram name="PLT.MissingStart" enum="MissingStartType"
-    expires_after="2014-06-30">
-  <obsolete>
-    Removed as of 2014-06.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Diagnose error conditions in PLT reporting. A start time should always be
-    present.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NavStartToLoadEnd" units="ms" expires_after="2014-06-23">
-  <obsolete>
-    deprecated 2012-01-19 in favour of PLT.PT_*
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time elapsed between the Navigation Timing metrics navigationStart and
-    loadEventEnd. Definitions: http://www.w3.org/TR/navigation-timing/
-  </summary>
-</histogram>
-
-<histogram name="PLT.NavStartToLoadStart" units="ms" expires_after="2014-06-23">
-  <obsolete>
-    deprecated 2012-01-19 in favour of PLT.PT_*
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time elapsed between the Navigation Timing metrics navigationStart and
-    loadEventStart. Definitions: http://www.w3.org/TR/navigation-timing/
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_Connect" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from connectStart to connectEnd based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeConnect" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domanLookupEnd to connectStart based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeDomainLookup" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from fetchStart to domainLookupStart based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeDomLoading" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016. Replaced by
-    PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from responseStart to domLoading based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeFetch" units="ms" expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from navigationStart to fetchStart based on Navigation Timing when no
-    redirect.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeFetchRedirect" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from navigationStart to fetchStart excluding time spent on redirects
-    based on Navigation Timing. Only page loads with redirects are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeLoadEvent" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016. Replaced by
-    PageLoad.DocumentTiming.NavigationToLoadEventFired.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domContentLoadedEventEnd to loadEventStart based on Navigation
-    Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DelayBeforeRequest" units="ms"
-    expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from connectEnd to requestStart based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DomainLookup" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domainLookupStart to domainLookupEnd based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DomContentLoaded" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToDOMContentLoadedEventFired
-    instead.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domContentLoadedEventStart to domContentLoadedEventEnd based on
-    Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DomInteractive" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domInteractive to domContentLoadEventStart based on Navigation
-    Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_DomLoading" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from domLoading to domInteractive based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_LoadEvent" units="ms" expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from loadEventStart to loadEventEnd based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_Redirect" units="ms" expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from redirectStart to redirectEnd based on Navigation Timing when
-    redirects exist.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_Request" units="ms" expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016. Replaced by
-    PageLoad.ParseTiming.NavigationToParseStart.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from requestStart to responseStart based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.NT_Response" units="ms" expires_after="2016-07-21">
-  <obsolete>
-    Removed as of 7/19/2016. Replaced by PageLoad.ParseTiming.ParseDuration.
-  </obsolete>
-  <owner>bolian@chromium.org</owner>
-  <summary>
-    Time from responseStart to responseEnd based on Navigation Timing.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PageUsed_PrerenderLoad" enum="PageUsed"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed as of 5/02/2011.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Distribution of discarded and displayed prerendered pages.</summary>
-</histogram>
-
-<histogram name="PLT.PerceivedLoadTime" units="ms" expires_after="2013-04-11">
-  <obsolete>
-    Removed as of 5/02/2011, replaced by Prerender.RendererPLT.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Perceived load time of a page. For non-prerendered pages, this is just
-    BeginToFinish. For displayed prerendered pages, this is the time from when
-    the prerendered page is moved into a TabContents until finish.
-    &quot;Finish&quot; == after onload() and all resources are loaded. Note that
-    this is 0 if the loading finishes before the page is moved into a
-    TabContents.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PerceivedLoadTime_PrerenderLoad" units="ms"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed as of 5/02/2011, replaced by Prerender.RendererPerceivedPLTMatched.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Perceived load time of a prerendered page that is displayed. This is the
-    time from when the prerendered page is moved into a TabContents until
-    finish. &quot;Finish&quot; == after onload() and all resources are loaded.
-    Note that this is 0 if the loading finishes before the page is moved into a
-    TabContents.
-  </summary>
-</histogram>
-
-<histogram name="PLT.Prerender_TimeUntilDisplay" units="ms"
-    expires_after="2014-06-23">
-  <obsolete>
-    Removed as of 5/02/2011, replaced by Prerender.RendererTimeUntilDisplay.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time elapsed between when the prerendering of a page starts and when the
-    page is displayed. Prerendered pages discarded without being displayed are
-    excluded from this count.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PrerenderIdleTime" units="ms" expires_after="2014-06-23">
-  <obsolete>
-    Removed as of 5/02/2011, replaced by Prerender.RendererIdleTime.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This is the time from when a prerendered page finishes loading to when it is
-    displayed. When a page is displayed before it finishes loading, no value is
-    recorded in this histogram.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT.NavigationStartToFirstLayout" units="ms"
-    expires_after="2016-03-10">
-  <obsolete>
-    Removed. Use PageLoad.Timing2.* instead.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's navigation start to the time the
-    first document layout is performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT.ResponseStartToFirstLayout" units="ms"
-    expires_after="2016-03-10">
-  <obsolete>
-    Removed. Use PageLoad.Timing2.* instead.
-  </obsolete>
-  <owner>bmcquade@chromium.org</owner>
-  <summary>
-    Measures the time from navigation timing's response start to the time the
-    first document layout is performed.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToCommit" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.Timing2.NavigationToCommit instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.BeginToCommit. Commit: responseStart. Begin: requestStart or
-    navigationStart if user-initiated request.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToCommit_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 9/2016. Use Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToCommit
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.BeginToCommit. Commit: responseStart. Begin: requestStart or
-    navigationStart if user-initiated request. Only page loads through the data
-    reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.BeginToFinish. Finish: loadEventEnd. Begin: requestStart or
-    navigationStart if user-initiated request.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToFinish_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 9/2016. Use Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.BeginToFinish_SpdyProxy. Finish: loadEventEnd. Begin:
-    requestStart or navigationStart if user-initiated request. Only page loads
-    through the data reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToFinishDoc" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.BeginToFinishDoc. FinishDoc: loadEventStart. Begin:
-    requestStart or navigationStart if user-initiated request.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_BeginToFinishDoc_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.BeginToFinishDoc_SpdyProxy. FinishDoc: loadEventStart. Begin:
-    requestStart or navigationStart if user-initiated request. Only page loads
-    through the data reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_CommitToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.CommitToFinish. Commit: responseStart. Finish: loadEventEnd.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_CommitToFinish_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.CommitToFinish. Commit: responseStart. Finish: loadEventEnd.
-    Only page loads through the data reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_CommitToFinishDoc" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.CommitToFinishDoc. Commit: responseStart. FinishDoc:
-    loadEventStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_CommitToFinishDoc_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.CommitToFinishDoc. Commit: responseStart. FinishDoc:
-    loadEventStart. Only page loads through the data reduction proxy are
-    considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_FinishDocToFinish" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    No longer needed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.FinishDocToFinish. Finish: loadEventEnd. FinishDoc:
-    loadEventStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_FinishDocToFinish_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.FinishDocToFinish. Finish: loadEventEnd. FinishDoc:
-    loadEventStart. Only page loads through the data reduction proxy are
-    considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToCommit" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.Timing2.NavigationToCommit instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and measures the time until
-    the renderer got first byte of document. Commit: time when renderer got
-    first byte of document. Request: navigationStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToDomContentLoaded" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and measures the time until
-    the beginning of the DOMContentLoaded event. DOMContentLoaded:
-    domContentLoadedEventStart. Request: navigationStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and is a more accurate
-    version of PLT.RequestToFinish. Finish: loadEventEnd. Request:
-    navigationStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToFinish_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016. Use
-    PageLoad.Clients.DataReductionProxy.DocumentTiming.NavigationToLoadEventFired
-    instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.RequestToFinish. Finish: loadEventEnd. Request:
-    navigationStart. Only page loads through the data reduction proxy are
-    considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToFinishDoc" units="ms"
-    expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the NavigationTiming spec and measures the page load
-    time until the beginning of the load event. Finish: loadEventStart. Request:
-    navigationStart.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_RequestToStart_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.RequestToStart. Start: requestStart. Request:
-    navigationStart. Only page loads through the data reduction proxy are
-    considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_StartToCommit_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.StartToCommit. Start: requestStart. Commit: responseStart.
-    Only page loads through the data reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.PT_StartToFinish_DataReductionProxy" units="ms"
-    expires_after="2016-09-08">
-  <obsolete>
-    Removed 09/2016.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    This time is based on the PerformanceTiming spec and is a more accurate
-    version of PLT.StartToFinish. Start: requestStart. Finish: loadEventEnd.
-    Only page loads through the data reduction proxy are considered.
-  </summary>
-</histogram>
-
-<histogram name="PLT.RequestToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;request&quot; to &quot;finish.&quot; &quot;Request&quot; ==
-    time when user requested document. &quot;Finish&quot; == after onload() and
-    all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="PLT.StartToCommit" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.Timing2.NavigationToCommit instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;start&quot; to &quot;commit.&quot; &quot;Start&quot;== time
-    when renderer requested load of document, after any unload of last document.
-    &quot;Commit&quot;== time when renderer got first byte of document.
-  </summary>
-</histogram>
-
-<histogram name="PLT.StartToFinish" units="ms" expires_after="2016-08-02">
-  <obsolete>
-    Use PageLoad.DocumentTiming.NavigationToLoadEventFired instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from &quot;start&quot; to &quot;finish.&quot; &quot;Start&quot;== time
-    when renderer requested load of document, after any unload of last document.
-    &quot;Finish&quot;==after onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="PLT.StartToFinish.NoProxy.http" units="units"
-    expires_after="2014-07-08">
-  <obsolete>
-    Removed as of 07/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>StartToFinish times when using http and no proxy.</summary>
-</histogram>
-
-<histogram name="PLT.StartToFinish.NoProxy.https" units="units"
-    expires_after="2014-07-08">
-  <obsolete>
-    Removed as of 07/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>StartToFinish times when using https and no proxy.</summary>
-</histogram>
-
-<histogram name="PLT.StartToFinish.Proxy.http" units="units"
-    expires_after="2014-07-08">
-  <obsolete>
-    Removed as of 07/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>StartToFinish times when using http over a proxy.</summary>
-</histogram>
-
-<histogram name="PLT.StartToFinish.Proxy.https" units="units"
-    expires_after="2014-07-08">
-  <obsolete>
-    Removed as of 07/2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>StartToFinish times when using https over a proxy.</summary>
-</histogram>
-
-<histogram name="PLT.UserTiming_Mark" units="ms" expires_after="2016-09-15">
-  <obsolete>
-    Removed as of 09/2016.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the User Timing spec and measures the time from
-    Navigation Timing navigationStart until the point where the page called
-    performance.mark().
-  </summary>
-</histogram>
-
-<histogram name="PLT.UserTiming_MeasureDuration" units="ms"
-    expires_after="2016-09-15">
-  <obsolete>
-    Removed as of 09/2016.
-  </obsolete>
-  <owner>pmeenan@chromium.org</owner>
-  <summary>
-    This time is based on the User Timing spec and reports the time between two
-    arbitrary points defined by the page being loaded and directly matches the
-    measurement exposed by performance.measure().
-  </summary>
-</histogram>
-
-<histogram name="Plugin.AvailabilityStatus.WidevineCdm"
-    enum="PluginAvailabilityStatus" expires_after="2018-01-11">
-  <obsolete>
-    Removed as of 01/2017 (M65).
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The availability status of Widevine CDM. In normal cases, this is reported
-    per render process if EME API is used. This is not reported if EME API is
-    not used. This could be reported multiple times per render process until
-    PLUGIN_AVAILABLE is reported (which should be a rare case).
-  </summary>
-</histogram>
-
-<histogram name="Plugin.EnabledStatusMigrationDone" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 06/2019 (M77).
-  </obsolete>
-  <owner>pastarmovj@chromium.org</owner>
-  <owner>tommycli@chromium.org</owner>
-  <summary>Tracks whether plugins that were disabled were migrated.</summary>
-</histogram>
-
-<histogram name="Plugin.Flash.ClickSize.AspectRatio" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Aspect ratio of Flash plugins users click at least once. The aspect ratio is
-    multiplied by 100 and stored as a rounded integer.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.Flash.ClickSize.Height" units="pixels"
-    expires_after="M77">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>Height of Flash plugins users click at least once.</summary>
-</histogram>
-
-<histogram name="Plugin.Flash.ClickSize.Width" units="pixels"
-    expires_after="M77">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>Width of Flash plugins users click at least once.</summary>
-</histogram>
-
-<histogram name="Plugin.Flash.Engagement" units="units"
-    expires_after="2017-12-13">
-  <obsolete>
-    Removed 12/2017 in Issue 781644 as we no longer use Site Engagement Index as
-    a signal for Flash display.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    The engagement score of origins which have passed through a site engagement
-    check to permit or block Flash. Recorded every time the Flash plugin is
-    requested with the PreferHtmlOverPlugins feature active.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.Flash.TinyContentSize" enum="FlashTinyContentSize"
-    expires_after="2020-03-22">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Collects the sizes of all loaded Flash plugin instances. This is for
-    determining the prevalence of tiny flash plugin instances.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.Flash.YouTubeRewrite" enum="YouTubeRewriteStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed from code 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    Records the YouTube Flash embed rewrite status when attempted.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.NpapiRemovalInfobar.Removed.PluginGroup"
-    enum="PluginGroup" expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    The plugin group of an NPAPI plugin that is no longer supported. Recorded
-    when the NPAPI removal infobar is shown for a plugin which is no longer
-    supported.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.NpapiRemovalInfobar.RemovedSoon.PluginGroup"
-    enum="PluginGroup" expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    The plugin group of an NPAPI plugin that will be unsupported soon. Recorded
-    when the NPAPI removal infobar is shown after an NPAPI plugin first loads to
-    warn the user that NPAPI support for this plugin will be removed soon.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.NPAPIStatus" enum="NPAPIPluginStatus"
-    expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    Records whether NPAPI plugins are supported by the platform, and if so,
-    whether they are enabled or disabled. Recorded once at browser startup.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PowerSaver.PeripheralHeuristic"
-    enum="PluginPowerSaverPeripheralHeuristicDecision"
-    expires_after="2016-08-10">
-  <obsolete>
-    Removed in favor of Plugin.PowerSaver.PeripheralHeuristicInitialDecision.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Records each decision of the Plugin Power Saver peripheral content
-    heuristic. This UMA is counted once per peripheral query, and may count a
-    single plugin instance multiple times as it is resized.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PowerSaver.PeripheralHeuristicInitialDecision"
-    enum="PluginPowerSaverPeripheralHeuristicDecision"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Records the initial decision of the Plugin Power Saver peripheral content
-    heuristic for each plugin instance. This is recorded once per plugin
-    instance.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PowerSaver.PosterParamPresence"
-    enum="PluginPowerSaverPosterParamPresence" expires_after="2020-03-29">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Record how many plugin object tags use poster param. This is recorded once
-    per plugin instance, and is currently restricted to Flash plugin instances.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.RequestObjectResult" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed from code 07/2019.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>Result of HTMLPluginElement::requestObject in Blink.</summary>
-</histogram>
-
-<histogram name="Plugin.SyncMessageTime" units="ms" expires_after="2016-04-11">
-  <obsolete>
-    Removed due to NPAPI removal.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Roundtrip times for synchronous IPC calls from the renderer to NPAPI plugin
-    processes.
-  </summary>
-</histogram>
-
-<histogram name="PluginFinder.BuiltInPluginList.ErrorCode"
-    enum="PluginListError" expires_after="M77">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>twellington@chromium.org</owner>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    Error codes when parsing the built-in plugin list. Logged when the
-    PluginFinder singleton is created.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryDischargePercentPerHour" units="%"
-    expires_after="2017-03-10">
-  <obsolete>
-    Removed 02/2017 in favor of power benchmarks that have less variability than
-    data from users' machines.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The percentage of battery capacity used per hour relative to a full battery.
-    Reported once when the power adaptor is plugged back in after the system is
-    on battery power for more than 30 minutes. If at any point the system is
-    suspended or all Chrome renderers are closed the measurement is not
-    recorded. Anytime the user unplugs the power adaptor, a new measurement will
-    begin being recorded. Collection of this histogram only starts after 30
-    minutes of uptime at which point the clock starts (assuming the user is on
-    battery power at that point). The system will need to remain unplugged for
-    at least another 30 minutes in order for any measurement to be recorded.
-    Values are normalized to a percent per hour scale. This measurement is tied
-    tightly to hardware model/OS and is not comparable across different hardware
-    configurations.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryDischargeRate_15" units="%"
-    expires_after="2017-03-10">
-  <obsolete>
-    Removed 02/2017 in favor of power benchmarks that have less variability than
-    data from users' machines.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The percent of depleted battery capacity relative to a full battery over the
-    first 15 minutes after battery power collection information starts.
-    Collection of this histogram only starts after 30 minutes of uptime at which
-    point the clock starts (assuming the user is on battery power at that
-    point). The system will need to remain unplugged for at least another 15
-    minutes in order for any measurement to be recorded. Values are normalized
-    to a percent per hour scale. This measurement is tied tightly to hardware
-    model/OS and is not comparable across different hardware configurations.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryDischargeRate_30" units="%"
-    expires_after="2017-03-10">
-  <obsolete>
-    Removed 02/2017 in favor of power benchmarks that have less variability than
-    data from users' machines.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The percent of depleted battery capacity relative to a full battery over the
-    first 30 minutes after battery power collection information starts.
-    Collection of this histogram only starts after 30 minutes of uptime at which
-    point the clock starts (assuming the user is on battery power at that
-    point). The system will need to remain unplugged for at least another 30
-    minutes in order for any measurement to be recorded. Values are normalized
-    to a percent per hour scale. This measurement is tied tightly to hardware
-    model/OS and is not comparable across different hardware configurations.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryDischargeRate_5" units="%"
-    expires_after="2017-03-10">
-  <obsolete>
-    Removed 02/2017 in favor of power benchmarks that have less variability than
-    data from users' machines.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The percent of depleted battery capacity relative to a full battery over the
-    first 5 minutes after battery power collection information starts.
-    Collection of this histogram only starts after 30 minutes of uptime at which
-    point the clock starts (assuming the user is on battery power at that
-    point). The system will need to remain unplugged for at least another 5
-    minutes in order for any measurement to be recorded. Values are normalized
-    to a percent per hour scale. This measurement is tied tightly to hardware
-    model/OS and is not comparable across different hardware configurations.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryRemainingCharge" units="%"
-    expires_after="2013-05-01">
-  <obsolete>
-    Removed as of 03/2012, no longer being generated by powerd.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    Chrome OS remaining battery charge as percent of the maximum battery charge
-    sampled when the device runs on battery.
-  </summary>
-</histogram>
-
-<histogram name="Power.BatteryTimeToEmpty" units="minutes"
-    expires_after="2013-05-01">
-  <obsolete>
-    Removed as of 03/2012, no longer being generated by powerd.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    Chrome OS remaining time to empty battery in minutes sampled when the device
-    runs on battery.
-  </summary>
-</histogram>
-
-<histogram name="Power.BrightnessAdjustOnAC" enum="PowerBrightnessAdjust"
-    expires_after="2013-05-25">
-  <obsolete>
-    Removed as of 5/2013. See Accel_BrightnessDown_F6 and Accel_BrightnessUp_F7
-    user actions instead.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    Number of times the user has adjusted brightness up and down while running
-    on battery power.
-  </summary>
-</histogram>
-
-<histogram name="Power.BrightnessAdjustOnBattery" enum="PowerBrightnessAdjust"
-    expires_after="2013-05-25">
-  <obsolete>
-    Removed as of 5/2013. See Accel_BrightnessDown_F6 and Accel_BrightnessUp_F7
-    user actions instead.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    Number of times the user has adjusted brightness up and down while running
-    on AC power.
-  </summary>
-</histogram>
-
-<histogram name="Power.ChargerType" enum="PowerChargerType"
-    expires_after="2014-11-20">
-  <obsolete>
-    Removed 11/2014 in issue 427057.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    External power supply type such as MAINS_CHARGER, USB_CHARGER,
-    UNCONFIRMED_SPRING_CHARGER, SAFE_SPRING_CHARGER. A sample is reported each
-    time a charger is connected to the device.
-  </summary>
-</histogram>
-
-<histogram name="Power.MilliConsumptionPerHourIosOnActive" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average power consumption, measured in milli-units per hour, when sync
-    invalidator listens to on_application_active events. Values for this metric
-    are per session, i.e. from battery level at application entering foreground
-    to returning to background, and normalized to an hourly average consumption.
-    This is an iOS only measurement. Due to how iOS reports battery levels, it
-    is likely to see many readings of 0.
-  </summary>
-</histogram>
-
-<histogram name="Power.MilliConsumptionPerHourOthers" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average power consumption, measured in milli-units per hour, for other
-    sync invalidator methods. Values for this metric are per session, i.e. from
-    battery level at application entering foreground to returning to background,
-    and normalized to an hourly average consumption. This is an iOS only
-    measurement. Due to how iOS reports battery levels, it is likely to see many
-    readings of 0.
-  </summary>
-</histogram>
-
-<histogram name="Power.MilliConsumptionPerHourP2P" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average power consumption, measured in milli-units per hour, when sync
-    invalidator uses peer-to-peer notifications. Values for this metric are per
-    session, i.e. from battery level at application entering foreground to
-    returning to background, and normalized to an hourly average consumption.
-    This is an iOS only measurement. Due to how iOS reports battery levels, it
-    is likely to see many readings of 0.
-  </summary>
-</histogram>
-
-<histogram name="Power.MilliConsumptionPerHourServer" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The average power consumption, measured in milli-units per hour, when sync
-    invalidator uses server-based non-blocking invalidator. Values for this
-    metric are per session, i.e. from battery level at application entering
-    foreground to returning to background, and normalized to an hourly average
-    consumption. This is an iOS only measurement. Due to how iOS reports battery
-    levels, it is likely to see many readings of 0.
-  </summary>
-</histogram>
-
-<histogram name="Power.RetrySuspendCount" units="units"
-    expires_after="2014-02-13">
-  <obsolete>
-    Removed Feb 2014 by Power.SuspendAttemptsBeforeCancel and
-    Power.SuspendAttemptsBeforeSuccess.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    The number of times Chrome OS retried suspend due to previous failure.
-  </summary>
-</histogram>
-
-<histogram name="Power.SuspendStatus" enum="SuspendStatus"
-    expires_after="2014-01-28">
-  <obsolete>
-    Removed Jan 2014 by Power.SuspendAttempt and Power.SuspendResult.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>Chrome OS suspend status.</summary>
-</histogram>
-
-<histogram name="Power.ThermalAbortedFanTurnOn" units="%"
-    expires_after="2014-08-12">
-  <obsolete>
-    No longer sent.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    The percentage of aborted fan attempts out of total fan attempts per
-    session, where an abort is due to hysteresis. This value is computed from
-    boot and sent when powerd starts and then every 15 minutes afterwards.
-  </summary>
-</histogram>
-
-<histogram name="Power.ThermalMultipleFanTurnOn" units="%"
-    expires_after="2014-08-12">
-  <obsolete>
-    No longer sent.
-  </obsolete>
-  <owner>tbroch@chromium.org</owner>
-  <summary>
-    The percentage of fan trip point passes that are more than one trip point.
-    This value is computed from boot and sent when powerd starts and then every
-    15 minutes afterwards.
-  </summary>
-</histogram>
-
-<histogram name="Precache.BatteryPercentage.Start" units="%"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    The battery level in percentage when the precache task was started.
-  </summary>
-</histogram>
-
-<histogram name="Precache.BatteryPercentageDiff.End" units="%"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>rajendrant@chromium.org</owner>
-  <summary>
-    Measures the difference between the battery level percentage when the
-    precache task is started and ended. This value indicates the possible
-    battery usage due to the precache task. Logged when the precache task ends,
-    which could be due to successful completion, time-out, error conditions, max
-    download limit exceeded, etc.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheSize.AllEntries" units="KB"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The size in kilobytes occupied by all the entries existing in the cache at
-    the time of the last precache.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheStatus.NonPrefetch" enum="HttpCachePattern"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Like HttpCache.Pattern but only for requests not made during precaching.
-    Logged per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheStatus.NonPrefetch.FromPrecache"
-    enum="HttpCachePattern" expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Like Precache.CacheStatus.NonPrefetch but only for requests which having a
-    matching URL in the precache. Measures the amount of precache misses due to
-    expiration or eviction. Logged per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheStatus.NonPrefetch.NonTopHosts"
-    enum="HttpCachePattern" expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>jamartin@chromium.org</owner>
-  <summary>
-    Like Precache.CacheStatus.NonPrefetch, but only for requests with a referer
-    not in the user's top visited hosts. See History.TopHostsVisitsByRank for
-    details on the top hosts computation.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheStatus.NonPrefetch.TopHosts"
-    enum="HttpCachePattern" expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>jamartin@chromium.org</owner>
-  <summary>
-    Like Precache.CacheStatus.NonPrefetch, but only for requests with a referer
-    in the user's top visited hosts. See History.TopHostsVisitsByRank for
-    details on the top hosts computation.
-  </summary>
-</histogram>
-
-<histogram name="Precache.CacheStatus.Prefetch" enum="HttpCachePattern"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>twifkak@chromium.org</owner>
-  <summary>
-    Like HttpCache.Pattern but only for requests made during precaching. Logged
-    per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.DownloadedNonPrecache" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The number of bytes that were downloaded over the network for HTTP/HTTPS
-    fetches that were not motivated by precaching. Logged per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.DownloadedPrecacheMotivated" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The number of bytes that were downloaded because of precaching. Logged
-    per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Events" enum="PrecacheEvents"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Enumerates the various failure reasons and events of interest for
-    precaching. The events are persisted when the native library is not loaded,
-    and recorded when the library loads next time.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.FailureReasons" units="units"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    A bit vector of reasons why the precache fetch failed to start. Bit values
-    are documented in the FailureReason Java enum.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.MinWeight" units="thousandths"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <summary>
-    The minimum resource weight that is fetched in a given precache run.
-    Reported if the precache completed successfully or was canceled due to the
-    byte cap, but not if it was cancelled due to an ill-formed manifest or
-    exceeding the time limit. Reported only if global_ranking is true.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.PercentCompleted" units="%"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The percent of manifests for which all resources have been downloaded.
-    Logged per prefetch run.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.ResponseBytes" units="bytes"
-    expires_after="2015-08-04">
-  <obsolete>
-    Removed July 29 2015.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of response bytes received from all prefetch requests,
-    including config, manifests, and resources. Logged per prefetch run.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.ResponseBytes.Daily" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <summary>
-    The total number of response bytes in 24 hours received over the network
-    from all prefetch requests, including config, manifests, and resources.
-    Logged during the next precache run after the 24 hours has elapsed.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.ResponseBytes.Network" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of response bytes received over the network from all
-    prefetch requests, including config, manifests, and resources. Logged per
-    prefetch run.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.ResponseBytes.NetworkWasted" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of response bytes received over the network for a wasted
-    resource precache fetch. Logged when a partially downloaded resource
-    precache fetch gets cancelled due to per-resource size limit or max precache
-    size limit.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.ResponseBytes.Total" units="bytes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total number of response bytes contained in all prefetch requests,
-    including config, manifests, and resources. Logged per prefetch run.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Fetch.TimeToComplete" units="ms"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The time, in milliseconds, to complete a prefetch run. Only applies to
-    non-cancelled runs (those for which PercentCompleted is 100).
-  </summary>
-</histogram>
-
-<histogram name="Precache.Freshness.Prefetch" units="seconds"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The freshness lifetimes of the resources that were precached from the moment
-    they were fetched or revalidated as described in RFC 2616 13.2.4. Logged per
-    precache request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Latency.NonPrefetch" units="ms"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed March 7 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The latency for requests that were not made during precaching. Logged
-    per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Latency.NonPrefetch.NonTopHosts" units="ms"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed March 7 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Like Precache.Latency.NonPrefetch, but limited to requests with a referer
-    not in the user's top visited hosts. See History.TopHostsVisitsByRank for
-    details on the top hosts computation.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Latency.NonPrefetch.TopHosts" units="ms"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed March 7 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    Like Precache.Latency.NonPrefetch, but limited to requests with a referer in
-    the user's top visited hosts. See History.TopHostsVisitsByRank for details
-    on the top hosts computation.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Latency.Prefetch" units="ms"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed March 7 2017.
-  </obsolete>
-  <owner>twifkak@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The latency for requests that were made during precaching. Logged
-    per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.PeriodicTaskInterval" units="minutes"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>rajendrant@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The time between successive precache periodic GCM task invocations. When
-    precache task is started, the time interval from previous task invocation is
-    logged.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Saved" units="bytes" expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The number of bytes during user browsing that were served from the cache,
-    but would have been downloaded over a network if precaching was disabled.
-    Logged per-request.
-  </summary>
-</histogram>
-
-<histogram name="Precache.Saved.Freshness" units="seconds"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The freshness lifetimes (RFC 2616 13.2.4) of the resources that were
-    precached and later used (and thus served from the cache). This is computed
-    at serving time and thus possibly different from the precached value if the
-    cache entry was revalidated. Logged per-request but only once per URL and
-    precaching cycle (as Precache.Saved).
-  </summary>
-</histogram>
-
-<histogram name="Precache.TimeSinceLastPrecache" units="seconds"
-    expires_after="2017-07-12">
-  <obsolete>
-    Removed July 11 2017.
-  </obsolete>
-  <owner>jamartin@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The time between the the beginning of the last precache session and each of
-    the URL fetches made by the user ever since. Logged per-request.
-  </summary>
-</histogram>
-
-<histogram name="Prefetch.Redirect" enum="PrefetchRedirect"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed March 31 2020.
-  </obsolete>
-  <owner>dom@chromium.org</owner>
-  <owner>yhirano@chromium.org</owner>
-  <owner>yoavweiss@chromium.org</owner>
-  <summary>
-    Recorded when a prefetch request is made, and when a prefetch request is
-    redirected. Specifically, PrefetchURLLoader::PrefetchURLLoader records
-    &quot;Prefetch request made&quot;, and PrefetchURLLoader::FollowRedirect
-    records one of the two redirection values. This is to collect data on how
-    often prefetch requests experience redirects. Note that when the
-    PrefetchRedirectError flag is enabled, no events are recorded. We do not
-    want to interact with this histogram when we're experimenting with the
-    redirect mode for prefetch requests.
-  </summary>
-</histogram>
-
-<histogram name="PrefService.CreateProfilePrefsTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>The amount of time that elapsed during CreateProfilePrefs.</summary>
-</histogram>
-
-<histogram name="PrefService.NetworkPredictionEnabled" enum="BooleanEnabled"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019. No longer needed.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <summary>
-    Count events where Network Prediction was enabled or disabled.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.Counts" units="preloads"
-    expires_after="2016-05-25">
-  <obsolete>
-    Removed 5/25/2016 in favor of PreloadScanner.Counts2
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>The number of preloads generated by the preload scanner.</summary>
-</histogram>
-
-<histogram name="PreloadScanner.Counts.Miss" units="preloads"
-    expires_after="2016-05-25">
-  <obsolete>
-    Removed 5/25/2016 in favor of PreloadScanner.Counts2.Miss
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of unused preloads generated by the preload scanner. Note that
-    some link rel preloads are not referenced until after this point, so they
-    will be falsely marked as preload misses. These will show up in the Raw
-    bucket.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.Counts2" units="preloads"
-    expires_after="2018-02-06">
-  <obsolete>
-    Removed Feb 2018, no longer useful.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>The number of preloads generated by the preload scanner.</summary>
-</histogram>
-
-<histogram name="PreloadScanner.Counts2.Miss" units="preloads"
-    expires_after="2018-02-06">
-  <obsolete>
-    Removed Feb 2018, no longer useful.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of unused preloads generated by the preload scanner. Note that
-    some link rel preloads are not referenced until after this point, so they
-    will be falsely marked as preload misses.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.DocumentWrite.ExecutionTime.Failure" units="ms"
-    expires_after="2017-07-27">
-  <obsolete>
-    DocumentWriteEvaluator was removed in 07/2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Time spent executing a script tag in the blink preload scanner, for the
-    purpose of preloading scripts that will be fetched via a call to
-    document.write. The execution failed to generate a preload request.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.DocumentWrite.ExecutionTime.Success" units="ms"
-    expires_after="2017-07-27">
-  <obsolete>
-    DocumentWriteEvaluator was removed in 07/2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Time spent executing a script tag in the blink preload scanner, for the
-    purpose of preloading scripts that will be fetched via a call to
-    document.write. The execution successfully resulted in a preload request.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.DocumentWrite.GatedEvaluation"
-    enum="DocumentWriteGatedEvaluation" expires_after="2017-07-27">
-  <obsolete>
-    DocumentWriteEvaluator was removed in 07/2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The reason a particular inline script was blocked from evaluation.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.DocumentWrite.InitializationTime" units="ms"
-    expires_after="2017-07-27">
-  <obsolete>
-    DocumentWriteEvaluator was removed in 07/2017
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Time spent initializing a new V8 context for the purpose of evaluating it
-    and preloading document.written strings.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.DocumentWrite.ScriptLength" units="characters"
-    expires_after="2016-12-07">
-  <obsolete>
-    No longer needed
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The length of the inline script that is being considered for document write
-    evaluation.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.ExternalCSS.PreloadCount" units="preloads"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed August 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The number of preloads generated by scanning an external preloaded CSS
-    resource. As of 4/25/2016 this only includes @import declarations.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.ExternalCSS.ScanTime" units="microseconds"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed August 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Microseconds it took to scan the first chunk of external CSS for preloads.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.ReferenceTime" units="ms"
-    expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time between preload discovery and when the resource is actually
-    referenced. This is implemented by marking when a preload is discovered by
-    the scanner, and when it has its first ResourceClient added to it. Note that
-    for link rel preloads, this tracks the time from scanner discory to DOM
-    discovery of the link declaration, not the actual resource.
-  </summary>
-</histogram>
-
-<histogram name="PreloadScanner.TTFB" units="ms" expires_after="2018-05-15">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time between preload discovery and when the first bytes of the response
-    data arrive.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.AbandonTimeUntilUsed" units="ms"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09 as prerenders can no longer be 'used' (=='swapped-in').
-  </obsolete>
-  <owner>davidben@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a prerendered page is abandoned to when it is first used due
-    to user navigation. If the page is swapped before begin abandoned, a zero is
-    recorded.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.CookieSendType" enum="PrerenderCookieSendType"
-    expires_after="2015-03-13">
-  <obsolete>
-    Removed March 13 2015.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Enumeration of what types of cookies were sent for a prerender.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.CookieStatus" enum="PrerenderCookieStatus"
-    expires_after="2015-03-13">
-  <obsolete>
-    Removed March 13 2015.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>Enumeration of what cookie actions a prerender caused.</summary>
-</histogram>
-
-<histogram name="Prerender.Event" enum="PrerenderEvent"
-    expires_after="2015-01-14">
-  <obsolete>
-    Removed Dec 12 2014.
-  </obsolete>
-  <summary>
-    Enumeration of what events related to prerendering have occurred.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.Events" enum="PrerenderHoverEvent"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated May 10 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Hover Event counts for prerendering.</summary>
-</histogram>
-
-<histogram name="Prerender.FinalStatusMatchComplete"
-    enum="PrerenderFinalStatus" expires_after="2016-05-12">
-  <obsolete>
-    deprecated 2016-05-12
-  </obsolete>
-  <summary>
-    Final status for prerender pages - either success, or why it was canceled.
-    This is for the MatchComplete set of pages (including some pages that were
-    not actually prerendered), to match the control group.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.FractionPixelsFinalAtSwapin" units="units"
-    expires_after="2014-01-15">
-  <obsolete>
-    Removed Jan 14 2014.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For prerenders that are swapped in, the percentage of pixels that is already
-    final at swap-in time compared to when the spinner stops.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.HoverStats_TimeUntilClicked" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated May 10 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Duration that a user hovers a link before clicking on it.
-
-    This is recorded for all pages loaded in a session.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.HoverStats_TimeUntilDiscarded" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated May 10 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Duration that the mouse pointer hovers on a link before the mouse pointer
-    moves off of it.
-
-    This is recorded for all pages loaded in a session.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorEvent"
-    enum="PrerenderLocalPredictorEvents" expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Enumeration of what events related to the local predictor have occurred
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorLoggedInLookupTime" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time to perform the LoggedIn Lookup for the local predictor. This operation
-    checks whether a user is likely logged into a page that we would like to
-    prerender.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorPrefetchMatchPLT" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The PrerenderLocalPredictor uses local browsing history and the prerender
-    service to predict pages likely visited soon. Some of these URLs are
-    prefetched. When such prefetched likely next pages are visited, this
-    histogram records the PLT for such pages. In particular, this also happens
-    if prefetch is actually disabled, allowing (by pivoting on whether or not
-    prefetch is enabled) to compare the effect of prefetch on PLT.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorServiceLookupTime" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time to perform the Service Lookup for the local predictor. This operation
-    queries a Google service to obtain pages to prerender, as well as whether
-    prerender candidate pages are likely safe for prerendering.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorTimeUntilUsed" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a prerendered page is started to when it is first used due to
-    user navigation. If the page is never used, it is not included in this
-    histogram. This only refers to prerenders based on the local predictor.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalPredictorURLLookupTime" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time to perform the URL Lookup for the local predictor. This operation
-    retrieves from the user's local browsing history the URLs corresponding to
-    URLIDs.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalVisitCoreTransition" enum="CorePageTransition"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The transition type for each new visit as recorded in the local visits
-    database.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.LocalVisitDatabaseSize" units="units"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Size of the local visits database (number of entries).</summary>
-</histogram>
-
-<histogram name="Prerender.LocalVisitEvents" enum="PrerenderLocalVisitEvents"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Enumeration of what events related to local visits have occurred
-  </summary>
-</histogram>
-
-<histogram name="Prerender.ModPagespeedHeader" units="units"
-    expires_after="2013-10-21">
-  <obsolete>
-    Removed as of 10/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Previous version of the Prerender.PagespeedHeader.* histograms.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.NetworkBytes.TotalForProfile" units="bytes"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed May 13th 2014, use Prerender.NetworkBytesTotalForProfile instead.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Number of bytes transferred on the network for URLRequests (not including
-    HTTP/TLS/TCP/IP overhead). Reported on event of a PrerenderContents
-    deletion. Includes prerender bytes. Bytes are only counted when prerendering
-    is enabled and not in a control group. The sum of the distribution for a
-    single user represents all of that user's network transfers for resource for
-    that time period while prerendering was enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.NetworkBytes.Used" units="bytes"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed May 13th 2014, use Prerender.NetworkBytes.Used instead.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Number of bytes transferred on the network for URLRequests (not including
-    HTTP/TLS/TCP/IP overhead) for a prerender that was used (or would have been
-    used).
-  </summary>
-</histogram>
-
-<histogram name="Prerender.NetworkBytes.Wasted" units="bytes"
-    expires_after="2014-05-15">
-  <obsolete>
-    Removed May 13th 2014, use Prerender.NetworkBytes.Wasted instead.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Number of bytes transferred on the network for URLRequests (not including
-    HTTP/TLS/TCP/IP overhead) for a prerender that was not used.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.NetworkBytesUsed" units="bytes"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09 as prerenders can no longer be 'used' (=='swapped-in').
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Number of bytes transferred on the network for URLRequests (not including
-    HTTP/TLS/TCP/IP overhead) for a prerender that was used (or would have been
-    used).
-  </summary>
-</histogram>
-
-<histogram name="Prerender.NoStatePrefetchAge" units="ms"
-    expires_after="2017-01-02">
-  <obsolete>
-    Removed December 28, 2016, use Prerender.PrefetchAge instead.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>mattcary@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>Time between the prefetch and the actual load of the page.</summary>
-</histogram>
-
-<histogram name="Prerender.OmniboxNavigationsCouldPrerender" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed 2020-04, as NoStatePrefetch is launched everywhere.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    A boolean that indicates whether the Omnibox navigation being committed
-    could have been prerendered by the Omnibox Prerender system. This provides
-    an upper bound for Prerender.OmniboxNavigationsUsedPrerenderCount and allows
-    the potential for Omnibox Prerendering coverage to be understood. If Omnibox
-    Prerendering is disabled, this histogram will register a 'false' entry. The
-    total count is the equivalent of the deprecated
-    NetworkActionPredictor.NavigationCount histogram.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.OmniboxNavigationsUsedPrerenderCount" units="units"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09 as prerenders can no longer be 'used' (=='swapped-in').
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The number of navigations that use a prerender initiated from the Omnibox.
-    The count is incremented when the Prerendered tab is swapped in if the
-    Prerender was initiated by the Omnibox, which obviously requires
-    Prerendering from the Omnibox to be enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.OmniboxPrerenderCount" units="units"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The number of prerenders initiated from the Omnibox. This is incremented
-    when the NetworkActionPredictor suggests Prerendering as an optimal strategy
-    given the text the user has entered and the Autocomplete suggestion
-    currently selected. It is only incremented if Prerendering from the Omnibox
-    is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PagespeedHeader.ServerCounts"
-    enum="PagespeedHeaderServerType" expires_after="2018-04-25">
-  <obsolete>
-    Removed April 2018
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The number of responses received bucketed into the range [0,4]: bucket 0 is
-    the total number of responses received; bucket 1 is the number of responses
-    received with an X-Mod-Pagespeed header [indicating a mod_pagespeed server];
-    bucket 2 is the number of responses received with an X-Page-Speed header and
-    a header value in the X-Mod-Pagespeed format (a.b.c.d-e) [indicating an
-    ngx_pagespeed server]; bucket 3 is the number of responses received with an
-    X-Page-Speed header and a header value in the PageSpeed Service format
-    (a_b_c) [indicating a PSS server]; and bucket 4 is the number of responses
-    received with an X-Page-Speed header and a header value in neither of the
-    preceding formats [indicating some other server; IISpeed is the only known
-    one at this stage].
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PagespeedHeader.VersionCounts"
-    enum="PagespeedVersion" expires_after="2018-04-25">
-  <obsolete>
-    Removed April 2018
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The number of responses received that either have an X-Mod-Pagespeed header
-    or have an X-Page-Speed header with a value in the X-Mod-Pagespeed format
-    (a.b.c.d-e), bucketed into the range [1,99]: bucket 1 is for header values
-    that aren't in the a.b.c.d-e format, the remaining buckets are an encoding
-    of the value: 2 + 2 * (max(c, 10) - 10) + (d &gt; 1 ? 1 : 0). The rationale
-    is that 'c' is incremented with each new release and 'd' is initially 0 but
-    is incremented for each patch to a release.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PageviewEvents" enum="PrerenderPageviewEvents"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Types of pages rendered.</summary>
-</histogram>
-
-<histogram name="Prerender.PageVisitedStatus" enum="Boolean"
-    expires_after="2015-03-30">
-  <obsolete>
-    deprecated March 30, 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Indicates whether the user has ever visited (in the past) a URL for which a
-    prerender is launched.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_Control" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLT_ContentPrefetchPrerenderControl.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This particular histogram is for all page loads for users who do not have
-    prerendering enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_PrerenderMatchControl"
-    units="ms" expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLTMatched_ContentPrefetchPrerenderControl.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This particular histogram is only for pages that would have been prerendered
-    if the user had prerender enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_PrerenderMatchTreatment"
-    units="ms" expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLTMatched_ContentPrefetchPrerender.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This particular histogram is for all prerendered page loads for users who
-    have prerender enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_Treatment" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLT_ContentPrefetchPrerender.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This particular histogram is for all page loads for users who have
-    prerendering enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_WindowControl" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLTWindowed_ContentPrefetchPrerenderControl.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This particular histogram is for all page loads within 30 seconds after a
-    prefetch tag is seen for users who do not have prerendering enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPageLoadTime_WindowTreatment" units="ms"
-    expires_after="2013-05-15">
-  <obsolete>
-    Removed 03/24/11. Replaced by
-    Prerender.PerceivedPLTWindowed_ContentPrefetchPrerender.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load pre navigation.
-
-    This particular histogram is for all page loads within 30 seconds after a
-    prefetch tag is seen for users who have prerendering enabled.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLT" units="ms" expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded for all pages loaded in a session.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTFirstAfterMiss" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded for the first page load completing immediately after a
-    prerender.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTFirstAfterMissAnyOnly" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    &quot;FirstAfterMiss&quot; means the first pageload after a prerender miss.
-    There are two types: Any, and Non-overlapping. The latter only applies to
-    page loads initiated after the prerender. This variable records cases where
-    only Any triggered.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTFirstAfterMissBoth" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    &quot;FirstAfterMiss&quot; means the first pageload after a prerender miss.
-    There are two types: Any, and Non-overlapping. The latter only applies to
-    page loads initiated after the prerender. This variable records cases where
-    both triggered.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTFirstAfterMissNonOverlapping" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded for the first page load completing immediately after a
-    prerender, but which has also started after the prerender has been
-    initiated.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTFirstAfterMissNonOverlappingOnly"
-    units="ms" expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    &quot;FirstAfterMiss&quot; means the first pageload after a prerender miss.
-    There are two types: Any, and Non-overlapping. The latter only applies to
-    page loads initiated after the prerender. This variable records cases where
-    only Non-overlapping triggered.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTMatched" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded only for prerendered pages, or for pages which would have
-    been prerendered in the control case.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTMatchedComplete" units="ms"
-    expires_after="2016-12-22">
-  <obsolete>
-    Removed August 2016
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded only for prerendered pages, or for pages which would have
-    been prerendered in the control case.
-
-    In MatchedComplete, the prerender group also contains cancelled prerenders,
-    so as to produce a perfect match of page views attributed this group in the
-    prerender group with those attributed to this group in the control group.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTWindowed" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded for all page loads which happen within 30 seconds after a
-    prefetch tag is observed.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedPLTWindowNotMatched" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a user navigates to a page to when it loads. Since the pages
-    may start loading before the user navigates to it, this does not include any
-    portion of load prior to navigation.
-
-    This is recorded for all page loads which happen within 30 seconds after a
-    prefetch tag is observed and which do not correspond to a prerender tag.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PerceivedTTFCPRecorded" enum="BooleanRecorded"
-    expires_after="2019-03-05">
-  <obsolete>
-    Obsoleted in Feb 2019.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>mattcary@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Whether the perceived Time to First Contentful Paint (TTFCP) was recorded
-    successfully for a prerendered page. Since a prerendered page will start
-    loading before a user navigates to it, the perceived TTFCP does not include
-    an time prior to the user navigation. If true, there is an associated
-    PrefetchTTFCP that records the TTFCP from the swapped-in navigation start.
-    If false, no PrefetchTTFCP was recorded.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PercentLoadDoneAtSwapin" units="units"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09 as prerenders can no longer be 'used' (=='swapped-in').
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For prerenders that are swapped in, the percentage of the time from load
-    start until the onload event fires that has elapsed at the time of the
-    swapin.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PeriodicCleanupDeleteContentsTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    How long the cleanup portion of PrerenderManager::PeriodicCleanup takes, to
-    measure jank.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PeriodicCleanupResourceCheckTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    How long the resource check portion of PrerenderManager::PeriodicCleanup
-    takes, to measure jank.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PrefetchAge" units="ms" expires_after="M85">
-  <obsolete>
-    Deprecated July 2020
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>mattcary@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time between a prefetch or effective prefetch and the actual load of the
-    page. For NoState prefetch, this is the time of the actual prefetch. For
-    prerendering, it is the time that prerender began. For control groups in
-    NoState prefetch experiments, it is the time that prefetch would have
-    occurred.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PrefetchTTFCP" units="ms" expires_after="M85">
-  <obsolete>
-    Deprecated July 2020
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>mattcary@chromium.org</owner>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time to first contentful paint (TTFCP) for navigations related to prefetch
-    (including prerender, no-state prefetch, and associated experiments). This
-    measures user-visible TTFCP. For no-state prefetch this is standard
-    navigation-to-FCP; for prerender this is the time from navigation start when
-    the prerender is swapped in to FCP.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PrerenderCountOf3Max" units="units"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    After launching a prerender, how many simultanious prerenders are recorded
-    as running, out of a maximum of three.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PrerenderNotSwappedInPLT" units="ms"
-    expires_after="2017-03-31">
-  <obsolete>
-    Removed 2017-03.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For prerenders that finish loading before they are ever swapped in, their
-    page load time until the onload event fires.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.PrerenderStartToReleaseContentsTime" units="ms"
-    expires_after="2020-11-01">
-  <obsolete>
-    Removed 2020-05-07
-  </obsolete>
-  <owner>justincohen@chromium.org</owner>
-  <summary>
-    This is the time from when a prerendered page begins to load to when it is
-    swapped in as the main page load. Recorded when the swap occurs, only on
-    iOS.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RelTypesLinkAdded" enum="PrerenderRelTypes"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For each prerender link added to a document, records the rel types present
-    on the link element.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RelTypesLinkStarted" enum="PrerenderRelTypes"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For each prerender in a document which starts prerendering, records the rel
-    types present on the link element.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RendererIdleTime" units="ms"
-    expires_after="2013-04-25">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This is the time from when a prerendered page finishes loading to when it is
-    displayed, as measured by the renderer process. When a page is displayed
-    before it finishes loading, no value is recorded in this histogram.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RendererPerceivedPLT" units="ms"
-    expires_after="2013-04-25">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Perceived load time of a page, as measured by the renderer process. For
-    non-prerendered pages, this is just BeginToFinish. For displayed prerendered
-    pages, this is the time from when the prerendered page is moved into a
-    TabContents until finish. &quot;Finish&quot; == after onload() and all
-    resources are loaded. Note that this is 0 if the loading finishes before the
-    page is moved into a TabContents.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RendererPerceivedPLTMatched" units="ms"
-    expires_after="2013-04-25">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Perceived load time of a prerendered page that is displayed, as measured by
-    the renderer process. This is the time from when the prerendered page is
-    moved into a TabContents until finish. &quot;Finish&quot; == after onload()
-    and all resources are loaded. Note that this is 0 if the loading finishes
-    before the page is moved into a TabContents.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.RendererTimeUntilDisplay" units="ms"
-    expires_after="2013-04-25">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time elapsed between when the prerendering of a page starts and when the
-    page is displayed, as measured by the renderer process. Prerendered pages
-    discarded without being displayed are excluded from this count.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.SchemeCancelReason"
-    enum="PrerenderSchemeCancelReason" expires_after="M77">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The detailed reason why a prerender is canceled with
-    FINAL_STATUS_UNSUPPORTED_SCHEME
-  </summary>
-</histogram>
-
-<histogram name="Prerender.Sessions" enum="PrerenderMode"
-    expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Enumeration of how prerender was used per session.</summary>
-</histogram>
-
-<histogram name="Prerender.SessionStorageNamespaceMergeTime" units="ms"
-    expires_after="2015-01-14">
-  <obsolete>
-    Removed Dec 12 2014.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>Time to perform the session storage namespace merge.</summary>
-</histogram>
-
-<histogram name="Prerender.SimulatedLocalBrowsingBaselinePLT" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For simulated local browsing prerendering, the baseline PLT of pages without
-    any prerendering for pages that would be prerendered.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.SimulatedLocalBrowsingPLT" units="ms"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    For simulated local browsing prerendering, the estimated PLT of pages with
-    prerendering enabled for pages that would be prerendered.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.TabContentsDeleterSuppressedDialog"
-    enum="BooleanSuppressed" expires_after="M85">
-  <obsolete>
-    Obsoleted in Dec 2019.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    A boolean that indicates how often we suppress a dialog from a tab when
-    swapping it with a prerender.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.TabHelperEvent" enum="PrerenderTabHelperEvents"
-    expires_after="2015-04-17">
-  <obsolete>
-    Removed April 2015
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Enumeration of what events related to the TabHelper class have occurred.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.TimeBetweenPrerenderRequests" units="ms"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>Time between subsequent prerender requests.</summary>
-</histogram>
-
-<histogram name="Prerender.TimeSinceLastRecentVisit" units="ms"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    The time elapsed between the most recent visit to a URL and when an
-    attempted prerender of the same URL is cancelled with
-    FINAL_STATUS_RECENTLY_VISITED.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.TimeToClick" units="ms" expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Duration that a user hovers a link before clicking on it.</summary>
-</histogram>
-
-<histogram name="Prerender.TimeUntilUsed" units="ms" expires_after="2013-05-15">
-  <obsolete>
-    deprecated Nov 16 2012. See Prerender.TimeUntilUsed2, which has a larger
-    range.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time from when a prerendered page is started to when it is first used due to
-    user navigation. If the page is never used, it is not included in this
-    histogram.
-  </summary>
-</histogram>
-
-<histogram name="Prerender.TimeUntilUsed2" units="ms"
-    expires_after="2017-09-06">
-  <obsolete>
-    Removed 2017-09 as prerenders can no longer be 'used' (=='swapped-in').
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    Time from when a prerendered page is started to when it is first used due to
-    user navigation. If the page is never used, it is not included in this
-    histogram.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ContextMenuAction.LoFi"
-    enum="PreviewsContextMenuActionLoFi" expires_after="M80">
-  <obsolete>
-    Functionality removed in M77.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    User interactions with the Lo-Fi context menu options. These include:
-
-    Displays and clicks on the &quot;Load image&quot; and &quot;Load
-    images&quot; context menu options. Count of pages where the user has clicked
-    &quot;Load image&quot; at least once.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintCacheLevelDBStore.LoadMetadataResult"
-    enum="PreviewsHintCacheLevelDBStoreLoadMetadataResult" expires_after="M81">
-  <obsolete>
-    Replaced by OptimizationGuide.HintCacheLevelDBStore.LoadMetadataResult in
-    07/2019.
-  </obsolete>
-  <owner>jegray@chromium.org</owner>
-  <summary>
-    Records the result of loading the metadata while initializing the
-    HintCacheLevelDBStore.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintCacheLevelDBStore.Status"
-    enum="PreviewsHintCacheLevelDBStoreStatus" expires_after="M80">
-  <obsolete>
-    Replaced by OptimizationGuide.HintCacheLevelDBStore.LoadMetadataResult in
-    07/2019.
-  </obsolete>
-  <owner>jegray@chromium.org</owner>
-  <summary>
-    Records each status change within the HintCacheLevelDBStore.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintCacheStore.OnLoadHint.FetchedHintExpired"
-    enum="BooleanExpired" expires_after="M80">
-  <obsolete>
-    Replaced by OptimizationGuide.HintCacheLevelDBStore.LoadMetadataResult in
-    07/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records that a fetched hint loaded from the store has expired. If expired,
-    the hint is not provided.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintsFetcher.GetHintsRequest.HostCount"
-    units="total host count" expires_after="M77">
-  <obsolete>
-    Replaced by OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount in
-    06/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the number of hosts selected for sending a OnePlatform client hint
-    request. This will be captured when any OnePlatform client hint request is
-    initiated.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintsFetcher.GetHintsRequest.NetErrorCode"
-    enum="NetErrorCodes" expires_after="M77">
-  <obsolete>
-    Replaced by OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode in
-    06/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Net error codes for HintsFetch requests to the Optimization Guide Service on
-    success and failure.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintsFetcher.GetHintsRequest.Status"
-    enum="HttpResponseCode" expires_after="M77">
-  <obsolete>
-    Replaced by OptimizationGuide.HintsFetcher.GetHintsRequest.Status in
-    06/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    For each HintsFetch request to the Optimization Guide Service, log the HTTP
-    response code on success and failure.
-  </summary>
-</histogram>
-
-<histogram
-    name="Previews.HintsFetcher.TopHostProvider.BlacklistSize.OnInitialize"
-    units="total host count" expires_after="M77">
-  <obsolete>
-    Replaced by
-    OptimizationGuide.HintsFetcher.TopHostProvider.BlacklistSize.OnInitialize in
-    06/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the number of hosts placed on the HintsFetcherTopHostBlacklist when
-    it is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Previews.HintsFetcher.TopHostProvider.BlacklistSize.OnRequest"
-    units="total host count" expires_after="M77">
-  <obsolete>
-    Replaced by
-    OptimizationGuide.HintsFetcher.TopHostProvider.BlacklistSize.OnRequest in
-    06/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the number of hosts on the HintsFetcherTopHostBlacklist when top
-    hosts are requested.
-  </summary>
-</histogram>
-
-<histogram name="Previews.InfoBarAction" enum="PreviewsInfoBarAction"
-    expires_after="M80">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>bengr@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    User interactions with the previews &quot;Saved data&quot; infobar. These
-    include:
-
-    Displays of the infobar and clicks on the &quot;Load original&quot; link.
-    Whether the infobar was dismissed by navigation or the user clicking on
-    &quot;X&quot; close button.
-  </summary>
-</histogram>
-
-<histogram name="Previews.InfoBarTimestamp" enum="PreviewsInfoBarTimestamp"
-    expires_after="2018-09-27">
-  <obsolete>
-    Replaced by Previews.StalePreviewTimestampShown as of 09/2018.
-  </obsolete>
-  <owner>megjablon@chromium.org</owner>
-  <summary>
-    Whether the timestamp for a stale preview was shown on the infobar. If the
-    timestamp was not shown, states the reason why.
-  </summary>
-</histogram>
-
-<histogram name="Previews.Offline.CommittedErrorPage" enum="BooleanError"
-    expires_after="M90">
-  <obsolete>
-    Offline Previews functionality removed in M86.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Whether or not an offline preview that was committed showed an error page.
-    This metric is recorded every time an offline preview is committed.
-  </summary>
-</histogram>
-
-<histogram name="Previews.Offline.FalsePositivePrevention.Allowed"
-    enum="BooleanAllowed" expires_after="M85">
-  <obsolete>
-    Offline Previews functionality removed in M86.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Whether or not the navigated URL was allowed to trigger an offline preview.
-    This is done by checking an in-memory cache of all available offline
-    previews which is designed to prevent false positive triggering. This metric
-    is recorded on every preview eligible navigation when the
-    OfflinePreviewsFalsePositivePrevention feature is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Previews.Offline.FalsePositivePrevention.PrefSize"
-    units="count of entries" expires_after="M85">
-  <obsolete>
-    Offline Previews functionality removed in M86.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of entries in the false positive prevention pref. This is
-    recorded every time we update the pref from a DB query, at most once per
-    session.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OmniboxLiteStringShown" enum="BooleanShown"
-    expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Whether the verbose status string was shown on a Preview page. This is
-    recorded on every transition from a non-preview page to a preview page. An
-    entry of false means that the Previews Icon appeared without the
-    &quot;Lite&quot; string only because there was not enough room to show the
-    string.
-
-    Note that it is possible for the Lite string to not be shown on the page
-    after true is recorded if the user rotates their device or enters
-    multi-window mode while viewing the page, or the converse.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Previews.OptimizationFilterStatus"
-    enum="PreviewsOptimizationFilterStatus" expires_after="M77">
-  <obsolete>
-    Removed in favor of OptimizationGuide.OptimizationFilterStatus as of
-    07/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Status of processing OptimizationFilter configurations for server-provided
-    blacklists. Recorded when the PreviewsOptimizationGuide receives a
-    notification to process hints.
-  </summary>
-</histogram>
-
-<histogram
-    name="Previews.OptimizationGuide.HintCache.FetchedHint.TimeToExpiration"
-    units="seconds" expires_after="M78">
-  <obsolete>
-    Removed in favor of OptimizationGuide.HintCache.FetchedHint.TimeToExpiration
-    as of 08/2019.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    The remaining time a fetched hint that was loaded for use has before it
-    expires and is removed from the hint cache store.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptimizationGuide.HintCache.HasHint.AtCommit"
-    enum="NQEEffectiveConnectionType" expires_after="M80">
-  <obsolete>
-    Removed in favor of OptimizationGuide.HintCache.HasHint.AtCommit as of
-    08/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the effective connection type when the optimization guide hint cache
-    has a hint entry for a URL's host at commit time.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptimizationGuide.HintCache.HasHint.BeforeCommit"
-    enum="NQEEffectiveConnectionType" expires_after="M80">
-  <obsolete>
-    Removed in favor of OptimizationGuide.HintCache.HasHint.BeforeCommit as of
-    08/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the effective connection type when the optimization guide hint cache
-    has a hint entry for a URL's host before commit time (e.g., at original
-    navigation time or redirected navigation time).
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptimizationGuide.HintCache.HintType.Loaded"
-    enum="HintCacheStoreEntryType" expires_after="M79">
-  <obsolete>
-    Replaced by OptimizationGuide.HintCache.HintType.Loaded in 07/19.
-  </obsolete>
-  <owner>mcrouse@chromium.org</owner>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the store entry type of a hint when it is loaded from the hint cache
-    store.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptimizationGuide.HintCache.HostMatch.AtCommit"
-    enum="NQEEffectiveConnectionType" expires_after="M80">
-  <obsolete>
-    Removed in favor of OptimizationGuide.HintCache.HostMatch.AtCommit as of
-    08/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the effective connection type when the optimization guide hint cache
-    has a loaded hint entry matching a URL's host at commit time. This is
-    recorded regardless of whether an associated preview type is allowed for the
-    navigation or not. If no associated preview type is allowed, the hint will
-    not be loaded from a backing store, so this will only capture matches for
-    in-memory hints.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptimizationGuide.HintCache.PageMatch.AtCommit"
-    enum="NQEEffectiveConnectionType" expires_after="M80">
-  <obsolete>
-    Removed in favor of OptimizationGuide.HintCache.PageMatch.AtCommit as of
-    08/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the effective connection type when the optimization guide hint cache
-    has a loaded page hint for a URL at commit time. This is recorded regardless
-    of whether an associated preview type is allowed for the navigation or not.
-    If no associated preview type is allowed, the hint will not be loaded from a
-    backing store, so this will only capture matches for in-memory hints.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptOut.DBRowCount" units="rows"
-    expires_after="2018-06-14">
-  <obsolete>
-    No longer used as of 06/2018.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The number of rows in the Previews opt out SQLite table at profile startup.
-  </summary>
-</histogram>
-
-<histogram name="Previews.OptOut.SQLiteLoadError" enum="SqliteErrorCode"
-    expires_after="2018-06-14">
-  <obsolete>
-    No longer used as of 06/2018.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The SQLite error code that the previews opt out store saw when trying to
-    open the SQLite database. This is logged when an unexpected error occurs
-    when trying to open the database file.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ProcessHintsResult" enum="PreviewsProcessHintsResult"
-    expires_after="M80">
-  <obsolete>
-    Merged with OptimizationGuide.ProcessHintsResult in 07/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Whether processing the previews hints succeeded and if any previews hints
-    were found. Recorded when the PreviewsOptimizationGuide receives a
-    notification to process hints.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.BlacklistReasons"
-    enum="PreviewsServerLitePageBlacklistReason" expires_after="2020-10-04">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    The reason that a navigation is blacklisted from loading a server lite page
-    preview by a dynamic blacklist. Recorded only after the observed navigation
-    has passed static eligibility checks.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.HostBlacklistedOnBypass"
-    enum="Boolean" expires_after="2020-07-10">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tombergan@chromium.org</owner>
-  <owner>src/chrome/browser/data_saver/OWNERS</owner>
-  <summary>
-    Whether or not the server directed Chrome to blacklist the requested host on
-    a bypass response.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.HttpOnlyFallbackPenalty" units="ms"
-    expires_after="2019-01-25">
-  <obsolete>
-    Replaced January 2019 by Previews.ServerLitePage.Penalty.*
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    The time spent on a navigation request that loaded a fallback signal from
-    the lite page previews server. This does not include any penalty incurred
-    because of network errors.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.IneligibleReasons"
-    enum="PreviewsServerLitePageIneligibleReason" expires_after="2020-09-27">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    The reasons that a navigation is not eligible to be shown a server lite page
-    preview by static eligibility checks. Each check is evaluated on every
-    observed navigation when the feature is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.NotReportedNavigationRestartPenalty"
-    units="ms" expires_after="2019-01-25">
-  <obsolete>
-    Removed November 2018 when PLM support was reverted.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Every time a navigation is restarted on account of this preview we attempt
-    to report the cumulative total penalty to page load metrics. This histogram
-    tracks penalties that were not successfully reported. The penalty is the
-    amount of time between the navigation start of the original (i.e.:
-    user-initiated) navigation and the current navigation when this histogram is
-    reported. This histogram is reported at the start of every navigation for
-    every navigation seen by the Lite Page Redirect Navigation Throttle.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Previews.ServerLitePage.Penalty" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    The lost time spent attempting a server lite page via canceling and
-    restarting navigations. This value is the difference between the final
-    navigation's start time and the start time of the original navigation. This
-    metric is recorded everytime the Previews NavigationThrottle acts on a
-    response, whether that is from the previews server or a network error.
-
-    This histogram is only recorded in M73 for the non-URLLoader implementation
-    of this feature. For M72, refer to
-    Previews.ServerLitePage.HttpOnlyFallbackPenalty which records this penalty
-    for failure statuses only.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.PreconnectedToPreviewServer"
-    enum="PreviewOrOriginServerConnection" expires_after="2020-08-30">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Recorded whenever lite page preview predictor preconnects to a URL. True is
-    recorded when the URL that is preconnected is for the lite pages previews
-    server, False is when the origin is preconnected.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.PredictorToggled"
-    enum="BooleanToggled" expires_after="2020-08-30">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Recorded whenever the lite page preview predictor state is changed. True is
-    recorded when preresolving or preconnecting starts and False is recorded
-    when it stops.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.PreresolvedToPreviewServer"
-    enum="PreviewOrOriginServerConnection" expires_after="2020-08-30">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Recorded whenever lite page preview preresolver preresolves a URL. True is
-    recorded when the URL that is preresolved is for the lite pages previews
-    server, False is when the origin is preresolved.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ReportedNavigationRestartPenalty"
-    units="ms" expires_after="2019-01-25">
-  <obsolete>
-    Removed November 2018 when PLM support was reverted.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Every time a navigation is restarted on account of this preview we attempt
-    to report the cumulative total penalty to page load metrics. This histogram
-    tracks penalties that were successfully reported. The penalty is the amount
-    of time between the navigation start of the original (i.e.: user-initiated)
-    navigation and the current navigation when this histogram is reported. This
-    histogram is reported at the start of every navigation for every navigation
-    seen by the Lite Page Redirect Navigation Throttle.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ServerNetError" enum="NetErrorCodes"
-    expires_after="M85">
-  <obsolete>
-    Removed in favor of
-    Previews.ServerLitePage.ServerNetError.(After|Before)Commit
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The net error from connecting to the previews server. Recorded every time a
-    connection to the server is finished.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ServerNetError.AfterCommit"
-    enum="NetErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The net error from connecting to the previews server after commit. Recorded
-    every time a connection to the server is finished after commit.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ServerNetError.BeforeCommit"
-    enum="NetErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    The net error from connecting to the previews server before commit. Recorded
-    every time a connection to the server is finished before commit.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ServerResponse"
-    enum="PreviewsServerLitePageServerResponse" expires_after="2020-09-27">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    The type of response given by the previews server when a server lite page
-    preview was triggered.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.ToggledPreresolve" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    Replaced by Previews.ServerLitePage.PredictorToggled.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Recorded whenever the lite page preview preresolver state is changed. True
-    is recorded when preresolving starts and False is recorded when it stops.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.Triggered" enum="Boolean"
-    expires_after="M80">
-  <obsolete>
-    Removed in M79.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Whether or not the server lite page preview is triggered. Recorded on every
-    observed navigation when the feature is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Previews.ServerLitePage.URLLoader.Attempted"
-    enum="BooleanAttempted" expires_after="2020-08-30">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>ryansturm@chromium.org</owner>
-  <summary>
-    Whether or not the server lite page preview was attempted during a
-    navigation. Recorded when the lite page URLLoader feature is enabled, during
-    any leg of the navigation (redirects trigger recording the histogram).
-  </summary>
-</histogram>
-
-<histogram name="Previews.StalePreviewTimestampShown"
-    enum="PreviewsStalePreviewTimestamp" expires_after="2020-07-10">
-  <obsolete>
-    Stale timestamp functionality removed in M86.
-  </obsolete>
-  <owner>robertogden@chromium.org</owner>
-  <summary>
-    Whether the timestamp for a stale preview was shown on the UI. If the
-    timestamp was not shown, states the reason why.
-  </summary>
-</histogram>
-
-<histogram name="Previews.Triggered.EffectiveConnectionType"
-    enum="NQEEffectiveConnectionType" expires_after="2019-01-09">
-  <obsolete>
-    Replaced by Previews.Triggered.EffectiveConnectionType2 as of 01/2019.
-  </obsolete>
-  <owner>dougarnett@chromium.org</owner>
-  <summary>
-    Records the effective connection type of a navigation that triggers a
-    preview. This is captured for slow page preview types - that is, ones that
-    support variable thresholds depending on matching a page pattern in the
-    optimization guide hints.
-  </summary>
-</histogram>
-
-<histogram name="PrinterService.PrinterServiceEvent"
-    enum="PrinterServiceEventType" expires_after="M85">
-  <obsolete>
-    Removed 06/2017 as part of crbug.com/734161.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Count of events in PrinterService on Chrome OS related to USB printers.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.EmptyNetworkAutomaticSetupEventSource"
-    enum="PrinterSetupSource" expires_after="M82">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>valleau@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records the source from which a network printer was configured in Chrome OS
-    if it was setup automatically with unpopulated make and model fields. Used
-    to determine the source pathway from which printers without any make and
-    model information are able to be setup automatically with a PPD.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.EmptyUsbAutomaticSetupEventSource"
-    enum="PrinterSetupSource" expires_after="M82">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>valleau@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records the source from which a USB printer was configured in Chrome OS if
-    it was setup automatically with unpopulated make and model fields. Used to
-    determine the source pathway from which printers without any make and model
-    information are able to be setup automatically with a PPD.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.InvalidPpdResolved" enum="BooleanChanged"
-    expires_after="2021-01-22">
-  <obsolete>
-    Removed 06/2020 because it is not longer needed (Issue 1046125).
-  </obsolete>
-  <owner>luum@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records when a synced printer's invalid PPD reference has been resolved by
-    stripping off the autoconf flag. Recorded during initial sync across
-    PrintersSyncBridge.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PpdSource" enum="PpdSource" expires_after="M77">
-  <obsolete>
-    Most users do not provide their own PPDs.
-  </obsolete>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records the source of PostScript Printer Description files used during
-    printer setup. Entries are recorded for every attempted configuration. Only
-    recorded on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PrintJobDatabaseEntries" units="entries"
-    expires_after="2020-09-11">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    The number of entries in the print job database. Recorded when the database
-    is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PrintJobDatabaseEntrySize" units="bytes"
-    expires_after="2020-09-11">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    The size in bytes of the entry in the print job database. Recorded every
-    time when new print job is written to the database.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PrintJobDatabaseLoadTime" units="ms"
-    expires_after="2020-09-11">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records the time it takes to fetch compeleted print jobs from the database.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PrintJobDatabasePrintJobSaved"
-    enum="BooleanSuccess" expires_after="2020-09-11">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Indicates whether we were successful performing saving print job database
-    operation.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PrintJobDatabasePrintJobsDeleted"
-    enum="BooleanSuccess" expires_after="2020-09-11">
-  <obsolete>
-    Removed 09/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>nikitapodguzov@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Indicates whether we were successful performing deleting print jobs database
-    operation.
-  </summary>
-</histogram>
-
-<histogram name="Printing.CUPS.PwgRasterDocumentResolutionSupported"
-    enum="Boolean" expires_after="M82">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>valleau@chromium.org</owner>
-  <owner>skau@chromium.org</owner>
-  <summary>
-    Records whether a printer supports the
-    pwg-raster-document-resolution-supported attribute.
-  </summary>
-</histogram>
-
-<histogram name="Printing.FrameIsActiveOnCreateLoaderFactory"
-    enum="BooleanEnabled" expires_after="2020-07-31">
-  <obsolete>
-    Removed in 2020-06. kUseFrameAssociatedLoaderFactory has shipped in M83 and
-    Printing.FrameIsActiveOnCreateLoaderFactory is true in 100% of cases on all
-    platforms.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    Records whether the associated frame is active when
-    PrepareFrameAndViewForPrint::CreateURLLoaderFactory is called. If it is
-    always active we want to replace the CreateFailingURLLoaderFactory call with
-    a DCHECK.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.FontType" enum="PrintPreviewFontTypeType"
-    expires_after="M85">
-  <obsolete>
-    Removed 01/2015 as part of crbug.com/278148.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Count of font file formats embeeded in print preview PDFs. These numbers are
-    biased by what the platforms supports in terms of detection.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.GcpPromo" enum="PrintPreviewGcpPromoBuckets"
-    expires_after="2017-09-12">
-  <obsolete>
-    No longer used as of 09/2017.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    Actions performed by the user when the Google Cloud Print add-printers
-    promotion is shown to the user.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.InitiatedByScript" enum="BooleanMainFrame"
-    expires_after="M77">
-  <obsolete>
-    No longer used as of 07/2019.
-  </obsolete>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    Logged when a document calls the window.print() API. The boolean value
-    indicates whether it is invoked by the main frame. It will be false for
-    documents in subframes.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.OutOfProcessSubframe" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    No longer used as of 07/2019.
-  </obsolete>
-  <owner>nasko@chromium.org</owner>
-  <summary>
-    Logged when a document calls the window.print() API in any frame. The
-    boolean value will be true when the API call is invoked by a document which
-    is in a process different than the top level document. It will be false in
-    all other cases.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.Initial" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The page count of the initial print preview, a.k.a. the total number of
-    pages in documents to be printed.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.OpenInMacPreview" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to PDF and
-    opened in Preview.app on Mac.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintToCloudPrint" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to a cloud
-    printer.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintToCloudPrintWebDialog"
-    units="units" expires_after="2016-01-14">
-  <obsolete>
-    No longer used as of 01/2016.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to a cloud
-    printer using web dialog.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintToGoogleDrive" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rbpotter@chromium.org</owner>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to Google
-    Drive.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintToPDF" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to PDF.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintToPrinter" units="units"
-    expires_after="2020-01-20">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to a
-    printer.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintWithExtension" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to an
-    extension printer (using printerProvider API).
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.PrintWithPrivet" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed to a privet
-    printer.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PageCount.SystemDialog" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    The final page count (after page selection) of documents printed using
-    system dialog.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PdfAction" enum="PrintPreviewPdfActionBuckets"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rbpotter@chromium.org</owner>
-  <summary>
-    Actions taken on the PDF viewer inside Print Preview's preview area.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.PreviewEvent" enum="PrintPreviewHelperEvents"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>thestig@chromium.org</owner>
-  <summary>Print preview events.</summary>
-</histogram>
-
-<histogram name="PrintPreview.SiteIsolation.CrossSiteFrameCount" units="frames"
-    expires_after="M81">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    The number of cross-site frames contained in a document being printed, as
-    defined by comparing scheme and eTLD+1.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.SiteIsolation.CrossSiteVisibleFrameCount"
-    units="frames" expires_after="M81">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    The number of cross-site visible frames contained in a document being
-    printed.
-  </summary>
-</histogram>
-
-<histogram name="PrintPreview.SiteIsolation.RemoteFrameCount" units="frames"
-    expires_after="M81">
-  <obsolete>
-    Removed 01/2020.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    The number of out-of-process frames contained in a document being printed.
-  </summary>
-</histogram>
-
-<histogram name="Privacy.ConsentAuditor.UserEventServiceReady" enum="Boolean"
-    expires_after="2018-04-04">
-  <obsolete>
-    Removed as of 4/2018.
-  </obsolete>
-  <owner>dullweber@google.com</owner>
-  <owner>msramek@google.com</owner>
-  <summary>
-    Logs whether the UserEventServiceReady is ready when recording a consent.
-    This should always be true as the service is created at startup.
-  </summary>
-</histogram>
-
-<histogram name="Process.Sandbox.FlagOverrodeRemoteSessionCheck" enum="Boolean"
-    expires_after="2020-06-18">
-  <obsolete>
-    The check seems to be needed for as long as Windows 7 is supported. Removed
-    2020-05.
-  </obsolete>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    Measure how often the automatic recognition for terminal services
-    environment would have incorrectly decided that the job object should be
-    applied, when it shouldn't have been as dictated by the flag
-    --allow-no-sanbox-job. This histogram will guide the final removal of the
-    flag, which will be possible when the number of false values becomes
-    insignificant.
-  </summary>
-</histogram>
-
-<histogram name="Process.Sandbox.PolicyGlobalSize" units="bytes"
-    expires_after="M85">
-  <obsolete>
-    Replaced by PolicyGlobalSizeOnSuccess as failure cases were uninteresting.
-    Removed 2020-04.
-  </obsolete>
-  <owner>ajgo@chromium.org</owner>
-  <owner>src/sandbox/policy/win/OWNERS</owner>
-  <summary>
-    Size of policy global memory used when policy was committed on Windows for
-    all outcomes. 0 indicates that no rules were used.
-  </summary>
-</histogram>
-
-<histogram name="Process.Sandbox.PolicyGlobalSizeOnSuccess" units="bytes"
-    expires_after="M85">
-  <obsolete>
-    Policy size reduced, metric no longer required. Removed 2020-06.
-  </obsolete>
-  <owner>ajgo@chromium.org</owner>
-  <owner>src/sandbox/policy/win/OWNERS</owner>
-  <summary>
-    Size of policy global memory used when policy was committed after successful
-    process start on Windows. 0 indicates that no rules were used.
-  </summary>
-</histogram>
-
-<histogram name="ProductTour.IOSScreens" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 04/2020. See crrev.com/c/2129507
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="IOSProductTourScreens" -->
-
-  <owner>mrefaat@google.com</owner>
-  <summary>The time spent in product tour screens for ios.</summary>
-</histogram>
-
-<histogram name="Profile.AuthResult" enum="ProfileAuth" expires_after="M82">
-  <obsolete>
-    Not accessed in months. All results say &quot;authentication was
-    unnecessary&quot;. Removed 2020-03.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Counts of authorization results when trying to open a locked profile from
-    the User Manager.
-  </summary>
-</histogram>
-
-<histogram name="Profile.AvatarLoadStatus" enum="ProfileAvatarLoadStatus"
-    expires_after="M77">
-  <obsolete>
-    No longer recorded as of M87.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Load status of an avatar for decorating the Windows taskbar</summary>
-</histogram>
-
-<histogram name="Profile.CreateAndInitializeProfile" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>Length of time to setup profile.</summary>
-</histogram>
-
-<histogram name="Profile.CreateBrowserContextServicesTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the CreateBrowserContextServices call
-    within OnPrefsLoaded.
-  </summary>
-</histogram>
-
-<histogram name="Profile.CreateProfileHelperTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during ProfileManager::CreateProfileHelper.
-    This is called when a profile is created synchronously (usually at startup).
-  </summary>
-</histogram>
-
-<histogram name="Profile.CreateTime" units="ms" expires_after="2013-09-11">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Back-end time elapsed while creating a new profile. The max is 30 seconds,
-    when an external timeout was applied.
-  </summary>
-</histogram>
-
-<histogram name="Profile.CreateTimeCanceled" units="ms"
-    expires_after="2013-09-11">
-  <obsolete>
-    Removed as of 8/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time elapsed before the user decided to cancel creation of a new profile.
-    Since only managed-user profile creation can be canceled, this time comes
-    from managed-user registration. The max is 30 seconds, when an external
-    timeout was applied.
-  </summary>
-</histogram>
-
-<histogram name="Profile.CreateTimeCanceledNoTimeout" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 6/2019.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>michaelpg@chromium.org</owner>
-  <summary>
-    Time elapsed from when the handler received the message that a user clicked
-    'Create' until the user decided to cancel creation of a new profile. Since
-    only managed-user profile creation can be canceled, this time comes from
-    managed-user registration.
-  </summary>
-</histogram>
-
-<histogram name="Profile.DesktopMenu" enum="ProfileDesktopMenu"
-    expires_after="M81">
-  <obsolete>
-    Replaced by Profile.Menu.ClickedActionableItem in M81.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>tangltom@chromium.org</owner>
-  <summary>
-    Track user interactions that can be performed in the user menu and user
-    manager. The origin of the action, whether the an interaction in the content
-    area or some other source, is noted in the histogram suffix.
-  </summary>
-</histogram>
-
-<histogram name="Profile.GetProfile" units="ms" expires_after="2015-02-19">
-  <obsolete>
-    Removed 02/2015. Profile.CreateAndInitializeProfile is more useful.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>Length of time to retrieve profile.</summary>
-</histogram>
-
-<histogram name="Profile.GetProfileInfoPath.OutsideUserDir" enum="BooleanHit"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020. There are no recordings of this event since M83.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Whether Profile::GetProfileInfoPath is called with a profile that does not
-    have the user data directory as a parent directory. This is expected to
-    never happen, but there are a few events recorded on stable as of M80. This
-    metric should be removed once http://crbug.com/981374 is fixed.
-  </summary>
-</histogram>
-
-<histogram name="Profile.InitProfileUserPrefs.OutsideUserDir" enum="BooleanHit"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020. There are no recordings of this event since M83.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Whether Profile::InitProfileUserPrefs is called with a profile that does not
-    have the user data directory as a parent directory. This is expected to
-    never happen, but there are a few events recorded on stable as of M80. This
-    metric should be removed once http://crbug.com/981374 is fixed.
-  </summary>
-</histogram>
-
-<histogram name="Profile.LaunchBrowser" enum="ProfileType" expires_after="M82">
-  <obsolete>
-    Removed 03/2020.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <summary>
-    Number of times users launch a browser window from either a primary or
-    secondary profile (i.e., each time a browser window is opened we log which
-    type of profile it belongs to).
-  </summary>
-</histogram>
-
-<histogram name="Profile.LockedProfilesDuration" units="minutes"
-    expires_after="M79">
-  <obsolete>
-    Removed 12/2019. We do not lock profiles anymore.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    How long locked profiles have been locked for. This is logged each time any
-    profile is loaded. Note that this does not track the total time the profile
-    was locked, but rather the span from when the profile was locked to when the
-    measurement takes place.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NewAvatarMenu.NotYou"
-    enum="ProfileNewAvatarMenuNotYou" expires_after="2017-10-17">
-  <obsolete>
-    Removed 2017-10-16. No longer tracked. Feature removed.
-  </obsolete>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    Tracks user interactions with the 'Not You?' bubble that users can navigate
-    to from the Upgrade bubble after upgrade to the New Avatar Menu.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NewAvatarMenu.Signin"
-    enum="ProfileNewAvatarMenuSignin" expires_after="2017-10-19">
-  <obsolete>
-    Removed 2017-10-19. No longer tracked. Feature removed.
-  </obsolete>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    Tracks user interactions with the signin bubble that appears in the New
-    Avatar Menu upon signin. This bubble appears after the user signs in using
-    the Inline Signin flow.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NewAvatarMenu.Upgrade"
-    enum="ProfileNewAvatarMenuUpgrade" expires_after="2017-10-17">
-  <obsolete>
-    Removed 2017-10-16. No longer tracked. Feature removed.
-  </obsolete>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    Tracks user interactions with the bubble that appears for users in the new
-    avatar menu after upgrade.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NotifyProfileCreatedTime" units="ms"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the Notify() of
-    NOTIFICATION_PROFILE_CREATED during ProfileImpl::DoFinalInit().
-  </summary>
-</histogram>
-
-<histogram name="Profile.NumberOfProfilesAfterAddOrDelete" units="units"
-    expires_after="2014-01-29">
-  <obsolete>
-    Removed 2013-04-09. No longer tracked. See Profile.NumberOfProfiles.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <summary>
-    Counts the number of profiles on a user's machine whenever a profile is
-    added or deleted.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NumberOfProfilesOnStartup" units="units"
-    expires_after="2014-01-29">
-  <obsolete>
-    Removed; replaced by Profile.NumberOfProfiles on 2013-04-09. Data are
-    suspect, especially after 2012-02-24: see https://crbug.com/189213.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <summary>
-    Counts the number of profiles on a user's machine when Chrome starts up.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NumberOfSignedInProfilesOnStartup" units="units"
-    expires_after="2014-01-29">
-  <obsolete>
-    Removed; replaced by Profile.NumberOfSignedInProfiles on 2013-04-09.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <summary>
-    Counts the number of profiles that are signed in to Chrome when Chrome
-    starts up.
-  </summary>
-</histogram>
-
-<histogram name="Profile.NumberOfSwitches" units="units" expires_after="M82">
-  <obsolete>
-    Removed 03/2020.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <summary>
-    Counts the number of times profiles were switched in a browser session. This
-    value is incremented when a profile is switched to and the result is logged
-    during shutdown.
-  </summary>
-</histogram>
-
-<histogram name="Profile.OnLocaleReadyTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during ProfileImpl::OnLocaleReady. This
-    happens once after profile was loaded.
-  </summary>
-</histogram>
-
-<histogram name="Profile.OnPrefsLoadedTime" units="ms"
-    expires_after="2015-05-12">
-  <obsolete>
-    Removed 04/2015, and replaced by Profile.OnLocaleReadyTime.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during ProfileImpl::OnPrefsLoaded.
-  </summary>
-</histogram>
-
-<histogram name="Profile.Opening" enum="ProfileOpen" expires_after="2014-01-29">
-  <obsolete>
-    Removed because it did not present the information clearly.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The frequency of ways that the profiles are opened.</summary>
-</histogram>
-
-<histogram name="Profile.OpenMethod" enum="ProfileOpenMethod"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <summary>
-    The frequency with which the user opens the different profile menus or
-    switches profiles. For the open statistics, this does not mean the user
-    necessarily opened a profile after clicking. The switch statistics indicate
-    how often and how the user switches profiles. They are provided together for
-    comparison of how often the user actually switches after opening the avatar
-    bubble menu.
-  </summary>
-</histogram>
-
-<histogram name="Profile.ProfileImplDoFinalInit" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the ProfileImpl::DoFinalInit().
-  </summary>
-</histogram>
-
-<histogram name="Profile.RemoveUserWarningStatsTime" units="ms"
-    expires_after="2020-03-01">
-  <obsolete>
-    Removed 02/2020 since the histogram indicators were stable.
-  </obsolete>
-  <owner>dullweber@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during profile statistics calculation.
-  </summary>
-</histogram>
-
-<histogram name="Profile.SupervisedProfileCreateError"
-    enum="GoogleServiceAuthError" expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The error code generated in the final step (registration step) of creating a
-    new supervised profile.
-  </summary>
-</histogram>
-
-<histogram name="Profile.SupervisedProfileImportError"
-    enum="GoogleServiceAuthError" expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The error code generated in the final step (registration step) of importing
-    a supervised profile.
-  </summary>
-</histogram>
-
-<histogram name="Profile.SupervisedProfileTotalCreateTime" units="ms"
-    expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time elapsed from when the handler received the message that a user clicked
-    'Create' to create a new supervised user profile until the registration ends
-    either successfully or with a failure (both recorded in
-    Profile.SupervisedProfileCreateResult).
-  </summary>
-</histogram>
-
-<histogram name="Profile.SupervisedProfileTotalImportTime" units="ms"
-    expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Time elapsed from when the handler received the message that a user clicked
-    'Import supervised user' until the registration ends either successfully or
-    with a failure (both recorded in Profile.SupervisedProfileImportResult).
-  </summary>
-</histogram>
-
-<histogram name="Profile.Sync" enum="ProfileSync" expires_after="2014-01-29">
-  <obsolete>
-    Removed because it did not present the information clearly.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Activity of the user with regards to sync.</summary>
-</histogram>
-
-<histogram name="Profile.SyncSignIn" enum="ProfileType"
-    expires_after="2019-01-15">
-  <obsolete>
-    Removed 11/2018 as this histogram is not of sufficient value anymore. It
-    only records events made through the advanced settings dialog which are very
-    rare and not representative for most analysis purposes.
-  </obsolete>
-  <owner>tschumann@google.com</owner>
-  <summary>
-    Number of times the user signed into sync from original or secondary
-    profile.
-  </summary>
-</histogram>
-
-<histogram name="Profile.ThumbnailsSize" units="MB" expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Size of the thumbnails database.</summary>
-</histogram>
-
-<histogram name="Profile.TimeToOpenUserManager" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. Replaced by Profile.TimeToOpenUserManagerUpTo1min with the
-    max time increased from 10 seconds to 1 minute.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>tangltom@chromium.org</owner>
-  <summary>
-    Time required to open the UserManager, from when it started to show until
-    when its javascript started executing.
-  </summary>
-</histogram>
-
-<histogram name="Profile.UpdateTaskbarDecoration.Win.Result" enum="Hresult"
-    expires_after="M85">
-  <obsolete>
-    Removed 6/3/2020. No longer needed.
-  </obsolete>
-  <owner>phillis@chromium.org</owner>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    Record the result of updating taskbar decoration on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Profile.UpgradeEnrollment" enum="ProfileUpgradeEnrollment"
-    expires_after="2014-08-12">
-  <obsolete>
-    Removed 8/2014. Upgrade Promotional UI removed.
-  </obsolete>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    The process which leads a user to enroll in New Profile Management. Also
-    tracks if the user chooses to opt out, and tutorials which guide the user
-    into New Profile Management.
-  </summary>
-</histogram>
-
-<histogram name="ProfileReset.SendFeedback" enum="Boolean" expires_after="M80">
-  <obsolete>
-    Removed 07/2019. No longer tracked.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Signifies if the user selected &quot;Send feedback&quot; checkbox in the
-    Reset Profile dialog.
-  </summary>
-</histogram>
-
-<histogram name="Protector.DefaultSearchProvider" enum="ProtectorError"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Errors that Protector detects about default search provider in Web Data.
-    Reported once when Web Data is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Protector.Preferences" enum="ProtectorError"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Errors that Protector detects about protected settings in Preferences.
-    Reported once when profile is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Protector.SearchProvider" enum="SearchEngine"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When the default search provider setting is changed outside of Chrome, which
-    is detected by the Protector, this histogram reports the new setting.
-  </summary>
-</histogram>
-
-<histogram name="Protector.StartupSettings" enum="SessionStartupType"
-    expires_after="2013-08-03">
-  <obsolete>
-    Removed 8/2013. No longer tracked.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    When the startup settings are changed outside of Chrome, which is detected
-    by the Protector, this histogram reports the new setting.
-  </summary>
-</histogram>
-
-<histogram name="ProxyOverriddenBubble.ExtensionCount" units="Extensions"
-    expires_after="2016-09-09">
-  <obsolete>
-    Removed 9/2016. Never added to histograms.xml and value is always 1.
-  </obsolete>
-  <summary>
-    The number of extensions overriding the proxy, triggering the proxy override
-    extension warning bubble.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.BlinkGCKB" units="KB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The memory usage of the BlinkGC allocator after a background renderer is
-    purged and suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.DiscardableKB" units="KB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The memory usage of the discardable memory after a background renderer is
-    purged and suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.MallocMB" units="MB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The memory usage of the malloc after a background renderer is purged and
-    suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.PartitionAllocKB" units="KB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The memory usage of PartitionAlloc after a background renderer is purged and
-    suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.TotalAllocatedMB" units="MB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The sum of the memory usages of PartitionAlloc, malloc, discardable memory,
-    mainThreadIsolate() and BlinkGC allocator after a backgrounded renderer is
-    purged and suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.Memory.V8MainThreadIsolateMB" units="MB"
-    expires_after="2017-04-25">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    The memory usage of mainThreadIsolate() after a backgrounded renderer is
-    purged and suspended. Note: this metric is for A/B testing.
-  </summary>
-</histogram>
-
-<histogram name="PurgeAndSuspend.PendingTaskCount" units="units"
-    expires_after="2017-10-11">
-  <obsolete>
-    Removed Oct 2017.
-  </obsolete>
-  <owner>tasak@google.com</owner>
-  <summary>
-    This records how many tasks are still in task queues when a backgrounded
-    renderer is suspended.
-  </summary>
-</histogram>
-
-<histogram name="PushMessaging.QueuedMessagesCount" units="units"
-    expires_after="2020-04-22">
-  <obsolete>
-    Removed April 2020
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    When a message arrives for a lazy subscription and Chrome isn't in the
-    foreground, it is persisted on disk until next time Chrome is in the
-    foreground. This is recorded before adding the message the persisted queue
-    to estimate how large does the queue grow.
-  </summary>
-</histogram>
-
-<histogram name="PushMessaging.TimeToCheckIfSubscriptionLazy" units="ms"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed Dec 2019
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    When a message arrives to a subscription while Chrome is in the background,
-    the subscription is checked first for being lazy, and accordingly the
-    message is forwarded or persisted on disk. Since this check may require disk
-    access, this histogram measures the time spent in checking if the
-    subscription is lazy.
-  </summary>
-</histogram>
-
-<histogram name="Quota.DaysSinceLastAccess" units="days" expires_after="M77">
-  <obsolete>
-    Removed June 2019
-  </obsolete>
-  <owner>jarrydg@chromium.org</owner>
-  <summary>
-    The number of days since an origin's data was last accessed. Logged upon
-    access when the time since last access is at least 24 hours.
-  </summary>
-</histogram>
-
-<histogram name="Quota.ErrorsOnEvictingOriginPerHour" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Number of errors on evicting origin by QuotaTemporaryStorageEvictor in an
-    hour.
-  </summary>
-</histogram>
-
-<histogram name="Quota.ErrorsOnGettingUsageAndQuotaPerHour" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Number of errors on getting usage and quota by QuotaTemporaryStorageEvictor
-    in an hour.
-  </summary>
-</histogram>
-
-<histogram name="Quota.EvictedOriginTimeSinceAccess" units="units"
-    expires_after="2017-02-06">
-  <obsolete/>
-  <owner>calamity@chromium.org</owner>
-  <summary>
-    The time since the evicted origin was last accessed. Logged when the origin
-    is evicted.
-  </summary>
-</histogram>
-
-<histogram name="Quota.FreeDiskSpaceForProfile" units="MB"
-    expires_after="2015-12-16">
-  <obsolete/>
-  <owner>jarrydg@chromium.org</owner>
-  <summary>Amount of free disk space for profile directory.</summary>
-</histogram>
-
-<histogram name="Quota.InitialTemporaryGlobalStorageQuota" units="MB"
-    expires_after="2015-12-16">
-  <obsolete/>
-  <owner>jarrydg@chromium.org</owner>
-  <summary>Initial quota for global temporary storage.</summary>
-</histogram>
-
-<histogram name="Quota.LRUOriginTypes" enum="QuotaOriginTypes"
-    expires_after="2018-07-30">
-  <obsolete>
-    Removed July 2018
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Types of origins that are initially selected for eviction via LRU. Some of
-    these types are exempt from eviction.
-  </summary>
-</histogram>
-
-<histogram name="Quota.NumberOfPersistentStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of origins using persistent storage.</summary>
-</histogram>
-
-<histogram name="Quota.NumberOfProtectedPersistentStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of protected origins using persistent storage.</summary>
-</histogram>
-
-<histogram name="Quota.NumberOfProtectedTemporaryStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of protected origins using temporary storage.</summary>
-</histogram>
-
-<histogram name="Quota.NumberOfTemporaryStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of origins using temporary storage.</summary>
-</histogram>
-
-<histogram name="Quota.NumberOfUnlimitedPersistentStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of unlimited origins using persistent storage.</summary>
-</histogram>
-
-<histogram name="Quota.NumberOfUnlimitedTemporaryStorageOrigins" units="units"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M74.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>Number of unlimited origins using temporary storage.</summary>
-</histogram>
-
-<histogram name="Quota.PercentUsedForTemporaryStorage" units="%"
-    expires_after="M81">
-  <obsolete/>
-  <owner>jarrydg@chromium.org</owner>
-  <summary>
-    Percentage of the storage device that is being use for temporary storage.
-    Logged at irregular intervals (during eviction).
-  </summary>
-</histogram>
-
-<histogram name="Quota.TimeBetweenRepeatedOriginEvictions" units="units"
-    expires_after="2017-02-06">
-  <obsolete/>
-  <owner>calamity@chromium.org</owner>
-  <summary>
-    Time since an origin was last chosen to be evicted from the storage,
-    recorded each time the origin is evicted (except for the first eviction).
-  </summary>
-</histogram>
-
-<histogram name="Quota.TimeToGetSettings" units="ms" expires_after="M77">
-  <obsolete>
-    Removed June 2019
-  </obsolete>
-  <owner>jarrydg@chromium.org</owner>
-  <summary>
-    Time spent querying the embedder for the settings values. Logged at
-    irregular intervals as the values are refreshed.
-  </summary>
-</histogram>
-
-<histogram name="Quota.TimeToInitializeGlobalQuota" units="ms"
-    expires_after="2017-02-06">
-  <obsolete>
-    Removed November 2016
-  </obsolete>
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Time spent initializing the global quota. Logged when the storage
-    partition's quota manager is initialized.
-  </summary>
-</histogram>
-
-<histogram name="Quota.UsageOverageOfTemporaryGlobalStorage" units="MB"
-    expires_after="2019-03-07">
-  <obsolete>
-    Expired on 2018-08-30. Removed in M75.
-  </obsolete>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Overage of the temporary global storage usage at beginning of an eviction
-    round.
-  </summary>
-</histogram>
-
-<histogram name="rappor.last_daily_sample" enum="DailyEventIntervalType"
-    expires_after="2015-05-05">
-  <obsolete>
-    Removed 2015/05/05.
-  </obsolete>
-  <owner>holte@chromium.org</owner>
-  <summary>
-    Rappor.DailyEvent.IntervalType reported under the wrong name.
-  </summary>
-</histogram>
-
-<histogram name="RecurrenceRanker.ConfigurationError"
-    enum="RecurrenceRankerConfigurationError" expires_after="M80">
-  <obsolete>
-    Replaced by RecurrenceRanker.InitializationStatus.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>charleszhao@chromium.org</owner>
-  <summary>
-    Reports different kinds of misconfigurations of a RecurrenceRanker.
-  </summary>
-</histogram>
-
-<histogram name="RecurrenceRanker.LogFileOpenType" enum="FileOpenType"
-    expires_after="2019-12-31">
-  <obsolete>
-    Removed December 2019.
-  </obsolete>
-  <owner>jiameng@chromium.org</owner>
-  <owner>thanhdng@chromium.org</owner>
-  <owner>tby@chromium.org</owner>
-  <summary>
-    Records number of file opens for each file open type events.
-  </summary>
-</histogram>
-
-<histogram name="RecurrenceRanker.SerializationError"
-    enum="RecurrenceRankerSerializationError" expires_after="M80">
-  <obsolete>
-    Replaced by RecurrenceRanker.SerializationStatus.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>charleszhao@chromium.org</owner>
-  <summary>
-    Reports various saving/loading errors for a RecurrenceRanker or
-    RecurrencePredictor.
-  </summary>
-</histogram>
-
-<histogram name="RecurrenceRanker.UsageError" enum="RecurrenceRankerUsageError"
-    expires_after="M80">
-  <obsolete>
-    The cases this reported can no longer occur.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>charleszhao@chromium.org</owner>
-  <summary>
-    Reports when a RecurrenceRanker is used in a way not supported by its
-    underlying RecurrencePredictor.
-  </summary>
-</histogram>
-
-<histogram name="Referrer.HeaderLength" units="bytes" expires_after="M85">
-  <obsolete>
-    We successfully shipped a 4k restriction in M77, and no longer require the
-    data on `referer` header length.
-  </obsolete>
-  <owner>mkwst@chromium.org</owner>
-  <summary>
-    The size of each outgoing request's 'Referer' header field's value, in
-    bytes.
-  </summary>
-</histogram>
-
-<histogram name="Render.Workers.MaxWorkerCountInRendererProcess" units="units"
-    expires_after="2016-12-29">
-  <obsolete>
-    Removed Dec 2016. This metric did not report the number of shared workers
-    correctly, since it used the RenderProcessHostImpl ref counts, which in the
-    shared worker case is more like a boolean flag (zero or one or maybe two)
-    than the number of shared workers. So its results can be thought of as
-    roughly the number of service workers only.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Maximum number of workers (SharedWorker or ServiceWorker) that are
-    simultaneously hosted in a single renderer process. Recorded when the
-    renderer process host is being destructed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.AcceleratedFixedRootBackground"
-    enum="AcceleratedFixedRootBackground" expires_after="2018-05-21">
-  <obsolete>
-    Removed May 2018. There are no longer accelerated fixed root backgrounds.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Keeps track of the number of main frame scrolls with an accelerated fixed
-    root background, the number of main frame scrolls with an unaccelerated
-    fixed root background, and the total number of main frame scrolls.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.DrawDuration" units="ms" expires_after="2016-06-10">
-  <obsolete>
-    Replaced by Scheduling.Renderer.DrawDuration. This metric did not
-    differentiate between processes.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>The time it takes for the compositor to draw a frame.</summary>
-</histogram>
-
-<histogram name="Renderer.DrawDurationOverestimate" units="ms"
-    expires_after="2016-06-10">
-  <obsolete>
-    Measurement no longer taken.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The amount by which the compositor's draw duration was overestimated in a
-    particular frame (0 if the duration was perfectly predicted or
-    underestimated).
-  </summary>
-</histogram>
-
-<histogram name="Renderer.DrawDurationUnderestimate" units="ms"
-    expires_after="2016-06-10">
-  <obsolete>
-    Measurement no longer taken.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The amount by which the compositor's draw duration was underestimated in a
-    particular frame (0 if the duration was perfectly predicted or
-    overestimated).
-  </summary>
-</histogram>
-
-<histogram name="Renderer.GpuLatency" units="ms" expires_after="2015-07-20">
-  <obsolete>
-    Measurement no longer taken.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The delay between the compositor submitting a command to the GPU and that
-    command executing on the GPU. This delay is measured once per frame.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.GpuLatencyOverestimate" units="ms"
-    expires_after="2015-07-20">
-  <obsolete>
-    Measurement no longer taken.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The amount by which GPU latency was overestimated in a particular frame (0
-    if the latency was perfectly predicted or underestimated).
-  </summary>
-</histogram>
-
-<histogram name="Renderer.GpuLatencyUnderestimate" units="ms"
-    expires_after="2015-07-20">
-  <obsolete>
-    Measurement no longer taken.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The amount by which GPU latency was underestimated in a particular frame (0
-    if the latency was perfectly predicted or overestimated).
-  </summary>
-</histogram>
-
-<histogram name="Renderer.LayoutMs" units="ms" expires_after="2015-04-24">
-  <obsolete>
-    Removed as of 3/2015.
-  </obsolete>
-  <owner>benjhayden@chromium.org</owner>
-  <summary>
-    Duration of the FrameView::performLayout trace event, which occurs at most
-    once per frame.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.LineLayoutMs" units="ms" expires_after="2015-04-24">
-  <obsolete>
-    Removed as of 3/2015.
-  </obsolete>
-  <owner>benjhayden@chromium.org</owner>
-  <summary>
-    Amount of time spent doing line layout during FrameView::performLayout.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.PixelIncreaseFromTransitions" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    A lower-bound on the percentage increase in memory that would result from
-    promoting all layers that have a webkit-transition on opacity or transform.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.unloadEventsDurationMS" units="ms"
-    expires_after="2013-10-29">
-  <obsolete>
-    Removed as of 10/2013.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This measures how long all unload event handlers required to run whenever an
-    unload event is processed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer.WKWebViewCallbackAfterDestroy" enum="BooleanHit"
-    expires_after="2019-12-25">
-  <obsolete>
-    Removed 12/2019 as it is no longer hit or recorded.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <summary>
-    [iOS] Counts the number of times a WKNavigationDelegate callback was called
-    after the CRWWebController was closed. This is unexpected and could be the
-    cause of many crashes. If this histogram is ever logged, it means that
-    Chrome needs to gracefully handle the case when WKNavigationDelegate
-    callbacks are called for a destroyed web controller. Only logged on iOS.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.FinishDocToFinish" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a document finished loading to when all it's resources
-    are also loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.RequestToFinish" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 6/15/09. Replaced by Renderer2.RequestToFinish_L
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page was requested by a user to when it is fully
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.RequestToFinish_L" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page was requested by a user to when it is fully
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.RequestToFirstLayout" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page was requested by a user to its first layout.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.RequestToStart" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page was requested by a user to when it starts loading.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.StartToFinish" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page started loading to when it is fully loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.StartToFinishDoc" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page starts loading to when the main document is
-    finished loading.
-  </summary>
-</histogram>
-
-<histogram name="Renderer2.StartToFirstLayout" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time from when a page starts loading to its first layout.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Abandoned" enum="Abandoned"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Distribution of actual finished pages, vs abandoned pages, where we needed
-    to declare a finish time prematurely since the page was being closed
-    (exited).
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.AccelContentPaintDurationMS" units="units"
-    expires_after="2014-05-13">
-  <obsolete>
-    Removed 2014-05 because of impl-side painting.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time spent by WebKit painting the page, in milliseconds, when the GPU
-    acceleration is active, for paints that affect non-root layers.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.AccelContentPaintMegapixPerSecond" units="units"
-    expires_after="2014-05-13">
-  <obsolete>
-    Removed 2014-05 because of impl-side painting.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    WebKit paint throughput, measured in megapixels per second, when GPU
-    acceleration is active, for paints that affect non-root layers.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.AccelDoDeferredUpdateDelay" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>Time between frames when GPU acceleration is active.</summary>
-</histogram>
-
-<histogram name="Renderer4.AccelRootPaintDurationMS" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time spent by WebKit painting the page, in milliseconds, when the GPU
-    acceleration is active, for paints that affect the root layer.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.AccelRootPaintMegapixPerSecond" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    WebKit paint throughput, measured in megapixels per second, when GPU
-    acceleration is active, for paints that affect the root layer.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.AnimationCallbackDelayTime" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from when the animation callback was posted to when it ran.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.BeginToCommit" units="ms" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;begin&quot; to &quot;commit.&quot; &quot;Begin&quot;==
-    &quot;request&quot; if user requested, and &quot;start&quot; otherwise.
-    &quot;Request&quot;== time when user requested document. &quot;Start&quot;==
-    time when renderer requested load of document, after any unload of last
-    document. &quot;Commit&quot;== time when renderer got first byte of
-    document.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.BeginToFinish" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="Renderer4.BeginToFinishDoc" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="Renderer4.BeginToFirstPaint" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;begin&quot; to &quot;first paint.&quot; &quot;Begin&quot;==
-    &quot;request&quot; if user requested, and &quot;start&quot; otherwise.
-    &quot;Request&quot;== time when user requested document. &quot;Start&quot;==
-    time when renderer requested load of document, after any unload of last
-    document. &quot;First paint&quot;== time when first paint operation was
-    performed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.BeginToFirstPaintAfterLoad" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;big&quot; to &quot;first paint after load.&quot;
-    &quot;Begin&quot;== &quot;request&quot; if user requested, and
-    &quot;start&quot; otherwise. &quot;Request&quot;== time when user requested
-    document. &quot;Start&quot;== time when renderer requested load of document,
-    after any unload of last document. &quot;First paint after load&quot;== time
-    after onload() when first paint operation is performed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Browser.PartialRasterPercentageSaved" units="%"
-    expires_after="M80">
-  <obsolete>
-    Obsolete as of M80. Partial raster has shipped for a long period of time /
-    is not being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Percentage of pixels which would have been rastered, but were skipped due to
-    the partial raster optimization. Logged for each raster task run in a
-    Browser process. The histogram is suffixed by the RasterBufferProvider which
-    is in use.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Browser.RasterTaskSchedulingDelay"
-    units="microseconds" expires_after="2020-08-22">
-  <obsolete>
-    Obsolete as of 11/2019. Replaced by
-    Renderer4.Browser.RasterTaskSchedulingDelayNoAtRasterDecodes since the
-    semantics changed: we used to count raster tasks that depended on at-raster
-    image decodes, but this is no longer the case.
-  </obsolete>
-  <owner>andrescj@chromium.org</owner>
-  <owner>chromeos-gfx@google.com</owner>
-  <summary>
-    The wall time elapsed between creating a raster task in the client and being
-    ready to issue raster work to the driver in the GPU process. This includes
-    time decoding and uploading images.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CommitToFinish" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;finish.&quot; &quot;Commit&quot;==
-    time when renderer got first byte of document. &quot;Finish&quot;==after
-    onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CommitToFinishDoc" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;finish doc.&quot; &quot;Commit&quot;==
-    time when renderer got first byte of document. &quot;Finish doc&quot; ==
-    main document loaded, before onload(). &quot;Finish&quot;==after onload()
-    and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CommitToFirstPaint" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;first paint.&quot;
-    &quot;Commit&quot;== time when renderer got first byte of document.
-    &quot;First paint&quot;== time when first paint operation was performed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CommitToFirstPaintAfterLoad" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;commit&quot; to &quot;first paint after load.&quot;
-    &quot;Commit&quot;== time when renderer got first byte of document.
-    &quot;First paint after load&quot;== time after onload() when first paint
-    operation is performed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CompositorScrollHitTestResult"
-    enum="CompositorScrollResult" expires_after="2017-12-06">
-  <obsolete>
-    Removed in 12/2017. Renderer4.MainThreadGestureScrollReason and
-    Renderer4.MainThreadWheelScrollReason could track more detailed reasons of
-    main thread scrolling.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    It's possible for compositor hit testing to determine conclusively that
-    compositor thread scrolling can or cannot be done. It's also possible that
-    the hit testing result is inconclusive. We would like to see the I-don't-
-    know result as little as possible. This histogram tracks the ratios.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.CompositorThreadImplDrawDelay" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed in 06/2018, M69. Renderer4.CompositorThreadImplDrawDelay is no
-    longer needed due to issue 851784.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time between frames, as measured on the compositor thread. This is collected
-    once per frame while it is being drawn to the screen in the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.drawPixelCountCulled" units="NormalizedPixels"
-    expires_after="2013-05-24">
-  <obsolete>
-    Renamed to Renderer4.pixelCountCulled_Draw.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels that culling prevented being drawn to the screen,
-    normalized to the viewport size. This is collected once per frame while it
-    is being drawn to the screen in the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.drawPixelCountOpaque" units="NormalizedPixels"
-    expires_after="2013-05-24">
-  <obsolete>
-    Renamed to Renderer4.pixelCountOpaque_Draw.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels drawn to the screen and known opaque, normalized to the
-    viewport size. This is collected once per frame while it is being drawn to
-    the screen in the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.drawPixelCountTranslucent" units="NormalizedPixels"
-    expires_after="2013-05-24">
-  <obsolete>
-    Renamed to Renderer4.pixelCountTranslucent_Draw.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels drawn to the screen and not known opaque, normalized to the
-    viewport size. This is collected once per frame while it is being drawn to
-    the screen in the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.FinishDocToFinish" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;finish doc&quot; to &quot;finish.&quot; &quot;Finish
-    doc&quot;== main document loaded, before onload(). &quot;Finish&quot;==after
-    onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.FinishToFirstPaintAfterLoad" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;finish &quot; to &quot;first paint after load.&quot;
-    &quot;Finish&quot;==after onload() and all resources are loaded. &quot;First
-    paint after load&quot;== time after onload() when first paint operation is
-    performed.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GestureScrollingThreadStatus"
-    enum="ScrollingThreadStatus" expires_after="2018-09-25">
-  <obsolete>
-    Removed 9/2018 and merged into Renderer4.MainThreadGestureScrollReason.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    For every touch scroll, we record whether the scroll occurred on the main
-    thread, on the compositor thread, or on the compositor thread but blocked on
-    the main thread. The last case will happen when there is a blocking event
-    listener.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuImageUploadState.FirstRefWasted"
-    enum="BooleanWasted" expires_after="2017-10-18">
-  <obsolete>
-    Removed as of 06/2017. No longer generated.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    Indication whether the first ref of a GPU image upload was wasted (not used
-    in raster). Images are uploaded prior to raster; this indicates whether the
-    upload was used during the first ref.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuImageUploadState.Used" enum="BooleanUsage"
-    expires_after="2017-10-18">
-  <obsolete>
-    Removed as of 06/2017. No longer generated.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    Indication whether the GPU image upload was used in raster. Images are
-    uploaded prior to raster; this indicates whether the upload was used during
-    raster.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuRasterizationSlowPathsWithNonAAPaint"
-    enum="BooleanHasSlowPathsWithNonAAPaint" expires_after="M78">
-  <obsolete>
-    Removed 10/2019.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <owner>enne@chromium.org</owner>
-  <summary>
-    If gpu rasterization is enabled, whether this page contains both slow-paths
-    (making it suitable for MSAA) and non-AA paints (making it not-suitable for
-    MSAA). This indicates a case where we would like to use MSAA, but may have
-    to avoid it for correctness reasons.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuRasterizationSuitableContent"
-    enum="BooleanEnabled" expires_after="M79">
-  <obsolete>
-    Removed 10/2019. Gpu rasterization is no longer dynamically triggerd by
-    content.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <owner>enne@chromium.org</owner>
-  <summary>
-    If gpu rasterization is enabled, whether the page contents contain no more
-    than 5 slow paths, and is suitable for non-MSAA gpu rasterization (checked
-    once after the page is painted for the first time).
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuRasterizationTriggered" enum="BooleanEnabled"
-    expires_after="2019-09-13">
-  <obsolete>
-    Removed 09/2019. Gpu rasterization is no longer dynamically triggerd by
-    content.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <owner>enne@chromium.org</owner>
-  <summary>
-    If gpu rasterization is enabled, whether it was triggered (checked once
-    after the page is painted for the first time).
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.GpuRasterizationUsed" enum="BooleanEnabled"
-    expires_after="2019-02-13">
-  <obsolete>
-    Removed 02/2019. Due to changes in the code, this is synonymous with
-    Renderer4.GpuRasterizationEnabled.
-  </obsolete>
-  <owner>alokp@chromium.org</owner>
-  <summary>
-    If gpu rasterization is enabled, whether it was actually used for the page
-    (checked once after the page is painted for the first time).
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.IdealContentsScale" units="units"
-    expires_after="2018-02-10">
-  <obsolete>
-    Removed 02/2018. The ideal content scale closely matches the default device
-    scale factor.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    The contents scale at which picture layer impl should be rasterized in order
-    to appear crisp. This is also known as ideal contents scale. This value is
-    recorded any time the ideal contents scale changes. Some examples of this
-    are pinch-zoom and JavaScript transform changes.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ImageDecodeMipLevel" units="mip level"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    The mip level at which images are decoded for rasterization in the renderer.
-    This value is recorded each time an image is decoded in the compositor and
-    records the mip level used for the decode. Note that the mip levels recorded
-    lie between [1, 32], with the value of 1 indicating the use of the original
-    image.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ImagePixelsPercentSRGB" units="%"
-    expires_after="M85">
-  <obsolete>
-    Removed July 2020, expired and no longer useful.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    For each cc::Layer that has more than zero discardable images, this metric
-    records the percent of image pixels that were from images that were
-    originally specified in an sRGB color space.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ImagesPercentSRGB" units="%" expires_after="M85">
-  <obsolete>
-    Removed July 2020, expired and no longer useful.
-  </obsolete>
-  <owner>ccameron@chromium.org</owner>
-  <summary>
-    For each cc::Layer that has more than zero discardable images, this metric
-    records the percent of images that were originally specified in an sRGB
-    color space.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.LanguageDetection" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed in 06/2018, M69. Renderer4.LanguageDetection is no longer needed due
-    to issue 851784.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time to determine the page language. This is done after the page has been
-    loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.LCDText.PercentageOfAALayers" units="%"
-    expires_after="2015-02-18">
-  <obsolete>
-    Removed as of 02/2015. No longer generated.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    The ratio of LCDText CC Layers / candidate LCDText layers. Recorded in
-    LayerTreeHost, after LayerTreeHostCommon::CalculateDrawProperties() has
-    computed the properties we need. Only recorded for the first 50 frames of
-    every page.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.LCDText.PercentageOfCandidateLayers" units="%"
-    expires_after="2015-02-18">
-  <obsolete>
-    Removed as of 02/2015. No longer generated.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    The ratio of CC Layers which are candidates for LCDText AA / total picture
-    or content Layers. Recorded in LayerTreeHost, after
-    LayerTreeHostCommon::CalculateDrawProperties() has computed the properties
-    we need. Only recorded for the first 50 frames of every page.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.LoadType" enum="LoadType" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Probability distribution for enumerated varieties of page loads.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.LockExistingCachedImage" enum="BooleanSuccess"
-    expires_after="M85">
-  <obsolete>
-    Removes as of 6/2020. We now get enough cache hit information from
-    Renderer4.SoftwareImageDecodeState* and don't need to divide it into tile
-    bins.
-  </obsolete>
-  <owner>cblume@chromium.org</owner>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    For each attempted lock of a cached image, records whether it was
-    successful.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.MomentumScrollOrderingJankPercentage" units="%"
-    expires_after="2019-07-30">
-  <obsolete>
-    Obsolete after 07/2019. Investigation concluded.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The percentage of input events which are janks (not processed in the
-    expected frame) during each momentum scroll gesture due to unstable ordering
-    of begin frame with regards to input delivery. Computed by tracking the
-    number of times we coalesce an extra input event close to the point at which
-    we process it. Added to track the impact of https://crbug.com/952930. Logged
-    once after a scroll with momentum events completes.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.pixelCountPainted" units="NormalizedPixels"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels painted by WebKit into main memory, recorded as 10 times
-    the percentage of the viewport that these pixels cover. This is collected
-    once per commit from WebKit to the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.RasterSourceClearType" enum="RasterSourceClearType"
-    expires_after="M77">
-  <obsolete>
-    Not used after M77. No longer tuning this code.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The type of clear which was needed for each cc::RasterSource rasterized.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ReadyToDrawTileDrawStatus" enum="UsedInDraw"
-    expires_after="2017-02-09">
-  <obsolete>
-    Removed 02/2017 in Issue 675840.
-  </obsolete>
-  <owner>vmpstr@chromium.org</owner>
-  <summary>
-    For each tile that was ready to draw at some point, logs whether the tile
-    was actually used in a draw. This is logged at tile destruction time.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Renderer.PartialRasterPercentageSaved" units="%"
-    expires_after="M80">
-  <obsolete>
-    Obsolete as of M80. Partial raster has shipped for a long period of time /
-    is not being tuned.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Percentage of pixels which would have been rastered, but were skipped due to
-    the partial raster optimization. Logged for each raster task run in a
-    Renderer process. The histogram is suffixed by the RasterBufferProvider
-    which is in use.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Renderer.RasterTaskSchedulingDelay"
-    units="microseconds" expires_after="2020-08-22">
-  <obsolete>
-    Obsolete as of 11/2019. Replaced by
-    Renderer4.Renderer.RasterTaskSchedulingDelayNoAtRasterDecodes since the
-    semantics changed: we used to count raster tasks that depended on at-raster
-    image decodes, but this is no longer the case.
-  </obsolete>
-  <owner>andrescj@chromium.org</owner>
-  <owner>chromeos-gfx@google.com</owner>
-  <summary>
-    The wall time elapsed between creating a raster task in the client and being
-    ready to issue raster work to the driver in the GPU process. This includes
-    time decoding and uploading images.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.RequestToFinish" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;request&quot; to &quot;finish.&quot; &quot;Request&quot;==
-    time when user requested document. &quot;Finish&quot;==after onload() and
-    all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.RequestToStart" units="ms"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;request&quot; to &quot;start.&quot; &quot;Request&quot;==
-    time when user requested document. &quot;Start&quot;== time when renderer
-    requested load of document, after any unload of last document.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ReservedMemory" units="MB" expires_after="M85">
-  <obsolete>
-    Removed in M85 as no longer being needed.
-  </obsolete>
-  <owner>bbudge@chromium.org</owner>
-  <summary>
-    The size of the contiguous memory block reserved in the renderer so that
-    large allocations are more likely to succeed. The reservation is currently
-    made in BlinkInitializer.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.ResourcePoolMemoryUsage" units="MB"
-    expires_after="M85">
-  <obsolete>
-    07/2020: Replaced by the Compositing.ResourcePoolMemoryUsage.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Size of the in-use portion of the ResourcePool. Recorded each time resources
-    are reclaimed after tile work completes.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Snapshot" units="units" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>Time to capture a renderer snapshot.</summary>
-</histogram>
-
-<histogram name="Renderer4.SoftwareCompositorThreadImplDrawDelay" units="ms"
-    expires_after="2018-07-03">
-  <obsolete>
-    Removed in 06/2018, M69. Renderer4.SoftwareCompositorThreadImplDrawDelay is
-    no longer needed due to issue 851784.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time between frames when the software renderer is being used, as measured on
-    the compositor thread. This is collected once per frame while it is being
-    drawn to the screen in the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.SoftwareDoDeferredUpdateDelay" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>Time between frames when the page is not GPU accelerated.</summary>
-</histogram>
-
-<histogram name="Renderer4.SoftwarePaintDurationMS" units="units"
-    expires_after="2017-08-21">
-  <obsolete>
-    Removed in issue 755432 as no longer being needed.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time spent by WebKit painting the page, in milliseconds, when the page is
-    not GPU accelerated.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.SoftwarePaintMegapixPerSecond" units="units"
-    expires_after="2017-08-21">
-  <obsolete>
-    Removed in issue 755432 as no longer being needed.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    WebKit paint throughput, measured in megapixels per second, when the page is
-    not GPU accelerated.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.StartToCommit" units="ms" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;start&quot; to &quot;commit.&quot; &quot;Start&quot;== time
-    when renderer requested load of document, after any unload of last document.
-    &quot;Commit&quot;== time when renderer got first byte of document.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.StartToFinish" units="ms" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Time from &quot;start&quot; to &quot;finish.&quot; &quot;Start&quot;== time
-    when renderer requested load of document, after any unload of last document.
-    &quot;Finish&quot;==after onload() and all resources are loaded.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.TextureGpuUploadTimeUS" units="units"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    The number of microseconds it took to upload a tile's full texture as
-    measured on the GPU process.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.Thumbnail" units="units" expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>Time to capture a renderer thumbnail.</summary>
-</histogram>
-
-<histogram name="Renderer4.tileCountCulled_Upload" units="NormalizedTiles"
-    expires_after="2019-02-14">
-  <obsolete>
-    Removed at an unknown time. No longer used in code.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of tiles that culling prevented being uploaded to texture memory.
-    This is an approximation and is recorded as a 100 times the percentage of
-    the number of tiles, of default size, needed to cover the viewport. This is
-    collected once per commit from WebKit to the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.uploadPixelCountCulled" units="NormalizedPixels"
-    expires_after="2013-05-24">
-  <obsolete>
-    Removed as of 04/2012, replaced with Renderer4.tileCountCulled_Upload.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels that culling prevented being uploaded to texture memory,
-    normalized to the viewport size. This is collected once per commit from
-    WebKit to the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.uploadPixelCountOpaque" units="NormalizedPixels"
-    expires_after="2013-05-24">
-  <obsolete>
-    Renamed to Renderer4.pixelCountOpaque_Upload.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels uploaded to texture memory and known to be opaque,
-    normalized to the viewport size. This is collected once per commit from
-    WebKit to the compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.uploadPixelCountTranslucent"
-    units="NormalizedPixels" expires_after="2013-05-24">
-  <obsolete>
-    Renamed to Renderer4.pixelCountTranslucent_Upload.
-  </obsolete>
-  <owner>wiltzius@chromium.org</owner>
-  <summary>
-    Number of pixels uploaded to texture memory and not known opaque, normalized
-    to the viewport size. This is collected once per commit from WebKit to the
-    compositor.
-  </summary>
-</histogram>
-
-<histogram name="Renderer4.WheelScrollingThreadStatus"
-    enum="ScrollingThreadStatus" expires_after="2018-09-25">
-  <obsolete>
-    Removed 9/2018 and merged into Renderer4.MainThreadWheelScrollReason.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    For every wheel tick, we record whether the scroll occurred on the main
-    thread, on the compositor thread, or on the compositor thread but blocked on
-    the main thread. The last case will happen when there is a blocking event
-    listener.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.BackgroundedRendererTransition"
-    enum="BackgroundedRendererTransition" expires_after="2018-06-13">
-  <obsolete>
-    Removed 6/2018 and replaced with PageScheduler.PageLifecycleStateTransition.
-  </obsolete>
-  <owner>fmeawad@chromium.org</owner>
-  <owner>panicker@chromium.org</owner>
-  <summary>
-    Tracks the transitions of the renderer scheduler when it is backgrounded.
-    Once it is backgrounded, it can be stopped after a timeout, stopped due to
-    critical resources, resumed or foregrounded.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.BackgroundRendererMainThreadLoad" units="%"
-    expires_after="2017-05-23">
-  <obsolete>
-    Replaced with RendererScheduler.BackgroundRendererMainThreadLoad2 as of May
-    2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load when renderer is backgrounded, i.e. percentage of
-    time spent on running tasks.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per minute per
-    renderer amortized.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.BackgroundRendererMainThreadLoad2" units="%"
-    expires_after="2017-07-13">
-  <obsolete>
-    Replaced with
-    RendererScheduler.RendererMainThreadLoad3.Background.AfterFirstMinute as of
-    July 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load when renderer is backgrounded, i.e. percentage of
-    time spent on running tasks.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per minute per
-    renderer amortized.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.ExpectedQueueingTimeByFrameStatus"
-    units="microseconds" expires_after="2018-01-31">
-  <obsolete>
-    Replaced with RendererScheduler.ExpectedQueueingTimeByFrameStatus2 as of Feb
-    2018. Buckets were changed.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to their frame status, in
-    microseconds. The sum of the split values will be equal to the total,
-    reported on RendererScheduler.ExpectedTaskQueueingDuration2. Recorded for
-    each 1000 ms window.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.ExpectedQueueingTimeByFrameStatus2"
-    units="microseconds" expires_after="2019-03-18">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to their frame status, in
-    microseconds. The sum of the split values will be equal to the total,
-    reported on RendererScheduler.ExpectedTaskQueueingDuration3. Recorded for
-    each 1000 ms window.
-  </summary>
-</histogram>
-
-<histogram base="true" name="RendererScheduler.ExpectedQueueingTimeByFrameType"
-    units="ms" expires_after="2017-12-12">
-  <obsolete>
-    Replaced with RendererScheduler.ExpectedQueueingTimeByFrameStatus as of
-    December 2017.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to their frame type. The sum
-    of the split values should be equal to the total, reported on
-    RendererScheduler.ExpectedTaskQueueingDuration. Recorded for each 1000 ms
-    window.
-  </summary>
-</histogram>
-
-<histogram base="true" name="RendererScheduler.ExpectedQueueingTimeByTaskQueue"
-    units="microseconds" expires_after="2018-01-31">
-  <obsolete>
-    Replaced with RendererScheduler.ExpectedQueueingTimeByTaskQueue2 as of Feb
-    2018. Buckets were changed.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to the type of their task
-    queue, in microseconds. The sum of the split values should be equal to the
-    total, reported on RendererScheduler.ExpectedTaskQueueingDuration2. Recorded
-    for each 1000 ms window.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.ExpectedQueueingTimeByTaskQueue2"
-    units="microseconds" expires_after="2019-02-05">
-  <obsolete>
-    Removed February 2019.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to the type of their task
-    queue, in microseconds. The sum of the split values should be equal to the
-    total, reported on RendererScheduler.ExpectedTaskQueueingDuration3. Recorded
-    for each 1000 ms window.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.ExpectedQueueingTimeByTaskQueueType" units="ms"
-    expires_after="2017-12-12">
-  <obsolete>
-    Replaced with RendererScheduler.ExpectedQueueingTimeByTaskQueue as of
-    December 2017.
-  </obsolete>
-  <owner>npm@chromium.org</owner>
-  <summary>
-    Expected queueing time split by tasks according to the type of their task
-    queue. The sum of the split values should be equal to the total, reported on
-    RendererScheduler.ExpectedTaskQueueingDuration. Recorded for each 1000 ms
-    window.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ExpectedQueueingTimeWhenQueueingTime"
-    units="ms" expires_after="2018-04-29">
-  <obsolete>
-    Removed 04/2018.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Expected queueing time for events which were queued on the main thread
-    longer or shorter than a threshold, given by the QueueingTimeThreshold
-    suffix.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ExpectedTaskQueueingDuration" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    The estimated queueing duration which would be observed for additional high
-    priority tasks posted to the RendererScheduler. Recorded for each 1000 ms
-    window.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ExpectedTaskQueueingDuration2"
-    units="microseconds" expires_after="2018-01-31">
-  <obsolete>
-    Replaced with RendererScheduler.ExpectedTaskQueueingDuration3 as of Feb
-    2018. Buckets were changed.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>npm@chromium.org</owner>
-  <summary>
-    The estimated queueing duration which would be observed for additional high
-    priority tasks posted to the RendererScheduler, in microseconds. Recorded
-    for each 1000 ms window.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ExpectedTaskQueueingDuration3"
-    units="microseconds" expires_after="M85">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>npm@chromium.org</owner>
-  <owner>speed-metrics-dev@chromium.org</owner>
-  <summary>
-    The estimated queueing duration which would be observed for additional high
-    priority tasks posted to the RendererScheduler, in microseconds. Recorded
-    for each 1000 ms window.
-
-    Do not modify this metric in any way without contacting
-    speed-metrics-dev@chromium.org.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="RendererScheduler.ExpectedTaskQueueingDurationWithoutMainFrame"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed March 2019.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <owner>npm@chromium.org</owner>
-  <summary>
-    The estimated queueing duration which would be observed for additional high
-    priority tasks posted to the RendererScheduler, in microseconds, for
-    renderer processes that do not host any main frame. Recorded for each 1000
-    ms window.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ForegroundRendererMainThreadLoad" units="%"
-    expires_after="2017-05-23">
-  <obsolete>
-    Replaced with RendererScheduler.ForegroundRendererMainThreadLoad2 as of May
-    2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load when renderer is foregrounded, i.e. percentage of
-    time spent on running tasks.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per minute per
-    renderer amortized.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.ForegroundRendererMainThreadLoad2" units="%"
-    expires_after="2017-07-13">
-  <obsolete>
-    Replaced with
-    RendererScheduler.RendererMainThreadLoad3.Foreground.AfterFirstMinute as of
-    July 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load when renderer is foregrounded, i.e. percentage of
-    time spent on running tasks.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per minute per
-    renderer amortized.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.MaxQueueingTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>maxlg@chromium.org</owner>
-  <summary>
-    The single maximum estimated queueing duration (or max queueing time)
-    between when user starts navigation and user navigates away. Navigate-away
-    is defined as a fast shutdown or a natural ending of renderer, or the new
-    navigation start which replacing the old navigation.
-
-    The queueing time is estimated on a sliding window basis. The width of the
-    sliding window is 1 second, the sliding step being 50ms. The max queueing
-    time keeps track of the largest queueing time on each slide.
-
-    This metric resets itself at navigation start, updates the max of queueing
-    time with the sliding window moving, reports the max queueing times to the
-    histogram at the next navigation start of the same or different renderer
-    process.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.NumberOfTasksPerQueueType"
-    enum="RendererSchedulerTaskQueueType" expires_after="2017-05-23">
-  <obsolete>
-    Replaced with RendererScheduler.NumberOfTasksPerQueueType2 as of May 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    The number of completed renderer tasks split per task queue type. Used to
-    monitor usage of each type of task queue. Reported each time when task is
-    completed.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.NumberOfTasksPerQueueType2"
-    enum="RendererSchedulerTaskQueueType" expires_after="2017-07-25">
-  <obsolete>
-    Replaced with RendererScheduler.TaskCountPerQueueType as of July 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    The number of completed renderer tasks split per task queue type. Used to
-    monitor usage of each type of task queue. Reported each time when task is
-    completed.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.QueueingDurationWhenExpectedQueueingTime"
-    units="ms" expires_after="2017-08-03">
-  <obsolete>
-    Removed as of 08/2017. Replaced with
-    RendererScheduler.ExpectedQueueingTimeWhenQueueingTime.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    Time between sending an event to the renderer main thread and when the
-    renderer begins to process that event, for events which were dispatched when
-    the expected queueing time was past some threshold.
-
-    Team: input-dev@chromium.org.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.RendererMainThreadLoad3" units="%"
-    expires_after="2017-08-02">
-  <obsolete>
-    This metric still used 1-minute reporting chunks. Replaced with
-    RendererMainThreadLoad4 as of July 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load (percentage of time spent in tasks), reported in
-    one minute chunks.
-
-    See http://bit.ly/chromium-renderer-main-thread-load-metric for details.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per second per
-    renderer amortized.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.RendererMainThreadLoad4" units="%"
-    expires_after="2017-08-10">
-  <obsolete>
-    Replaced with RendererMainThreadLoad5 as of August 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load (percentage of time spent in tasks), reported in
-    one second chunks.
-
-    See http://bit.ly/chromium-renderer-main-thread-load-metric for details.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per second per
-    renderer amortized.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskCPUDurationPerTaskType.DedicatedWorker"
-    enum="RendererSchedulerTaskType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskCPUDurationPerTaskType2.DedicatedWorker
-    as of June 2018 due to overflows (crbug.com/809668). Some metrics are
-    incremented with large amounts that they sometimes overflow and roll
-    negative before they get uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total duration of dedicated worker tasks (thread time) split by per thread
-    type. Reported each time when task is completed and current accumulated
-    duration is longer than 1ms.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskCPUDurationPerThreadType"
-    enum="RendererSchedulerThreadType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskCPUDurationPerThreadType2 as of June
-    2018 due to overflows (crbug.com/809668). Some metrics are incremented with
-    large amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total cpu time of renderer tasks split by per thread type. Wall time is
-    tracked by RendererScheduler.TaskDurationPerThreadType histogram. This
-    histogram is used to compare CPU usage of tasks from different threads.
-
-    Only 1% of randomly sampled tasks have cpu time measured and report duration
-    for this histogram.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram base="true" name="RendererScheduler.TaskDurationPerFrameOriginType"
-    enum="RendererSchedulerFrameOriginType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerFrameOriginType2 as of June
-    2018 due to overflows (crbug.com/809668). Some metrics are incremented with
-    large amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total cpu time of renderer tasks split by per frame origin type (main frame
-    vs same-origin frame vs cross-origin frame).
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerFrameType"
-    enum="RendererSchedulerFrameType" expires_after="2017-11-02">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerFrameType2 due to the
-    introduction of new types of frames as of 11/2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total duration of renderer per-frame tasks split per frame type. Used to
-    monitor workload coming from different frames. Reported each time when task
-    is completed and current accumulated duration is longer than 1ms.
-
-    This metric is susceptible to problematic outliers and should be analyzed
-    with custom scripts accounting for that rather than from a dashboard.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerFrameType2"
-    enum="RendererSchedulerFrameType2" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerFrameType3 as of June 2018
-    due to overflows (crbug.com/809668). Some metrics are incremented with large
-    amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total duration of renderer per-frame tasks split per frame type. Used to
-    monitor workload coming from different frames. Reported each time when task
-    is completed and current accumulated duration is longer than 1ms.
-
-    This metric is susceptible to problematic outliers and should be analyzed
-    with custom scripts accounting for that rather than from a dashboard.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerQueueType"
-    enum="RendererSchedulerTaskQueueType" expires_after="2017-05-23">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerQueueType2 as of May 2017.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    Total duration of renderer tasks split per task queue type. Used to monitor
-    usage of each type of task queues. Reported each time when task is completed
-    and current accumulated duration is longer than 1ms.
-
-    This metric is susceptible to problematic outliers and should be analyzed
-    with custom scripts accounting for that rather than from a dashboard.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerQueueType2"
-    enum="RendererSchedulerTaskQueueType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerQueueType3 as of June 2018
-    due to overflows (crbug.com/809668). Some metrics are incremented with large
-    amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    Total duration of renderer tasks split per task queue type. Used to monitor
-    usage of each type of task queues. Reported each time when task is completed
-    and current accumulated duration is longer than 1ms.
-
-    This metric is susceptible to problematic outliers and should be analyzed
-    with custom scripts accounting for that rather than from a dashboard.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerTaskType"
-    enum="RendererSchedulerTaskType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerTaskType2 as of June 2018 due
-    to overflows (crbug.com/809668). Some metrics are incremented with large
-    amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>hajimehoshi@chromium.org</owner>
-  <summary>
-    Total duration of renderer per-frame tasks split per task type. Used to
-    monitor usage of each task type. Reported each time when task is completed
-    and current accumulated duration is longer than 1ms.
-
-    This metric is susceptible to problematic outliers and should be analyzed
-    with custom scripts accounting for that rather than from a dashboard.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerTaskType.DedicatedWorker"
-    enum="RendererSchedulerTaskType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerTaskType2.DedicatedWorker as
-    of June 2018 due to due to overflows (crbug.com/809668). Some metrics are
-    incremented with large amounts that they sometimes overflow and roll
-    negative before they get uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Total duration of dedicated worker tasks (wall time) split by per thread
-    type. Reported each time when task is completed and current accumulated
-    duration is longer than 1ms.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerThreadType"
-    enum="RendererSchedulerThreadType" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerThreadType2 as of June 2018
-    due to overflows (crbug.com/809668). Some metrics are incremented with large
-    amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    Total duration of renderer tasks split by per thread type. Used to compare
-    CPU usage of tasks from different threads. Reported each time when task is
-    completed and current accumulated duration is longer than 1ms.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskDurationPerUseCase"
-    enum="RendererSchedulerTaskUseCase" expires_after="2018-06-12">
-  <obsolete>
-    Replaced with RendererScheduler.TaskDurationPerUseCase2 as of June 2018 due
-    to overflows (crbug.com/809668). Some metrics are incremented with large
-    amounts that they sometimes overflow and roll negative before they get
-    uploaded.
-  </obsolete>
-  <owner>altimin@chromium.org</owner>
-  <owner>farahcharab@chromium.org</owner>
-  <summary>
-    Total duration (measured in ms) of renderer main thread tasks split by
-    scheduler use case. Use case is a scheduler's educated guess of the current
-    state of the world. See renderer/use_case.h and
-    RendererSchedulerImpl::UpdatePolicy for more details.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskQueueManager.DelayedTaskLateness"
-    units="ms" expires_after="2017-08-30">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    The delta between when a delayed task was scheduled to run and when the
-    RendererScheduler actually ran it. Note: to reduce overhead only 10% of
-    tasks are sampled.
-  </summary>
-</histogram>
-
-<histogram
-    name="RendererScheduler.TaskQueueManager.ImmediateTaskQueueingDuration"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    The queueing duration for non-delayed tasks posted to the RendererScheduler.
-    This metric is only recorded if TrackingInfo::time_posted is set (i.e. not
-    on android). Note: to reduce overhead only 10% of tasks are sampled.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.TaskTime" units="microseconds"
-    expires_after="2017-05-23">
-  <obsolete>
-    Replaced with RendererScheduler.TaskTime2 as of May 2017.
-  </obsolete>
-  <owner>sunyunjia@chromium.org</owner>
-  <owner>tdresser@chromium.org</owner>
-  <summary>
-    The duration of every task queued in the _renderer_ scheduler to see the
-    distribution of the task duration.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.TimeRunningOtherAgentsWhileTaskReady"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed 07/2020. Summary of collected data: https://crbug.com/1019856#c6.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>etiennep@chromium.org</owner>
-  <summary>
-    Time spent running tasks from other agents between when an agent task
-    becomes ready and when it starts running. A non-delayed task is ready when
-    it is posted. A delayed task is ready when its delay expires. Recorded for 1
-    out of 1000 tasks.
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="RendererScheduler.TimeRunningOtherFramesWhileTaskReady"
-    units="microseconds" expires_after="M78">
-  <obsolete>
-    Removed 11/2019. Replace with
-    RendererScheduler.TimeRunningOtherAgentsWhileTaskReady.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>etiennep@chromium.org</owner>
-  <summary>
-    Time spent running tasks from other frames between when a frame task becomes
-    ready and when it starts running. A non-delayed task is ready when it is
-    posted. A delayed task is ready when its delay expires. Recorded for 1 out
-    of 1000 tasks.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.UserModel.GestureDuration" units="ms"
-    expires_after="2017-08-30">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>Duration of gestures (scrolls and pinches).</summary>
-</histogram>
-
-<histogram name="RendererScheduler.UserModel.GesturePredictedCorrectly"
-    enum="GesturePredictionResult" expires_after="2017-08-30">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>Whether a user gesture was predicted correctly.</summary>
-</histogram>
-
-<histogram name="RendererScheduler.UserModel.GestureStartTimeSinceModelReset"
-    units="ms" expires_after="2017-08-30">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>
-    Time between when the UserModel was last reset (which happens on navigation)
-    and a gesture starting.
-  </summary>
-</histogram>
-
-<histogram name="RendererScheduler.UserModel.TimeBetweenGestures" units="ms"
-    expires_after="2017-08-30">
-  <obsolete>
-    Removed from code 2017-08.
-  </obsolete>
-  <owner>alexclarke@chromium.org</owner>
-  <summary>Time between subsequent gestures (scrolls and pinches).</summary>
-</histogram>
-
-<histogram name="RenderFrameHostImpl.ReceivedPostMessageFromNonDescendant"
-    enum="BooleanReceived" expires_after="2018-10-30">
-  <obsolete>
-    Removed Oct 2018.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>boliu@chromium.org</owner>
-  <summary>
-    Record whether a local root frame ever received post messages from another
-    cross origin frame that's not a descendent. This is useful to evaluate if a
-    frame is safe to be reloaded automatically. Recorded when a frame crashed
-    while invisible, and then becomes visible to the user; this is the point a
-    crashed frame would be reloaded. Note this is not logged for the main frame,
-    which only has descendant frames.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidChangeScrollOffset" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidChangeScrollOffset.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidClearWindowObject" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidClearWindowObject.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidCommitProvisionalLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidCommitProvisionalLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidCreateScriptContext" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidCreateScriptContext.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidFailProvisionalLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidFailProvisionalLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidFinishDocumentLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidFinishDocumentLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidFinishLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidFinishLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidMeaningfulLayout" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidMeaningfulLayout.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.DidStartProvisionalLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.DidStartProvisionalLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.FocusedNodeChanged" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.FocusedNodeChanged.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.OnMessageReceived" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.OnMessageReceived.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.ScriptedPrint" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.ScriptedPrint.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.WillCommitProvisionalLoad" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.WillCommitProvisionalLoad.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.WillSendSubmitEvent" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.WillSendSubmitEvent.
-  </summary>
-</histogram>
-
-<histogram name="RenderFrameObservers.WillSubmitForm" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Cumulative time spent by all RenderFrameObservers in
-    RenderFrameImpl.WillSubmitForm.
-  </summary>
-</histogram>
-
-<histogram name="RenderViewContextMenu.OpenLinkAsUser" enum="OpenLinkAsUser"
-    expires_after="M85">
-  <obsolete>
-    Removed as of June 2020.
-  </obsolete>
-  <owner>jochen@chromium.org</owner>
-  <summary>
-    State of the profile that is activated via the &quot;Open Link as User&quot;
-    menu. Logged when one of the &quot;Open Link as User&quot; context menu
-    options is selected.
-  </summary>
-</histogram>
-
-<histogram name="RenderViewContextMenu.OpenLinkAsUserProfilesState"
-    enum="OpenLinkAsUserProfilesState" expires_after="M85">
-  <obsolete>
-    Removed as of June 2020.
-  </obsolete>
-  <owner>jochen@chromium.org</owner>
-  <summary>
-    Whether or not other profiles are active when the &quot;Open Link as
-    User&quot; context menu is shown. Logged when the context menu is created.
-  </summary>
-</histogram>
-
-<histogram name="RenderViewContextMenu.OpenLinkAsUserShown" units="profiles"
-    expires_after="2020-11-02">
-  <obsolete>
-    Removed as of June 2020.
-  </obsolete>
-  <owner>jochen@chromium.org</owner>
-  <summary>
-    Count of the profiles shown for the &quot;Open Link as User&quot; context
-    menu. Logged when the context menu is created.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.HeaderEndpointGroupOutcome"
-    enum="ReportingHeaderEndpointGroupOutcome" expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.HeaderEndpointGroupOutcome.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a single endpoint group in a
-    Report-To header once the header itself has been parsed.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.HeaderEndpointOutcome"
-    enum="ReportingHeaderEndpointOutcome" expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.HeaderEndpointOutcome.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a single endpoint in a Report-To
-    header once the header itself has been parsed.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.HeaderOutcome" enum="ReportingHeaderOutcome"
-    expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.HeaderOutcome.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to process a Report-To header. Once it is
-    parsed, Reporting.HeaderEndpointOutcome records the outcome of the endpoints
-    within it.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.ReportDeliveredAttempts" units="attempts"
-    expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.ReportDeliveredAttempts.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    When Reporting successfully delivers a report, the number of unsuccessful
-    delivery attempts that preceded the successful one.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.ReportDeliveredLatency" units="ms"
-    expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.ReportDeliveredLatency.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The delivery latency of reports successfully delivered by Reporting. Starts
-    when the report is queued and finishes when the delivery attempt returns
-    successfully.
-  </summary>
-</histogram>
-
-<histogram name="Reporting.ReportOutcome" enum="ReportingReportOutcome"
-    expires_after="2018-03-16">
-  <obsolete>
-    Moved to Net.Reporting.ReportOutcome.
-  </obsolete>
-  <owner>juliatuttle@chromium.org</owner>
-  <summary>
-    The outcome of Reporting trying to deliver a report, recorded when the
-    report is finally erased from memory.
-  </summary>
-</histogram>
-
-<histogram name="ReportingAndNEL.DBSizeInKB" units="KB" expires_after="M82">
-  <obsolete>
-    Removed as of March 9, 2020.
-  </obsolete>
-  <owner>chlily@chromium.org</owner>
-  <owner>sburnett@chromium.org</owner>
-  <summary>
-    Size on disk of the Reporting and NEL database. This is recorded when the
-    database is initialized, which typically happens upon the first network
-    request after startup.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.DismissalState"
-    enum="AutofillDialogDismissalState" expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    The state of the requestAutocomplete() dialog when it was dismissed.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.InitialUserState"
-    enum="AutofillDialogInitialUserState" expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    The initial state of a user that's interacting with a freshly shown
-    requestAutocomplete() dialog.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.PopupInDialog"
-    enum="AutofillDialogPopupEvent" expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    User interactions with the Autofill popup shown while filling an
-    requestAutocomplete() dialog.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.Security" enum="AutofillDialogSecurity"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the frequency of security warnings and errors in the
-    RequestAutocomplete dialog.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.UiDuration" units="ms"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the duration for which an requestAutocomplete() dialog was shown.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.UiDuration.Cancel" units="ms"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the duration for which an requestAutocomplete() dialog was shown,
-    in cases where the user ended up canceling out of the dialog.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.UiDuration.Submit" units="ms"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the duration for which an requestAutocomplete() dialog was shown,
-    in cases where the user ended up accepting the dialog.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.UiEvents" enum="AutofillDialogUiEvents"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures how users are interacting with the requestAutocomplete() dialog UI.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.UiLatencyToShow" units="ms"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the duration of time it takes for the requestAutocomplete() UI to
-    be actionable by the user after it is shown.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.WalletErrors" enum="WalletErrors"
-    expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the frequency of errors in communicating with the Google Online
-    Wallet server.
-  </summary>
-</histogram>
-
-<histogram name="RequestAutocomplete.WalletRequiredActions"
-    enum="WalletRequiredActions" expires_after="2016-05-05">
-  <obsolete>
-    Removed as of 5/5/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the frequency of required user actions returned by the Google
-    Online Wallet server.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.IPCPerMinute.Frame" units="count/m"
-    expires_after="2019-01-21">
-  <obsolete>
-    Removed as of 18/1/2019.
-  </obsolete>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    The number of IPCs from frame to GRC. Recorded every 1 minute.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.IPCPerMinute.Page" units="count/m"
-    expires_after="2019-01-21">
-  <obsolete>
-    Removed as of 18/1/2019.
-  </obsolete>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    The number of IPCs from page to GRC. Recorded every 1 minute.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.IPCPerMinute.Process" units="count/m"
-    expires_after="2019-01-21">
-  <obsolete>
-    Removed as of 18/1/2019.
-  </obsolete>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    The number of IPCs from process to GRC. Recorded every 1 minute.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.DatabaseInit"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="M77">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.DatabaseInitAfterDelete"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="M77">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database after deleting
-    it after a failed repair attempt.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.DatabaseInitAfterRepair"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="M77">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database after a repair
-    attempt.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.DatabaseRepair"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of trying to repair the Local Site Characteristics database after
-    a failed open.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.ObservationTimeBeforeFirstUse"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="LocalSiteCharacteristicsFeatures" -->
-
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The cumulative observation time before a feature tracked in the Local Site
-    Characteristics database gets used.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.OnDiskSize" units="KB"
-    expires_after="M85">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The size of the Local Site Characteristics database on disk. Recorded at
-    startup when the database gets opened.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.LocalDB.ReadHasCompletedBeforeQuery"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed July 2020.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    Boolean indicating if the read operation from the Local Site Characteristics
-    database has completed when we query for the characteristics of a site.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.Duration" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>The amount of wall-clock time a measurement cycle occupied.</summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.Memory.ExtraProcesses"
-    units="processes" expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    The number of unexpected processes encountered during memory measurement.
-    This is expected to be non-zero as new processes can be created after a
-    measurement cycle is initiated, plus non-renderer processes are counted here
-    at the moment.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.Memory.LateNotification"
-    enum="Boolean" expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    A boolean that measures how often a performance measurement notification
-    arrives at a WebContents that has been re-navigated.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.Memory.Outcome"
-    enum="MemoryMeasurementOutcome" expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    An enumeration indicating the outcome of each memory measurement attempt.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.Memory.UnmeasuredProcesses"
-    units="processes" expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    The number of processes that didn't get a memory measurement. This can
-    happen if processes die as or after measurement is initiated.
-  </summary>
-</histogram>
-
-<histogram name="ResourceCoordinator.Measurement.TotalProcesses"
-    units="processes" expires_after="M80">
-  <obsolete>
-    Removed April 2019. No longer recorded.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    The number of processes that were measured for CPU at least.
-  </summary>
-</histogram>
-
-<histogram name="ResourceLoadingHints.CountBlockedSubresourcePatterns"
-    units="pattern count" expires_after="M85">
-  <obsolete>
-    Obsoleted July 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The count of resource loading blocking patterns received by the renderer.
-    Recorded every time resource loading hints mojom message is received.
-    Recorded at most once per triggered navigation.
-  </summary>
-</histogram>
-
-<histogram name="ResourceLoadingHints.PageHints.ProcessedCount"
-    units="pattern count" expires_after="2019-03-12">
-  <obsolete>
-    Removed 03/2019 as it was never a useful metric.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The count of page hints received by the browser from the component updater.
-    Recorded every time a page hint is received by the browser from the
-    optimization guide service.
-  </summary>
-</histogram>
-
-<histogram name="ResourceLoadingHints.PageHints.TotalReceived"
-    units="total page hints count" expires_after="2019-03-12">
-  <obsolete>
-    Removed 03/2019 as it was never a useful metric.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total count of page hints received by the browser from the component
-    updater. Only the page hints that have at least one resource loading hint
-    are counted. One sample is recorded every time optimization guide service
-    processes the optimization hints provided by the component updater. The
-    count of hints loaded to memory may be lower than this.
-  </summary>
-</histogram>
-
-<histogram name="ResourceLoadingHints.ResourceHints.TotalReceived"
-    units="total resource loading hints count" expires_after="2019-03-12">
-  <obsolete>
-    Removed 03/2019 as it was never a useful metric.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    The total count of resource loading hints across all page hints received by
-    the browser from the component updater. One sample is recorded every time
-    optimization guide service processes the optimization hints provided by the
-    component updater. The count of hints loaded to memory may be lower than
-    this.
-  </summary>
-</histogram>
-
-<histogram name="ResourceLoadingHints.ResourcePatternsAvailableAtCommit"
-    enum="BooleanAvailable" expires_after="M85">
-  <obsolete>
-    Obsoleted July 2020.
-  </obsolete>
-  <owner>tbansal@chromium.org</owner>
-  <summary>
-    Records if the resource patterns were available at the time of page commit
-    if the committed previews type was RESOURCE_LOADING_HINTS.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.CachePattern"
-    enum="HttpCachePattern" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Like HttpCache.Pattern but only for requests made during speculative
-    prefetch. Logged per successful request.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.DatabaseReadiness" units="%"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    This metric measures the host coverage of the predictor database: On each
-    navigation, it records what percentage of the top X history entries are
-    found in the predictor DB. Caveats: (1) This metric is only recorded once
-    the user has accumulated enough browsing history, implemented as a minimum
-    threshold of total page visits by the user. (2) This metric is sampled, so
-    it's actually only recorded for 1 out of every K navigations.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.DbStringTooLong" units="units"
-    expires_after="2016-10-05">
-  <obsolete>
-    Removed October 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    A boolean that used to indicate a corner case when certain resources are not
-    written to the Predictor database becuase their URLs are too long. We
-    monitor this number to ensure that we do not discard too many resources.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HavePredictionsForUrl" units="units"
-    expires_after="2014-10-30">
-  <obsolete>
-    Removed 08/2012. Replaced with ResourcePrefetchPredictorNavigationEvent.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    A boolean that indicates if the speculative resource prefetch predictor has
-    predictions for a Navigation. This is updated on each navigations and helps
-    us determine the coverage of the predictor.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HavePrefetchResults" units="units"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    A boolean that used to indicate a corner case when we may not have prefetch
-    results even though prefetching is enabled and predictions are present,
-    because another navigation in the same tab canceled the prefetching of the
-    previous load.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HistoryVisitCountForUrl"
-    units="units" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    The visit count of a URL in the history database, measured when the onload
-    fires for the URL. Helpful in figuring out what visit count should be used
-    to start learning about a URL.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PredictedPrefetchCount"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Assuming a fixed number (25 or 50) of URLs could be prefetched max, how many
-    would be available for prefetch (after we apply our heuristics for picking
-    subresources to prefetch for a navigation).
-
-    This stat is recorded when the predictor uses the host of the main frame url
-    as the key for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PredictedPrefetchFromCache"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the cache restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the host of the main frame url
-    as the key for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PredictedPrefetchFromNetwork"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the network restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the host of the main frame url
-    as the key for prediction.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Host.PredictedPrefetchFromNetworkPercentOfTotalFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Similar to ResourcePrefetchPredictor.Host.PredictedPrefetchFromNetwork but
-    as a percent of the total number of resources the page actually fetched from
-    the network. This depcits the major gains that we can get.
-
-    This stat is recorded when the predictor uses the host of the main frame url
-    as the key for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PredictedPrefetchMisses"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page not used
-    by the page, restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the host of the main frame url
-    as the key for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchCancelled" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    prefetches cancelled as a percentage of the total number of resources that
-    the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchFailed" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    prefetches failed as a percentage of the total number of resources that the
-    predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchFromCacheNotUsed"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from cache while prefetching but were not
-    requested by the page, as a percentage of the total number of resources that
-    the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchFromCacheUsedFromCache"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from cache while prefetching and also came
-    from the cache when the page requested it, as a percentage of the total
-    number of resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Host.PrefetchFromCacheUsedFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from cache while prefetching but came from
-    the network when the page requested it, as a percentage of the total number
-    of resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchFromNetworkNotUsed"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from network while prefetching but were not
-    requested by the page, as a percentage of the total number of resources that
-    the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Host.PrefetchFromNetworkUsedFromCache"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from network while prefetching but came from
-    the cache when the page requested it, as a percentage of the total number of
-    resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Host.PrefetchFromNetworkUsedFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of
-    successful prefetches that came from cache while prefetching and also came
-    from the network when the page requested it, as a percentage of the total
-    number of resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Host.PrefetchNotStarted" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of resources
-    that were prefetchable but were not prefetched as a percentage of
-    prefetchable resources.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HostTableHostCount" units="units"
-    expires_after="2017-01-27">
-  <obsolete>
-    Removed January 2017. This is effectively the same as
-    ResourcePrefetchPredictor.HostTableRowCount2 after refactoring of the
-    predictor database.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The count of number of unique hosts in the HostTable, i.e. the number of
-    hosts that the database has prediction data for. This data is useful for
-    determining the recall/precision as a function of the number of hosts that
-    need to be tracked by the database. Measured at startup.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HostTableRowCount" units="units"
-    expires_after="2017-01-27">
-  <obsolete>
-    Removed January 2017. Replaced by
-    ResourcePrefetchPredictor.HostTableRowCount2.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The count of number of rows in the HostTable. This is effecively the number
-    of (host, resource URL) pairs in the database. This is measured at startup
-    and used to get an estimate of the data size.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.HostTableRowCount2" units="hosts"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    The number of rows in the HostTable. This is effectively the number of hosts
-    in the database. This is measured at startup and used to get an estimate of
-    the data size.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.LearningCount" units="urls"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    When the prefetch predictor has resources in the local database for a given
-    navigation, the count of predicted urls.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.LearningPrecision" units="%"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    When the prefetch predictor has resources in the local database for a given
-    navigation, the precision of the predictions, in percentage. This is
-    computed as 100 \times \frac{correct predictions}{predictions}.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.LearningRecall" units="%"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    When the prefetch predictor has resources in the local database for a given
-    navigation, the recall of the predictions, in percentage. This is computed
-    as 100 \times \frac{correct predictions}{all prefetchable subresources}.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.MainFrameRequestStats"
-    enum="ResourcePrefetchPredictorMainFrameRequestStats" expires_after="M80">
-  <obsolete>
-    Obsoleted in M-69.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Records stats about main frame navigations. Records the total number of
-    requests/responses/redirects for main frame urls along with the numbers for
-    how often the predictor can process such events. This is useful to figure
-    out what percentange of requests are handled by the predictor and also for
-    sanity checking the other stats.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.NavigationEvent"
-    enum="ResourcePrefetchPredictorNavigationEvent" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Records stats about various interesting events such as - request start,
-    response start, redirect, onload, etc during the load of a main frame.
-    Essential for understanding the complete life of a navigation request start
-    to the onload fire and the events that occur in between.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.NavigationStatus"
-    enum="ResourcePrefetchPredictorNavigationStatus" expires_after="2014-10-30">
-  <obsolete>
-    Removed 08/2012. Replaced with ResourcePrefetchPredictorNavigationEvent.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The status of various navigations from the view point of the 'onload' event.
-    Since we measure the prediction accuracy and learn navigation subresources
-    on the onload event, it is useful to know how many of the navigations are
-    abandoned before 'onload' fires.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.NetworkType"
-    enum="ResourcePrefetchPredictorNetworkType" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Records the number of pages on each type of network after a page is loaded.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PLT" units="ms"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Page load time. It starts from when the main frame URL request is sent out
-    to when the main frame document load is completed.
-
-    This is recorded for both prefetched and non-prefetched pages.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PredictedPrefetchCount"
-    units="units" expires_after="2014-10-30">
-  <obsolete>
-    Removed 01/2013. Replaced with specific ones for Url and Host.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Assuming a fixed number of URLs could be prefetched max, how many would be
-    available for prefetch (after we apply our heuristics for picking
-    subresources to prefetch for a navigation).
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PredictedPrefetchFromCache"
-    units="units" expires_after="2014-10-30">
-  <obsolete>
-    Removed 01/2013. Replaced with specific ones for Url and Host.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the cache restricted to some max predictions.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PredictedPrefetchFromNetwork"
-    units="units" expires_after="2014-10-30">
-  <obsolete>
-    Removed 01/2013. Replaced with specific ones for Url and Host.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the network restricted to some max predictions.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.PredictedPrefetchFromNetworkPercentOfTotalFromNetwork"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed 01/2013. Replaced with specific ones for Url and Host.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Similar to ResourcePrefetchPredictor.Predicted.PrefetchFromNetwork but as a
-    percent of the total number of resources the page actually fetched from the
-    network. This depcits the major gains that we can get.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PredictedPrefetchMisses"
-    units="units" expires_after="2014-10-30">
-  <obsolete>
-    Removed 01/2013. Replaced with specific ones for Url and Host.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page not used
-    by the page, restricted to some max predictions.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchedCount" units="count"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    The count of successfully prefetched subresources for a single page.
-    Recorded after all subresource prefetches have reached a terminal
-    success/failure state.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchedSizeKB" units="KB"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    The total amount of data consumed by predictor for a single page. Only
-    successfully finished requests taken into account. Recorded after all
-    subresource prefetches have reached a terminal success/failure state.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchHitsCount.Cached"
-    units="count" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Number of resources that were prefetched and requested by a page load, for
-    cached requests. Logged after the prefetcher completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchHitsCount.NotCached"
-    units="count" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Number of resources that were prefetched and requested by a page load, for
-    non cached requests. Logged after the prefetcher completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchHitsSizeKB" units="KB"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Amount of useful data fetched from the network for a prefetch request. This
-    is the total size of the resources accounted for in
-    ResourcePrefetchPredictor.PrefetchHitsCount.NotCached. Logged after the
-    prefetcher completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchingDuration" units="ms"
-    expires_after="2018-11-21">
-  <obsolete>
-    Removed at M72. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Amount of time available for prefetching. Specifically, this is a time
-    interval between corresponding StartPrefetching() and StopPrefetching()
-    calls. This is recorded for both prefetched and non-prefetched pages.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchMissesCount.Cached"
-    units="count" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Number of resources that were prefetched but not requested by a page load,
-    for cached requests. Logged after the prefetcher completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchMissesCount.NotCached"
-    units="count" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Number of resources that were prefetched but not requested by a page load,
-    for non cached requests, that is waste. Logged after the prefetcher
-    completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.PrefetchMissesSizeKB" units="KB"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    Amount of wasted data fetched from the network for a prefetch request. This
-    is the total size of the resources accounted for in
-    ResourcePrefetchPredictor.PrefetchMissesCount.NotCached. Logged after the
-    prefetcher completes.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.RedirectStatus"
-    enum="ResourcePrefetchPredictorRedirectStatus" expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    When the prefetch predictor has resources in the local database for a given
-    navigation, records stats about whether redirect was predicted correctly or
-    incorrectly.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.ReportingEvent"
-    enum="ResourcePrefetchPredictorReportingEvent" expires_after="2018-11-21">
-  <obsolete>
-    Removed at M72. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Records stats about various interesting events such as - when partial or all
-    of history is cleared. It will include events which do not necessarily
-    happen during a navigation (which are reported in
-    ResourcePrefetchPredictor.NavigationEvent).
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.RequestStats"
-    enum="ResourcePrefetchPredictorRequestStats" expires_after="M80">
-  <obsolete>
-    Obsoleted in M-69.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Records stats about requests, redirects, and responses observed by the
-    LoadingPredictorObserver. These stats are useful as a baseline for other
-    stats.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.ResourceStatus"
-    enum="ResourcePrefetchPredictorResourceStatus" expires_after="2016-08-09">
-  <obsolete>
-    Removed 08/2016 with the removal of the recording code.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The distribution of the reasons for which subresources are ignored during
-    prefetching. This helps us prioritze reasons we should further investigate
-    to increase coverage. This is reported as a bit map and every status will be
-    a bitwise or of the underlying reasons.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PredictedPrefetchCount"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Assuming a fixed number of URLs could be prefetched max (25 or 50), how many
-    would be available for prefetch (after we apply our heuristics for picking
-    subresources to prefetch for a navigation).
-
-    This stat is recorded when the predictor uses the main frame url as the key
-    for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PredictedPrefetchFromCache"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the cache restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the main frame url as the key
-    for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PredictedPrefetchFromNetwork"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page and served
-    from the network restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the main frame url as the key
-    for prediction.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Url.PredictedPrefetchFromNetworkPercentOfTotalFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Similar to ResourcePrefetchPredictor.Url.PredictedPrefetchFromNetwork but as
-    a percent of the total number of resources the page actually fetched from
-    the network. This depcits the major gains that we can get.
-
-    This stat is recorded when the predictor uses the main frame url as the key
-    for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PredictedPrefetchMisses"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    When we have predictions for a navigation, we measure the accuracy of the
-    predictions against the actual resources downloaded. This histogram gives
-    the distribution of the predictions that were fetched by the page not used
-    by the page, restricted to some max predictions (25 or 50).
-
-    This stat is recorded when the predictor uses the main frame url as the key
-    for prediction.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchCancelled" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of prefetches
-    cancelled as a percentage of the total number of resources that the
-    predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchFailed" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of prefetches
-    failed as a percentage of the total number of resources that the predictor
-    tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchFromCacheNotUsed"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from cache while prefetching but were not requested by
-    the page, as a percentage of the total number of resources that the
-    predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchFromCacheUsedFromCache"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from cache while prefetching and also came from the
-    cache when the page requested it, as a percentage of the total number of
-    resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Url.PrefetchFromCacheUsedFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from cache while prefetching but came from the network
-    when the page requested it, as a percentage of the total number of resources
-    that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchFromNetworkNotUsed"
-    units="%" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from network while prefetching but were not requested
-    by the page, as a percentage of the total number of resources that the
-    predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Url.PrefetchFromNetworkUsedFromCache"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from network while prefetching but came from the cache
-    when the page requested it, as a percentage of the total number of resources
-    that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.Url.PrefetchFromNetworkUsedFromNetwork"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on the main frame URL, the percentage of successful
-    prefetches that came from cache while prefetching and also came from the
-    network when the page requested it, as a percentage of the total number of
-    resources that the predictor tried to prefetch.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.Url.PrefetchNotStarted" units="%"
-    expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    For prefetching based on host of main frame URL, the percentage of resources
-    that were prefetchable but were not prefetched as a percentage of
-    prefetchable resources.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.UrlTableMainFrameUrlCount"
-    units="units" expires_after="2016-09-02">
-  <obsolete>
-    Removed September 2016. This is effectively the same as
-    ResourcePrefetchPredictor.UrlTableRowCount2 after refactoring of the
-    predictor database.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The count of number of unique main frame urls in the UrlTable, i.e. the
-    number of webpages that the database has prediction data for. This data is
-    useful for determining the recall/precision as a function of the number of
-    webpages that need to be tracked by the database. Measured at startup.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.UrlTableMainFrameUrlsDeletedNotInHistory"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed October 2012. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The count of number of unique main frame urls that are deleted from the URL
-    table at startup because they are no longer in history. Essential to figure
-    out how much data we are loosing out.
-  </summary>
-</histogram>
-
-<histogram
-    name="ResourcePrefetchPredictor.UrlTableMainFrameUrlsDeletedNotInHistoryPercent"
-    units="%" expires_after="M80">
-  <obsolete>
-    Removed October 2012. No longer recorded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    Same as ResourcePrefetchPredictor.UrlTableMainFrameUrlsDeletedNotInHistory
-    but recording percentage of URLs in the table rather than absolute numbers.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.UrlTableRowCount" units="units"
-    expires_after="2017-01-27">
-  <obsolete>
-    Removed January 2017. Replaced by
-    ResourcePrefetchPredictor.UrlTableRowCount2.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The count of number of rows in the UrlTable. This is effecively the number
-    of (main frame URL, resource URL) pairs in the database. This is measured at
-    startup and used to get an estimate of the data size.
-  </summary>
-</histogram>
-
-<histogram name="ResourcePrefetchPredictor.UrlTableRowCount2" units="urls"
-    expires_after="2018-02-28">
-  <obsolete>
-    Removed at M66. No longer recorded.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    The number of rows in the UrlTable. This is effectively the number of main
-    frame URLs in the database. This is measured at startup and used to get an
-    estimate of the data size.
-  </summary>
-</histogram>
-
-<histogram name="ResourceReporter.BrowserProcess.CpuUsage"
-    enum="ResourceReporterCpuUsage" expires_after="M85">
-  <obsolete>
-    Removed 04/2020.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The CPU usage range reported for the browser process when the Chrome OS
-    device memory pressure (which is the percentage of total memory used by the
-    system) is critical. This is emitted only when memory pressure changes from
-    a low pressure to a higher pressure.
-  </summary>
-</histogram>
-
-<histogram name="ResourceReporter.BrowserProcess.MemoryUsage"
-    enum="ResourceReporterMemoryUsage" expires_after="M85">
-  <obsolete>
-    Removed 04/2020.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The system memory usage range reported for the browser process when the
-    Chrome OS device memory pressure (which is the percentage of total memory
-    used by the system) is critical. This is emitted only when memory pressure
-    changes from a low pressure to a higher pressure.
-  </summary>
-</histogram>
-
-<histogram name="ResourceReporter.GpuProcess.CpuUsage"
-    enum="ResourceReporterCpuUsage" expires_after="M85">
-  <obsolete>
-    Removed 04/2020.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The CPU usage range reported for the GPU process when the Chrome OS device
-    memory pressure (which is the percentage of total memory used by the system)
-    is critical. This is emitted only when memory pressure changes from a low
-    pressure to a higher pressure.
-  </summary>
-</histogram>
-
-<histogram name="ResourceReporter.GpuProcess.MemoryUsage"
-    enum="ResourceReporterMemoryUsage" expires_after="M85">
-  <obsolete>
-    Removed 04/2020.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The system's RAM memory usage range reported for the GPU process when the
-    Chrome OS device memory pressure (which is the percentage of total memory
-    used by the system) is critical. This is emitted only when memory pressure
-    changes from a low pressure to a higher pressure.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.ClientLoadedTime.Active" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the ResourceScheduler is informed of a
-    Client's creation or starts loading and when that Client finishes loading in
-    a Client which has been user-observable the entire time.
-
-    Note: Will not include time for the main resource if PlzNavigate is in use.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.ClientLoadedTime.Background" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the ResourceScheduler is informed of a
-    Client's creation or starts loading and when that Client finishes loading in
-    a Client which has been background the entire time.
-
-    Note: Will not include time for the main resource if PlzNavigate is in use.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.ClientLoadedTime.Other" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the ResourceScheduler is informed of a
-    Client's creation or starts loading and when that Client finishes loading in
-    a Client which has switched between Active and Background.
-
-    Note: Will not include time for the main resource if PlzNavigate is in use.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.ClientLoadedTime.Other.SwitchedToActive"
-    units="units" expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between the last time that a Client becomes
-    user-observable and when that Client finishes loading in a Client that was
-    user-observable when the load completed.
-
-    Note: Will not include time for the main resource if PlzNavigate is in use.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeDeferred.Active" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time the ResourceScheduler is throttling a request after
-    WillStartRequest is called for a request in a client that was
-    user-observable at creation and start time.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeDeferred.Background"
-    units="units" expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time the ResourceScheduler is throttling a request after
-    WillStartRequest is called for a request in a client that was background at
-    creation and start time.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeDeferred.Other" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time the ResourceScheduler is throttling a request after
-    WillStartRequest is called on a request without a Client or a request in a
-    Client which is in a different state since the request was made. Note that
-    this won't capture requests which have switched state an even number of
-    times. Switching from Active to Background back to Active will be recorded
-    in the Active version of this histogram.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeThrottled.Active" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the request was created and when the
-    ResourceScheduler stops throttling the request in a client that was
-    user-observable at creation and start time.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeThrottled.Background"
-    units="units" expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the request was created and when the
-    ResourceScheduler stops throttling the request in a client that was
-    background at creation and start time.
-  </summary>
-</histogram>
-
-<histogram name="ResourceScheduler.RequestTimeThrottled.Other" units="units"
-    expires_after="2016-01-29">
-  <obsolete>
-    Removed 1/2016
-  </obsolete>
-  <owner>aiolos@chromium.org</owner>
-  <summary>
-    The amount of time between when the request was created and when the
-    ResourceScheduler stops throttling a request without a client or a request
-    in a Client which is in a different state since the request was made. Note
-    that this won't capture requests which have switched state an even number of
-    times. Switching from Active to Background back to Active will be recorded
-    in the Active version of this histogram.
-  </summary>
-</histogram>
-
-<histogram name="RTCQuicStream.ReadIntoAmountBytes" units="units"
-    expires_after="M75">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>shampson@chromium.org</owner>
-  <owner>steveanton@chromium.org</owner>
-  <summary>
-    The amount of data that gets read out via each call to the RTCQuicStream
-    readInto() API. The RTCQuicStream can record multiple ReadIntoAmountBytes in
-    its lifetime.
-  </summary>
-</histogram>
-
-<histogram name="RTCQuicStream.ReadIntoResult"
-    enum="RTCQuicStreamReadIntoResult" expires_after="M75">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>shampson@chromium.org</owner>
-  <owner>steveanton@chromium.org</owner>
-  <summary>
-    How data is read out with a finish (FIN) bit for each call to the
-    RTCQuicStream readInto API. The RTCQuicStream can record multiple
-    ReadIntoResults in its lifetime.
-  </summary>
-</histogram>
-
-<histogram name="RTCQuicStream.WriteAmountBytes" units="units"
-    expires_after="M75">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>shampson@chromium.org</owner>
-  <owner>steveanton@chromium.org</owner>
-  <summary>
-    The amount of data that gets written via each call to the RTCQuicStream
-    write() API. The RTCQuicStream can record multiple WriteAmountBytes in its
-    lifetime.
-  </summary>
-</histogram>
-
-<histogram name="RTCQuicStream.WriteUsage" enum="RTCQuicStreamWriteUsage"
-    expires_after="M75">
-  <obsolete>
-    Removed in M76.
-  </obsolete>
-  <owner>shampson@chromium.org</owner>
-  <owner>steveanton@chromium.org</owner>
-  <summary>
-    How data is written with a finish (FIN) bit for each call to the
-    RTCQuicStream write() API. The RTCQuicStream can record multiple WriteUsages
-    in its lifetime.
-  </summary>
-</histogram>
-
-<histogram name="SadTab.Created" enum="SadTabKind" expires_after="2015-06-02">
-  <obsolete>
-    Replaced with Tabs.SadTab.* in R20.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Track number of times we built a sad tab page for a renderer crash or kill.
-    The user may not have seen the page if it was not the frontmost tab.
-  </summary>
-</histogram>
-
-<histogram name="SadTab.Displayed" enum="SadTabKind" expires_after="2015-06-02">
-  <obsolete>
-    Replaced with Tabs.SadTab.* in R20.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Track number of times the user actually saw a sad tab page for a renderer
-    crash or kill.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ContentsSize.Height" units="DIPs"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the height of content area when the user opens a new browser window
-    or when the user finishes resizing a browser window.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ContentsSize.Width" units="DIPs"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the width of content area when the user opens a new browser window
-    or when the user finishes resizing a browser window.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.EnabledSettingChanged" enum="BooleanEnabled"
-    expires_after="2015-10-16">
-  <obsolete>
-    Not in the code anymore (10/2015).
-  </obsolete>
-  <owner>feng@chromium.org</owner>
-  <summary>
-    Records the user action that enables/disables safe browsing feature in the
-    Settings page on Android.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FileTypeUpdate.DynamicUpdateTypeCount"
-    units="number of file types" expires_after="M80">
-  <obsolete>
-    Removed in M80 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Number of file types (aka file extensions) present in the FileTypePolicies
-    proto loaded.
-
-    This is for the file types loaded from the component-update system. This
-    includes both those loaded from disk shortly after startup, and those
-    received over the network when the component version changes
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FileTypeUpdate.ResourceBundleTypeCount"
-    units="number of file types" expires_after="M80">
-  <obsolete>
-    Removed in M80 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Number of file types (aka file extensions) present in the FileTypePolicies
-    proto loaded.
-
-    This is for the file types loaded from the resource bundle packaged with
-    Chrome, which is always loaded at startup.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FontSize.Default" units="pts" expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Records the default font size on user startup.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FontSize.DefaultFixed" units="pts"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Records the default fixed font size on user startup.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FontSize.Minimum" units="pts" expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Records the minimum font size on user startup.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.FontSize.MinimumLogical" units="pts"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Was used to get a general sense of this value when planning
-    visual features in PhishGuard pings.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Records the minimum logical font size on user startup.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.GetV4HashHttpResponseOrErrorCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Network.Result.
-  </obsolete>
-  <owner>kcarattini@google.com</owner>
-  <summary>
-    Response or error codes from the SafeBrowsing Pver4 service. Logged after a
-    GetHash or request finishes to capture the response code or error code for
-    that call.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.GetV4HashNetwork" units="ms"
-    expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Network.Time.
-  </obsolete>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    The time that it took to receive a response from the Safe Browsing servers
-    for a V4 GetHash request.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.GetV4HashResult"
-    enum="SafeBrowsingV4OperationResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Result.
-  </obsolete>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Track return status from V4 GetHash attempts. The buckets of this histogram
-    overlap, so the counts cannot be used as percentages.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ModuleBaseRelocation" enum="BaseRelocationType"
-    expires_after="M85">
-  <obsolete>
-    No longer used. Removed 2020-06.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <owner>proberge@google.com</owner>
-  <summary>
-    A windows only historgram. Records when an unknown base relocation type is
-    encountered while reading the reloc table of a loaded module.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.NavigationObserver.IPAddressCleanUpCount"
-    units="units" expires_after="2018-09-21">
-  <obsolete>
-    Removed in M71+.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Count of how many ResolvedIPAddresses get removed in each periodic clean up.
-    This is a rough estimation of the number of IPs associated with main frame
-    and sub-frame navigations every two minutes.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.NotificationImageReporter.NetError"
-    enum="NetErrorCodes" expires_after="M85">
-  <obsolete>
-    Removed in M85+.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The net error code for failed reports sent by NotificationImageReporter, or
-    net::OK if successful.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ParseV4HashResult"
-    enum="SafeBrowsingParseV4HashResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Parse.Result.
-  </obsolete>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    Track the parsing results of a status 200 GetV4Hash request.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ParseV4UpdateResult"
-    enum="SafeBrowsingParseV4UpdateResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4Update.Parse.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the parsing results of a status 200 GetV4Update request.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.Pref.Scout" enum="NullableBoolean"
-    expires_after="2021-01-30">
-  <obsolete>
-    Removed in or before M86. See SafeBrowsing.Pref.Extended
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Tracks the Extended Reporting preference transition. Suffixes track which
-    opt-in text users are viewing and the values of each Extended Reporting
-    preference. Recorded for all non-Incognito profiles on profile startup.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.Pref.Scout.Decision"
-    enum="ScoutActiveExtendedReportingPref" expires_after="M85">
-  <obsolete>
-    This is unused due to it being part of SBER1. Deprecated 06/01/2020.
-  </obsolete>
-  <owner>lpz@chromium.org</owner>
-  <summary>
-    Tracks user decisions about the Extended Reporting opt-in on security
-    interstitials by comparing the initial and final states of the preference.
-    Suffixes specify the type of change that was made. Recorded when a user
-    closes a security interstitial or navigates away.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.Pref.Scout.SetPref" enum="BooleanEnabled"
-    expires_after="2021-01-30">
-  <obsolete>
-    Removed in or before M86. See SafeBrowsing.Pref.Extended.*
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Tracks the Extended Reporting preference being changed. Suffixes track which
-    Extended Reporting preference was changed, and the specific UI that the
-    change was made on. Recorded when a user changes the preference on any UI.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.Pref.Scout.Transition"
-    enum="ScoutTransitionReason" expires_after="2021-01-30">
-  <obsolete>
-    Removed in or before M86.
-  </obsolete>
-  <owner>lpz@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Tracks reasons for the Extended Reporting preference transition, such as a
-    user entering an experiment group or seeing a security interstitial for the
-    first time. Recorded for all non-Incognito profiles on profile startup.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ThreatReport.DomIsAmbiguous" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed in M78 due to lack of use and utility. See crbug.com/975258
-  </obsolete>
-  <owner>lpz@chromium.org</owner>
-  <summary>
-    A threat report contains a DOM hierarchy that is ambiguous. This indicates
-    that the parent/child relationship among the elements in the DOM may not be
-    accurate.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.ThreatReport.MaxNodesExceededInFrame"
-    enum="BooleanExceeded" expires_after="M77">
-  <obsolete>
-    Removed in M78 due to lack of use and utility. See crbug.com/975258
-  </obsolete>
-  <owner>lpz@chromium.org</owner>
-  <summary>
-    Whether the threat report generated for a subframe of a page hit the maximum
-    number of nodes. When this is true, the data from that frame will be
-    truncated.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.UnverifiedDownloads.Allowed"
-    enum="SBClientDownloadExtensions" expires_after="M85">
-  <obsolete>
-    Removed 09-2020 since this is no longer recorded.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    File types that were allowed to be downloaded without verifying their
-    content nor their source URLs with Safe Browsing.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.UnverifiedDownloads.AllowedByWhitelist"
-    enum="SBClientDownloadExtensions" expires_after="M85">
-  <obsolete>
-    Removed 09-2020 since this is no longer recorded.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    File types that were allowed to be downloaded without verifying their
-    content nor their source URLs with Safe Browsing due to the requestor URL
-    being on the Safe Browsing whitelist. Each sample recorded on this histogram
-    is also recorded in SafeBrowsing.UnverifiedDownloads.Allowed.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.UnverifiedDownloads.AllowedDueToDisabledService"
-    enum="SBClientDownloadExtensions" expires_after="M85">
-  <obsolete>
-    Removed 09-2020 since this is no longer recorded.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    File types that were allowed to be downloaded without verifying their
-    content nor their source URLs with Safe Browsing due to the SafeBrowsing
-    service being disabled. Each sample recorded on this histogram is also
-    recorded in SafeBrowsing.UnverifiedDownloads.Allowed.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.UnverifiedDownloads.AlternateExtensionCount"
-    units="units" expires_after="M85">
-  <obsolete>
-    Removed 09-2020 since this is no longer recorded.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Count of alternate extensions that were supplied when attempting to download
-    a file without verifying their content nor their source URLs with Safe
-    Browsing.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.UnverifiedDownloads.Blocked"
-    enum="SBClientDownloadExtensions" expires_after="M85">
-  <obsolete>
-    Removed 09-2020 since this is no longer recorded.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    File types that were blocked from downloaded without verifying their content
-    nor their source URLs with Safe Browsing.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4AddUnlumpedHashes.Time" units="ms"
-    expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/25/2018 since it was not being used actively or monitored.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to copy the SafeBrowsing list update as a string,
-    into a map which contains the hash prefixes that are looked up when a client
-    queries for the reputation of a resource (URL, full hash, etc.).
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4AddUnlumpedHashesTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4AddUnlumpedHashes.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to copy the SafeBrowsing list update as a string,
-    into a map which contains the hash prefixes that are looked up when a client
-    queries for the reputation of a resource (URL, full hash, etc.).
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ApplyUpdateResult"
-    enum="SafeBrowsingV4ApplyUpdateResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4*.ApplyUpdate.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the result of applying the update fetched from the PVer4 service for a
-    particular store.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ApplyUpdateResultWhenReadingFromDisk"
-    enum="SafeBrowsingV4ApplyUpdateResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ReadFromDisk.ApplyUpdate.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the result of applying an update read from disk after parsing it
-    successfully as a protobuf.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4DecodeAdditionsResult"
-    enum="SafeBrowsingV4DecodeResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4*.DecodeAdditions.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the result of decoding the Rice-encoded list of additions of 4-byte
-    hash prefixes. This is logged once per store, per update containing
-    Rice-encoded additions.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4DecodeAdditionsTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4*.DecodeAdditions.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded additions to the
-    blacklist into raw format.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4DecodeRemovalsResult"
-    enum="SafeBrowsingV4DecodeResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ProcessPartialUpdate.DecodeRemovals.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the result of decoding the Rice-encoded list of indexes of hash
-    prefixes to remove since the last update. This is logged once per store, per
-    update containing Rice-encoded removals.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4DecodeRemovalsTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ProcessPartialUpdate.DecodeRemovals.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded removals from the
-    blacklist into raw format.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4FullHashCacheResult"
-    enum="SafeBrowsingV4FullHashCacheResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.CacheHit.Result.
-  </obsolete>
-  <owner>kcarattini@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Track cache hits for V4 full hashes.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4GetHashCheckResult"
-    enum="SafeBrowsingV4GetHashCheckResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Check.Result.
-  </obsolete>
-  <owner>kcarattini@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Track get hash response hits for V4 full hash requests.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4GetHashNetwork.Time" units="ms"
-    expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4GetHash.Network.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to receive a response from the Google SafeBrowsing
-    servers for a full hash request.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4GetPrefixMatches.Time" units="ms"
-    expires_after="2018-03-14">
-  <obsolete>
-    Removed in favor of the TimeUs variant
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to check a URL against our in-memory database. It is
-    dominated by the time to perform checks for CheckBrowseUrl.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4GetPrefixMatches.TimeUs" units="microseconds"
-    expires_after="2019-01-09">
-  <obsolete>
-    Removed 01/2019 due to lack of use (Histogram Eraser).
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to check a URL against our in-memory database. It is
-    dominated by the time to perform checks for CheckBrowseUrl. Note that this
-    metric is recorded even for users with low resolution clocks.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4MergeUpdateTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4*.MergeUpdate.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to merge the existing state of the list with the
-    update. The update may have been received from the server, or it may have
-    just been read from disk.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessFullUpdate.ApplyUpdate.Time" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to process a SafeBrowsing list full update. It
-    includes V4AddUnlumpedHashes.Time for each prefix-sized list, and
-    V4ProcessFullUpdate.MergeUpdate.Time. Additionally, if the update is
-    Rice-encoded, it includes V4ProcessFullUpdate.DecodeAdditions.Time for each
-    prefix-sized list that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessFullUpdate.DecodeAdditions.Time"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded additions to the
-    blacklist into raw format when applying a full update to a store.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessFullUpdate.MergeUpdate.Time" units="ms"
-    expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/25/2018 since it was not being used actively or monitored.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to merge the existing state of the list with a
-    full update received from the server.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessFullUpdateTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ProcessFullUpdate.ApplyUpdate.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to process a SafeBrowsing list full update. It
-    includes V4AddUnlumpedHashesTime for each prefix-sized list, and
-    V4MergeUpdateTime. Additionally, if the update is Rice-encoded, it includes
-    V4DecodeAdditionsTime for each prefix-sized list that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdate.Time"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to process a SafeBrowsing list partial update. It
-    includes V4AddUnlumpedHashes.Time for each prefix-sized list, and
-    SafeBrowsing.V4ProcessPartialUpdate.MergeUpdate.Time. Additionally, if the
-    update is Rice-encoded, it includes
-    V4ProcessPartialUpdate.DecodeRemovals.Time, and
-    V4ProcessPartialUpdate.DecodeAdditions.Time for each prefix-sized list
-    that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessPartialUpdate.DecodeAdditions.Time"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded additions to the
-    blacklist into raw format when applying a partial update to a store.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessPartialUpdate.DecodeRemovals.Time"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded removals from the
-    blacklist into raw format when applying a partial update to a store.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessPartialUpdate.MergeUpdate.Time"
-    units="ms" expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/25/2018 since it was not being used actively or monitored.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to merge the existing state of the list with a
-    partial update received from the server.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ProcessPartialUpdateTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdate.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to process a SafeBrowsing list partial update. It
-    includes V4AddUnlumpedHashesTime for each prefix-sized list, and
-    V4MergeUpdateTime. Additionally, if the update is Rice-encoded, it includes
-    V4DecodeRemovalsTime, and V4DecodeAdditionsTime for each prefix-sized list
-    that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ReadFromDisk.ApplyUpdate.Time" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to read, parse, and process a SafeBrowsing list
-    stored on disk. This happens at Chromium start-up. It includes
-    V4AddUnlumpedHashes.Time for each prefix-sized list, and
-    SafeBrowsing.V4ReadFromDisk.MergeUpdate.Time. Additionally, if the file is
-    Rice-encoded, it includes V4ReadFromDisk.DecodeAdditions.Time for each
-    prefix-sized list that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ReadFromDisk.DecodeAdditions.Time" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to decode the Rice-encoded additions to the
-    blacklist into raw format when reading a store file from disk.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ReadFromDisk.MergeUpdate.Time" units="ms"
-    expires_after="2018-04-25">
-  <obsolete>
-    Removed 04/25/2018 since it was not being used actively or monitored.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to perform in-memory copy of the map of raw hash
-    prefixes read from disk.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4ReadFromDiskTime" units="ms"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4ReadFromDisk.ApplyUpdate.Time.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes to read, parse, and process a SafeBrowsing list
-    stored on disk. This happens at Chromium start-up. It includes
-    V4AddUnlumpedHashesTime for each prefix-sized list, and V4MergeUpdateTime.
-    Additionally, if the file is Rice-encoded, it includes V4DecodeAdditionsTime
-    for each prefix-sized list that's Rice-encoded.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4Store.IsStoreAvailable.ValidStore"
-    enum="BooleanAvailable" expires_after="M77">
-  <obsolete>
-    Removed in M77 since the histogram was very stable: crbug.com/984286.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records how often IsStoreAvailable fails due to an invalid store identifier.
-    This is logged each time a store is checked (a few times for each download,
-    and once when a potentially dangerous subresource is loaded).
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4StoreReadResult"
-    enum="SafeBrowsingV4StoreReadResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4StoreRead.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the parsing results of reading the SafeBrowsing V4 store file from
-    disk. Recorded every time a store is read from disk.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4StoreVersionRead" units="version number"
-    expires_after="M77">
-  <obsolete>
-    Removed in M78 since there's only ever been just 1 version number.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Version of V4Store read from a store file. This would be useful in tracking
-    the usage and rollout of new V4Store versions.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4StoreWriteResult"
-    enum="SafeBrowsingV4StoreWriteResult" expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SafeBrowsing.V4StoreWrite.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the results of writing the SafeBrowsing V4 store file to disk.
-    Recorded every time a store is written to disk.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4UnusedStoreFileExists" enum="BooleanExists"
-    expires_after="M85">
-  <obsolete>
-    Removed in M86. See https://crbug.com/1089439
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the presence of store files that were previously created but have been
-    deprecated since so need to be removed from disk. Logged once per startup.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4UnusedStoreFileExists.V3" enum="BooleanExists"
-    expires_after="2019-01-03">
-  <obsolete>
-    Removed in M73. See https://crbug.com/916192
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track the presence of Safe Browsing list files used for PVer3, which has
-    been deprecated. Logged once per startup.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4Update.TimedOut" enum="BooleanTimedOut"
-    expires_after="M77">
-  <obsolete>
-    Removed in M78 due to lack of use and timed out rate being less than 0.03%
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>True if a PVer4 update request timed out.</summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4UpdateHttpResponseOrErrorCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4Update.Network.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Response or error codes when fetching updates from the SafeBrowsing PVer4
-    service.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4UpdateResponseSizeKB" units="KB"
-    expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4Update.ResponseSizeKB.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the response sent by the SafeBrowsing PVer4 service, in KB.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.V4UpdateResult"
-    enum="SafeBrowsingV4OperationResult" expires_after="2016-11-04">
-  <obsolete>
-    Replaced by SafeBrowsing.V4Update.Result.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Track return status from V4 update attempts. The buckets of this histogram
-    overlap, so the counts cannot be used as percentages.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SafeBrowsing.WebSocket.Elapsed" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in June 2020.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Time spent on SafeBrowsing lookup. Since this includes any time spent on the
-    interstitial page the average may not be useful.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.WebSocket.Result"
-    enum="SafeBrowsingWebSocketResult" expires_after="M77">
-  <obsolete>
-    Removed in June 2019.
-  </obsolete>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Results of a SafeBrowsing lookup for a WebSocket handshake. All lookups are
-    counted. Note: the &quot;ABANDONED&quot; bucket contains both connections
-    that were abandoned before the check completed and those that were cancelled
-    when the user navigated away from the SafeBrowsing interstitial.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.WebView.UserConsentVsUrlCheckRace"
-    enum="SafeBrowsingUserConsentVsUrlCheckRaceResult" expires_after="M81">
-  <obsolete>
-    Removed in December 2019 because logic was simplified to remove this race.
-  </obsolete>
-  <owner>ntfschr@chromium.org</owner>
-  <summary>
-    WebView can simultaneously check for user opt-in and Safe-Browsing-check the
-    first URL, with both asynchronous checks racing to finish. This records the
-    outcome of that race: (1) which asynchronous method finished first; (2) if
-    user consent finished first, what was the outcome; and (3) did we show
-    malicious content to the user. This is recorded only once, for the first
-    Safe Browsing check.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsingBinaryUploadRequest.TimeToGetToken" units="ms"
-    expires_after="M90">
-  <obsolete>
-    Removed 06/2020 as SafeBrowsingBinaryUploadRequest.TimeToGetFCMToken
-    provides the same information with a better range of durations.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    This record how long it took for the request to get the FCM token. It is
-    logged every time a deep scanning request successfully gets a token.
-  </summary>
-</histogram>
-
-<histogram name="SB.BloomFilter" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The first stage check that measures the time that Chrome took to check if a
-    URL is present in our in-memory bloom filter.
-  </summary>
-</histogram>
-
-<histogram name="SB.BuildBloom" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD.</summary>
-</histogram>
-
-<histogram name="SB.Database" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The second stage check that measures the time that Chrome took to check if a
-    URL is present in our SQLite database.
-  </summary>
-</histogram>
-
-<histogram name="SB.DBCheck" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The second stage check that mesures the time that Chrome took to check if a
-    URL is present in our SQLite database. This time includes the filter check
-    time.
-  </summary>
-</histogram>
-
-<histogram name="SB.Delay" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This measures the time that SafeBrowsing actually delayed the browsing
-    experience. It records the difference between the time when Chrome would
-    have started reading the response for a URL and when the SafeBrowsing system
-    completed its check of that URL.
-  </summary>
-</histogram>
-
-<histogram name="SB.FilterCheck" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The first stage check that measures the time that Chrome took to check if a
-    URL is present in our in-memory hash table.
-  </summary>
-</histogram>
-
-<histogram name="SB.Network" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The third and final stage check that mesures the time that Chrome took to
-    get a response from the Google SafeBrowsing servers for a particular URL.
-  </summary>
-</histogram>
-
-<histogram name="SB.NetworkCheck" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The third and final stage check that mesures the time that Chrome took to
-    get a response from the Google SafeBrowsing servers for a particular URL.
-    This time includes the filter and database check time.
-  </summary>
-</histogram>
-
-<histogram name="SB.PauseSafe" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    This measures the time that SafeBrowsing actually delayed the browsing
-    experience. It records the difference between the time when Chrome would
-    have started reading the response for a URL and when the SafeBrowsing system
-    completed its check of that URL.
-  </summary>
-</histogram>
-
-<histogram name="SB.Update" units="units" expires_after="2014-07-09">
-  <obsolete>
-    Has not been generated for years (7/8/14).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>TBD.</summary>
-</histogram>
-
-<histogram name="SB2.AddPrefixes" units="units" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of add prefixes stored in the database after the last update.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BloomFailure" enum="SB2BloomFailure"
-    expires_after="2014-07-09">
-  <obsolete>
-    Bloom filter support deleted in October 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Track failures when in processing the safe-browsing database bloom filter.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BloomFilterFalsePositives"
-    enum="SB2BloomFilterFalsePositives" expires_after="2013-11-13">
-  <obsolete>
-    This became misleading around M-22 (September 2012), deleted in M-32
-    (November 2013).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    All prefix misses (server returned no full hashes) and prefix misses due to
-    false positives in the bloom filter.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BloomFilterLoad" units="ms" expires_after="2014-07-09">
-  <obsolete>
-    Bloom filter support deleted in October 2012.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Time to load the BloomFilter file.</summary>
-</histogram>
-
-<histogram name="SB2.BrowseDatabaseKilobytes" units="KB"
-    expires_after="2015-01-05">
-  <obsolete>
-    Removed 12/2014. Moved to SB2.DatabaseSizeKilobytes.Browse.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the browsing SafeBrowsing database file on disk in kilobytes,
-    after an update has occurred.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildFilter" units="ms" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to regenerate the filter after we have received all
-    the update chunks.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildReadBytes" units="bytes" expires_after="2013-04-25">
-  <obsolete>
-    Removed because it was exceeding the range. Replaced by
-    SB2.BuildReadKilobytes.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of bytes read by the browser process during the bloom filter
-    generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildReadKilobytes" units="KB" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of kilobytes read by the browser process during the filter
-    generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildReadOperations" units="units"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of read operations issued by the browser process during the
-    filter generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildWriteBytes" units="bytes" expires_after="2013-04-25">
-  <obsolete>
-    Removed because it was exceeding the range. Replaced by
-    SB2.BuildWriteKilobytes.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of bytes written by the browser process during the bloom filter
-    generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildWriteKilobytes" units="KB" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of kilobytes written by the browser process during the filter
-    generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.BuildWriteOperations" units="units"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of write operations issued by the browser process during the
-    filter generation phase.
-  </summary>
-</histogram>
-
-<histogram name="SB2.ChunkInsert" units="ms" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it takes to write one redirect URL (which can contain multiple
-    chunks) to the database.
-  </summary>
-</histogram>
-
-<histogram name="SB2.ChunkRequest" units="ms" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The network time between the request and response for a chunk.
-  </summary>
-</histogram>
-
-<histogram name="SB2.ChunkSize" units="bytes" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The size of one chunk URL.</summary>
-</histogram>
-
-<histogram name="SB2.DatabaseBytes" units="bytes" expires_after="2013-04-25">
-  <obsolete>
-    Removed because it was exceeding the range. Replaced by
-    SB2.DatabaseKilobytes.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The size of the SafeBrowsing database file on disk.</summary>
-</histogram>
-
-<histogram name="SB2.DatabaseFailure" enum="SB2DatabaseFailure"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Track failures when updating the safe-browsing database.</summary>
-</histogram>
-
-<histogram name="SB2.DatabaseKilobytes" units="KB" expires_after="2015-01-05">
-  <obsolete>
-    Replaced by SB2.BrowseDatabaseKilobytes.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the SafeBrowsing database file on disk in kilobytes.
-  </summary>
-</histogram>
-
-<histogram name="SB2.DatabaseOpen" units="ms" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time it takes to initialize the SafeBrowsing storage backend, in
-    milliseconds.
-  </summary>
-</histogram>
-
-<histogram name="SB2.DatabaseSizeKilobytes" units="KB"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The size of one of the SafeBrowsing database file on disk in kilobytes,
-    after a database update has occurred (once a few minutes after startup, and
-    every thirty minutes or so thereafter).
-  </summary>
-</histogram>
-
-<histogram name="SB2.DatabaseUpdateKilobytes" units="KB"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the update file before merging with the database file, in
-    kilobytes.
-  </summary>
-</histogram>
-
-<histogram name="SB2.Delay" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M65. Replaced by SB2.NoUserActionResourceLoadingDelay
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that SafeBrowsing actually delayed the browsing experience. It
-    records the difference between the time when Chrome would have started
-    reading the response for a URL and when the SafeBrowsing system completed
-    its check of that URL. This is the sum of .Mainframe and .Subresource
-    breakout metrics.
-  </summary>
-</histogram>
-
-<histogram name="SB2.Delay.MainFrame" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that SafeBrowsing actually delayed the browsing experience. It
-    records the difference between the time when Chrome would have started
-    reading the response for a URL and when the SafeBrowsing system completed
-    its check of that URL. Logged for main frame resources only.
-  </summary>
-</histogram>
-
-<histogram name="SB2.Delay.Subresource" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that SafeBrowsing actually delayed the browsing experience. It
-    records the difference between the time when Chrome would have started
-    reading the response for a URL and when the SafeBrowsing system completed
-    its check of that URL. Logged for non-main frame resources only.
-  </summary>
-</histogram>
-
-<histogram name="SB2.DownloadBinhashAddsDeleted" units="units"
-    expires_after="2014-02-20">
-  <obsolete>
-    Deleted in M-34 (February 2014).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Obsolete download BINHASH add chunks deleted.</summary>
-</histogram>
-
-<histogram name="SB2.DownloadBinhashSubsDeleted" units="units"
-    expires_after="2014-02-20">
-  <obsolete>
-    Deleted in M-34 (February 2014).
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Obsolete download BINHASH sub chunks deleted.</summary>
-</histogram>
-
-<histogram name="SB2.DownloadDatabaseKilobytes" units="KB"
-    expires_after="2015-01-05">
-  <obsolete>
-    Removed 12/2014. Moved to SB2.DatabaseSizeKilobytes.Download.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the downloads SafeBrowsing database file on disk in kilobytes,
-    after an update has occurred.
-  </summary>
-</histogram>
-
-<histogram name="SB2.DownloadDuration" units="ms" expires_after="2017-01-05">
-  <obsolete>
-    Removed 01/2017. Was measuring the lifetime of a network request
-    corresponding to a download, which may or may not correspond to the total
-    duration of a download.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The time it takes for a download to finish.</summary>
-</histogram>
-
-<histogram name="SB2.DownloadHashCheckDuration" units="ms"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time it takes for SafeBrowsing to check hash of a download file.
-  </summary>
-</histogram>
-
-<histogram name="SB2.DownloadUrlChecks" enum="SB2DownloadChecks"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 3/11/11, and replaced by SB2.DownloadChecks.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Records results of SafeBrowsing download url check.</summary>
-</histogram>
-
-<histogram name="SB2.ExtendedReportingIsEnabled" enum="BooleanEnabled"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed 03/2015. Replaced by
-    SecurityInterstitialInteraction::EXTENDED_REPORTING_IS_ENABLED.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Whether the user has Safe Browsing extended reporting enabled at the time a
-    Safe Browsing warning was dismissed. This tracks the fraction of all SB
-    interstitials that had reporting enabled.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FailedUpdate" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed, replaced by SB2.DatabaseFailure BROWSE_DB_UPDATE_FINISH.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of the number of times an update failed when being committed to
-    the database.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FilterCheck" units="ms" expires_after="2018-03-14">
-  <obsolete>
-    Removed in favor of SafeBrowsing.V4GetPrefixMatches.TimeUs
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to check a URL against our in-memory filter.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FilterKilobytes" units="KB" expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The size of the current bloom filter in kilobytes.</summary>
-</histogram>
-
-<histogram name="SB2.FilterLoad" enum="SB2FilterLoad"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Which filter file the database loaded from disk.</summary>
-</histogram>
-
-<histogram name="SB2.FilterMissing" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed, replaced by SB2.DatabaseFailure FILTER_MISSING.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of the number of times we attempted to load the bloom filter file
-    but it was missing.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FilterReadFail" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed, replaced by SB2.DatabaseFailure FILTER_READ.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of the number of times we attempted to load the bloom filter file
-    but failed while reading the file on disk.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FilterSize" units="bytes" expires_after="2013-04-25">
-  <obsolete>
-    Removed because it was exceeding the range. Replaced by SB2.FilterKilobytes.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The size of the current bloom filter.</summary>
-</histogram>
-
-<histogram name="SB2.FilterWriteFail" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed, replaced by SB2.DatabaseFailure FILTER_WRITE.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of the number of times we attempted to save the bloom filter file
-    but failed while writing the file to disk.
-  </summary>
-</histogram>
-
-<histogram name="SB2.FormatEvent" enum="SB2FormatEvent"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Collection of boolean events for SafeBrowsingFileStore instances. Includes
-    corruptions detected, old versions detected, and various failures detected.
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetChunkResponseOrErrorCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>vakh@google.com</owner>
-  <summary>
-    Response or error codes from the SafeBrowsing service. Logged after a
-    GetChunk request finishes to capture the response code or error code for
-    that call. Split out from SB2.GetHashErrorResponseOrErrorCode in M49.
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetHash200" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed in favor of SB2.GetHashResult STATUS_200.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of GetHash requests that returned data (valid requests).
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetHash204" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed in favor of SB2.GetHashResult STATUS_204.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of GetHash requests that returned empty data (false positives).
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetHashResult" enum="SB2GetHashResult"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Track return status from GetHash attempts (STATUS_200, STATUS_204,
-    NETWORK_ERROR, HTTP_ERROR, BACKOFF_ERROR), whether parsing a 200 result
-    failed (PARSE_ERROR), and dispensation of returned values (EMPTY, HIT,
-    MISS). EMPTY means the response had no full hashes, and should contain all
-    of the 204 responses plus all *_ERROR cases. HIT means that one of the full
-    hashes matched. MISS means that none of the hashes matched (there was a
-    prefix collision). (PARSE_ERROR, NETWORK_ERROR, HTTP_ERROR, and
-    BACKOFF_ERROR were added in M36.)
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetHashResultDownload" enum="SB2GetHashResult"
-    expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Track return status from GetHash attempts (STATUS_200, STATUS_204,
-    NETWORK_ERROR, HTTP_ERROR, BACKOFF_ERROR), whether parsing a 200 result
-    failed (PARSE_ERROR), and dispensation of returned values (EMPTY, HIT,
-    MISS). EMPTY means the response had no full hashes, and should contain all
-    of the 204 responses plus all *_ERROR cases. HIT means that one of the full
-    hashes matched. MISS means that none of the hashes matched (there was a
-    prefix collision). (PARSE_ERROR, NETWORK_ERROR, HTTP_ERROR, and
-    BACKOFF_ERROR were added in M36.)
-  </summary>
-</histogram>
-
-<histogram name="SB2.GetHashServerMiss" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed in favor of SB2.GetHashResult FULL_HASH_* and
-    SB2.BloomFilterFalsePositives. It is unclear if this histogram ever reported
-    useful data.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of GetHash requests returning full hashes that didn't match the
-    URL that initiated the request.
-  </summary>
-</histogram>
-
-<histogram name="SB2.HandleCorrupt" units="units" expires_after="2013-04-25">
-  <obsolete>
-    Removed, replaced by SB2.DatabaseFailure CORRUPT.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The count of the number of times a database was found corrupt and reset.
-  </summary>
-</histogram>
-
-<histogram name="SB2.InterstitialAction" enum="SB2InterstitialAction"
-    expires_after="2014-09-17">
-  <obsolete>
-    Removed, replaced by: interstitial.malware.* and interstitial.phishing.*.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Track number of times Safe Browsing interstitials have been shown, and how
-    many times they have been clicked through or not.
-  </summary>
-</histogram>
-
-<histogram name="SB2.InterstitialActionDetails"
-    enum="SB2InterstitialActionDetails" expires_after="2014-09-17">
-  <obsolete>
-    Removed, replaced by: interstitial.malware.* and interstitial.phishing.*.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Tracks the click-through rate for specific cases of the interstitial.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeClosed" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user navigating away by for example, closing the tab, clicking the browser
-    back button or typing another URL in the address bar.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeDiagnostic" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user clicking on diagnostic page link.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeExpandedSeeMore" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user expanding the &quot;see more info&quot; section of the page. (Only
-    applies to field trial version 2 of the interstitial.)
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeLearnMore" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user clicking on the learn more about malware link.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimePrivacyPolicy" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user clicking on the privacy policy link.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeProceed" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user clicking on the proceed link.
-  </summary>
-</histogram>
-
-<histogram name="SB2.MalwareInterstitialTimeTakeMeBack" units="ms"
-    expires_after="2014-09-16">
-  <obsolete>
-    Removed 9/2014.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The time between when we show the SafeBrowsing malware interstitial and the
-    user clicking on the big green back button.
-  </summary>
-</histogram>
-
-<histogram name="SB2.Network" units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time that it took to receive a response from the Google SafeBrowsing
-    servers for a GetHash request.
-  </summary>
-</histogram>
-
-<histogram name="SB2.NoUserActionResourceLoadingDelay" units="ms"
-    expires_after="2020-03-15">
-  <obsolete>
-    Removed in M77 since it is fairly flat and not really useful.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The total delay, in milliseconds, caused by SafeBrowsing for a resource
-    load, if the SafeBrowsing interstitial page is not shown and therefore no
-    user action is involved. At most one value is reported for each resource
-    load. If SafeBrowsing causes delays at different stages of a load, the sum
-    of all the delays will be reported.
-  </summary>
-</histogram>
-
-<histogram name="SB2.OldDatabaseKilobytes" units="KB"
-    expires_after="2014-07-24">
-  <obsolete>
-    Removed 7/2014. No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Size of v1 database deleted from client profile.</summary>
-</histogram>
-
-<histogram name="SB2.OutShardShifts" units="units" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates how sharded safe-browsing on-disk stores are. Values like 0 to 4
-    are reasonable.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetBitsPerPrefix" units="bits"
-    expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the PrefixSet storage in bits, divided by the number of prefixes
-    represented. Should almost always be 16.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetEvent" enum="SB2PrefixSetEvent"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012. No longer generated, BloomFilter being removed.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Records how well the PrefixSet implementation matches the BloomFilter
-    implementation.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetKilobytes" units="KB" expires_after="2015-01-07">
-  <obsolete>
-    Removed 01/2014. Replaced by suffixed SB2.PrefixSetSizeKilobytes.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The size of one of the PrefixSet files in kilobytes.</summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetLoad" units="ms" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Time to load one of the PrefixSet files.</summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetRestoredExcess" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. How many extra results GetPrefixes returns.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetRestoredShortfall" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. How many fewer results GetPrefixes returns.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetSizeKilobytes" units="KB"
-    expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of one of the PrefixSet files in kilobytes. Logged after a database
-    update has occurred and the PrefixSet has been flushed to disk (once a few
-    minutes after startup, and every thirty minutes or so thereafter).
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetUnsortedDelta" units="units"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. How far unsorted deltas are from expected value.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetUnsortedDifference" units="units"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. Distance of unsorted elements from expected
-    location.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetUnsortedPercent" units="%"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. How far into the results unsorted elements were
-    found. Interesting values would be 0%, 50%, or 100%.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetUnsortedSize" units="units"
-    expires_after="2013-04-11">
-  <obsolete>
-    Removed 9/2012. No longer generated.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    For debugging PrefixSet. Size of unsorted sets. To see if there is a problem
-    with a particular size of dataset.
-  </summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetVersionRead" units="units"
-    expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Version read from one of the PrefixSet files.</summary>
-</histogram>
-
-<histogram name="SB2.PrefixSetWrite" units="ms" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Time to store one of the PrefixSet files.</summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.CanUseLocalBlacklists"
-    enum="SB2RemoteCallCanUseLocalBlacklists" expires_after="M81">
-  <obsolete>
-    Removed in M84. This feature is not launched.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates whether the local Safe Browsing blacklists can be used on this
-    Android device. Logged once on first URL check request.
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.CheckDispatchTime" units="microseconds"
-    expires_after="2018-10-31">
-  <obsolete>
-    Removed Oct 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Wall time in microseconds for calling
-    Java_SafeBrowsingApiBridge_startUriLookup. Logged at every Safe Browsing
-    check on Android.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.ChecksPending" units="calls"
-    expires_after="2017-11-16">
-  <obsolete>
-    Removed in M64 (Nov 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Number of outstanding calls for URLs getting classified through
-    RemoteSafeBrowsingDatabaseManager. The size of the queue is logged before
-    initiating each request.
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.InternalErrorStatusCode" units="units"
-    expires_after="2018-06-19">
-  <obsolete>
-    No longer generated. Replaced by SB2.RemoteCall.InternalErrorStatusCode2
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The status code provided by GmsCore if it is unable to respond to a URL
-    check request due to incorrect initialization, not being ready, etc. Logged
-    on each URL check that hits the internal error condition. The total number
-    of these should add up to the INTERNAL_ERROR reports under
-    SB2.RemoteCall.Result.
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.LocalAllowlistLookupTime" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed M81. The latency looks good, not needed anymore.
-  </obsolete>
-  <owner>xinghuilu@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates the time for synchronous local allowlist lookup on Java side. This
-    metrics provides the evidence of whether asynchronous implementation is
-    needed for local allowlist.
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.LocalBlacklistsAgeInMs" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed in M84. This feature is not launched.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates the time since the local blacklists were successfully updated
-    last. Logged each time the verdict of local blacklists lookup is stale or
-    possibly unsafe, if the local blacklists feature is enabled (i.e.
-    SB2.RemoteCall.CanUseLocalBlacklists == ENABLED)
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.LocalBlacklistsLookupResult"
-    enum="SB2RemoteCallLocalBlacklistsLookupResult" expires_after="M81">
-  <obsolete>
-    Removed in M84. This feature is not launched.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates the result of local Safe Browsing blacklist lookup on Android.
-    Logged for each URL lookup, if the local blacklists feature is enabled (i.e.
-    SB2.RemoteCall.CanUseLocalBlacklists == ENABLED)
-  </summary>
-</histogram>
-
-<histogram name="SB2.RemoteCall.LocalBlacklistsUpdateSucceeded"
-    enum="BooleanSuccess" expires_after="M81">
-  <obsolete>
-    Removed in M84. This feature is not launched.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Indicates the result of local blacklists' update. Logged each time an update
-    of local blacklists is attempted, if the local blacklists feature is enabled
-    (i.e. SB2.RemoteCall.CanUseLocalBlacklists == ENABLED)
-  </summary>
-</histogram>
-
-<histogram name="SB2.ReportingIsEnabled" enum="BooleanEnabled"
-    expires_after="2014-06-16">
-  <obsolete>
-    Removed 06/2014. Replaced by SB2.ExtendedReportingIsEnabled.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether the user has Safe Browsing extended reporting enabled at the time a
-    Safe Browsing warning was dismissed. This tracks the fraction of all SB
-    interstitials that had reporting enabled.
-  </summary>
-</histogram>
-
-<histogram name="SB2.ResourceTypes" enum="ContentResourceType"
-    expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SB2.ResourceTypes2 in December 2015.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Resource types of resources that were inspected by Safe Browsing in the
-    SafeBrowsingResourceThrottle.
-  </summary>
-</histogram>
-
-<histogram name="SB2.SetExtendedReportingEnabled" enum="BooleanEnabled"
-    expires_after="2015-03-25">
-  <obsolete>
-    Removed 03/2015. Replaced by
-    SecurityInterstitialInteraction::SET_EXTENDED_REPORTING_ENABLED.
-  </obsolete>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Tracks changes to the Safe Browsing extended reporting opt-in which is shown
-    in the Safe Browsing interstitial.
-  </summary>
-</histogram>
-
-<histogram name="SB2.SetReportingEnabled" enum="BooleanEnabled"
-    expires_after="2014-06-16">
-  <obsolete>
-    Removed 06/2014. Replaced by SB2.SetExtendedReportingEnabled.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Tracks changes to the Safe Browsing extended reporting opt-in which is shown
-    in the Safe Browsing interstitial.
-  </summary>
-</histogram>
-
-<histogram name="SB2.SideEffectFreePrefixSetWrite" units="ms"
-    expires_after="2014-12-23">
-  <obsolete>
-    Removed 12/2014. Merged into SB2.PrefixSetWrite.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Time to store the Side Effect Free Whitelist PrefixSet file. Note: this
-    histogram was intended to be stored as
-    SB2.SideEffectFreeWhitelistPrefixSetWrite but was actually reported as
-    SB2.SideEffectFreePrefixSetWrite from its inception to its deprecation...
-  </summary>
-</histogram>
-
-<histogram name="SB2.SideEffectFreeWhitelistDatabaseKilobytes" units="KB"
-    expires_after="2014-12-23">
-  <obsolete>
-    Removed 12/2014. Moved to SB2.DatabaseSizeKilobytes.SideEffectFreeWhitelist.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the Side Effect Free Whitelist SaafeBrowsing database file on
-    disk in kilobytes, after an update has occurred.
-  </summary>
-</histogram>
-
-<histogram name="SB2.SideEffectFreeWhitelistPrefixSetKilobytes" units="KB"
-    expires_after="2014-12-23">
-  <obsolete>
-    Removed 12/2014. Moved to
-    SB2.PrefixSetSizeKilobytes.SideEffectFreeWhitelist.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of the Side Effect Free Whitelist PrefixSet file in kilobytes,
-    after an udpate has occurred.
-  </summary>
-</histogram>
-
-<histogram name="SB2.SideEffectFreeWhitelistPrefixSetLoad" units="ms"
-    expires_after="2014-12-23">
-  <obsolete>
-    Removed 12/2014. Merged into SB2.PrefixSetLoad.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Time to load the Side Effect Free Whitelist PrefixSet file.</summary>
-</histogram>
-
-<histogram name="SB2.SideEffectFreeWhitelistStatus"
-    enum="SB2SideEffectFreeWhitelistStatus" expires_after="2015-04-17">
-  <obsolete>
-    Removed 4/2015.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The instantiation status of the SideEffectFreeWhitelist.</summary>
-</histogram>
-
-<histogram name="SB2.StoreVersionRead" units="units" expires_after="2018-09-21">
-  <obsolete>
-    Removed after the launch of PVer4 in M57.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Version read from the store file.</summary>
-</histogram>
-
-<histogram name="SB2.SubPrefixes" units="units" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of sub prefixes stored in the database after the last update.
-  </summary>
-</histogram>
-
-<histogram name="SB2.Update" units="ms" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time from the receipt of the update request to the receipt of the final
-    update chunk.
-  </summary>
-</histogram>
-
-<histogram name="SB2.UpdateRequestSize" units="bytes"
-    expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The payload size of update requests to the server.</summary>
-</histogram>
-
-<histogram name="SB2.UpdateResult" enum="SB2UpdateResult"
-    expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Result from trying to update the SafeBrowsing data.</summary>
-</histogram>
-
-<histogram name="SB2.UpdateSize" units="bytes" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The size of all the chunk URLs in an update response.</summary>
-</histogram>
-
-<histogram name="SB2.UpdateSizeBackground" units="bytes"
-    expires_after="2015-10-16">
-  <obsolete>
-    Was used for an experiment in late 2014.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of all the chunk URLs in an update response when Chrome is in the
-    background.
-  </summary>
-</histogram>
-
-<histogram name="SB2.UpdateSizeForeground" units="bytes"
-    expires_after="2015-10-16">
-  <obsolete>
-    Was used for an experiment in late 2014.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The size of all the chunk URLs in an update response when Chrome is in the
-    foreground.
-  </summary>
-</histogram>
-
-<histogram name="SB2.UpdateUrls" units="units" expires_after="2018-09-10">
-  <obsolete>
-    Removed in M58 (Aug 2017). No longer generated.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The number of chunk URLs in an update response.</summary>
-</histogram>
-
-<histogram name="SB2.VolunteerPrefixesRemoved" units="units"
-    expires_after="2014-08-26">
-  <obsolete>
-    The operation this is tracking has been deleted as of 09/2014.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Older versions of the safe-browsing code incorrectly added additional
-    SBPrefix items when receiving full hashes. This caused errors when
-    calculating when to send gethash requests to the server. An additional pass
-    over the data has been added to remove the excess prefixes. This histogram
-    tracks progress of that code for purposes of informing a decision on when to
-    remove the additional pass. See http://crbug.com/361248 .
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ArchivedArchiveExtensions"
-    enum="SBClientDownloadExtensions" expires_after="M77">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Records a histogram of archive file types that were found while examining a
-    downloaded ZIP file. Each archive file type in a single ZIP file is recorded
-    at most once. The relative incidence rate of each filetype in this histogram
-    should indicate the probability of finding that file type in a ZIP file
-    given that that ZIP file contains an archive file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ArchiveDownloadExtensions"
-    enum="SBClientDownloadExtensions" expires_after="2020-08-30">
-  <obsolete>
-    This histogram was marked obsolete in 08/2020 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records a histogram of how often users download a file with a possibly
-    dangerous file extension (e.g., exe, class) within an archive.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileArchivedBinariesCount" units="count"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The original number of archived_binaries found in a DMG-like file when it's
-    scanned, if at least one is found. The actual number sent in the download
-    request may be capped below this value.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileFailureByType"
-    enum="SBClientDownloadExtensions" expires_after="M77">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Counts of DMG-like file types that failed to be successfully analyzed by the
-    SafeBrowsing download service.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileHasExecutable" enum="Boolean"
-    expires_after="2016-03-25">
-  <obsolete>
-    Replaced by SBClientDownload.DmgFileHas[No]ExecutableByType in M51.
-  </obsolete>
-  <owner>rsesek@chromium.org</owner>
-  <summary>
-    For each DMG file analyzed by the SafeBrowsing download service, records if
-    the DMG contained an executable file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileHasExecutableByType"
-    enum="SBClientDownloadExtensions" expires_after="M77">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Counts of DMG-like file types which were analyzed by the SafeBrowsing
-    download service that contained an executable file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileHasNoExecutableByType"
-    enum="SBClientDownloadExtensions" expires_after="M77">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Counts of DMG-like file types which were analyzed by the SafeBrowsing
-    download service that did NOT contain an executable file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgFileSuccess" enum="BooleanSuccess"
-    expires_after="2016-03-25">
-  <obsolete>
-    Replaced by SBClientDownload.DmgFile{Success,Failure}ByType in M51.
-  </obsolete>
-  <owner>rsesek@chromium.org</owner>
-  <summary>
-    For each DMG file analyzed by the SafeBrowsing download service, records
-    true if the analysis was successful, or false if there was an error
-    analyzing the file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DmgTooBigToUnpack" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether a given DMG download was too big to unpack, as specified by
-    configuration option set in SafeBrowsing download service. This metric is
-    logged each time the user downloads a DMG file on Mac.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DownloadFileHasDetachedSignatures"
-    enum="Boolean" expires_after="2020-03-08">
-  <obsolete>
-    Removed 09/19, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    A Mac-only metric that records whether a given download contains a detached
-    code signature file. This metric is logged before Chrome sends SafeBrowsing
-    download pings.
-  </summary>
-</histogram>
-
-<histogram
-    name="SBClientDownload.DownloadFileWithoutDiskImageExtensionHasKolySignature"
-    enum="Boolean" expires_after="M78">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether download files without an Apple disk image file extension
-    have a 'koly' signature. This can be used to identify distribution of disk
-    image files to Mac users without simply relying on file extension. This
-    metric is logged before Chrome sends SafeBrowsing download pings.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DownloadRequestTimeoutDuration" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M78, since the metrics were not being actively used and there was
-    no near-term plan to begin using them.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Records the portion of the SafeBrowsing download service check starting with
-    the point CheckClientDownloadRequest::StartTimeout() is called. It is
-    recorded regardless if a ping was sent or not. It is not recorded for
-    requests that were cancelled.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.DownloadRequestTimeoutStats"
-    enum="SBClientDownloadCheckDownloadStats" expires_after="M80">
-  <obsolete>
-    Removed in M78, since the metrics were not being actively used and there was
-    no near-term plan to begin using them.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    For SafeBrowsing binary download checks which reached the
-    CheckClientDownloadRequest::StartTimeout() call, records the final result
-    (once the check finishes or is cancelled).
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ExtractDmgFeaturesTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M76, replaced by SBClientDownload.ExtractDmgFeaturesTimeMedium.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>rsesek@chromium.org</owner>
-  <summary>
-    Records the time it takes for the SafeBrowsing download service to extract
-    info from a downloaded DMG file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ExtractImageHeadersTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77. Extracting image headers was usually fast so this histogram
-    was not providing useful data.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    Records the time it takes for the SafeBrowsing download service to extract
-    image headers from a downloaded binary.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ExtractRarFeaturesTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M76, replaced by SBClientDownload.ExtractRarFeaturesTimeMedium.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the time it takes for the SafeBrowsing download service to extract
-    info from a downloaded rar file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ExtractSignatureFeaturesTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M78, since the metrics were not being actively used and there was
-    no near-term plan to begin using them.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Records the time it takes for the SafeBrowsing download service to extract
-    signature info from a downloaded binary. This includes both unsigned and
-    signed binaries.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ExtractZipFeaturesTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in M76, replaced by SBClientDownload.ExtractZipFeaturesTimeMedium.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Records the time it takes for the SafeBrowsing download service to extract
-    info from a downloaded zip file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.PPAPIDownloadRequest.RequestDuration"
-    units="ms" expires_after="2018-08-08">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>Time taken to complete a PPAPIDownloadRequest.</summary>
-</histogram>
-
-<histogram name="SBClientDownload.PPAPIDownloadRequest.RequestOutcome"
-    enum="SBClientDownloadPPAPIDownloadRequestOutcome"
-    expires_after="2018-08-08">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>
-    Outcome of running CheckPPAPIDownloadRequest. Most failure modes cause an
-    UNKNOWN result to be returned to the caller. If the attempt succeeds, the
-    result returned to the caller is based on the SafeBrowsing resopnse. The
-    final result returned is counted in
-    SBClientDownload.PPAPIDownloadRequest.Result.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.PPAPIDownloadRequest.Result"
-    enum="SBClientDownloadCheckResult" expires_after="2018-08-08">
-  <obsolete>
-    Removed in 08/2018.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <summary>Result returned to the caller of CheckPPAPIDownloadRequest.</summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarFileArchivedBinariesCount" units="count"
-    expires_after="M85">
-  <obsolete>
-    Removed 09-2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The original number of archived_binaries found in a rar-like file when it's
-    scanned, if at least one is found. The actual number sent in the download
-    request may be capped below this value.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarFileHasArchiveButNoExecutable"
-    enum="Boolean" expires_after="M85">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each rar file analyzed by the SafeBrowsing download service, records
-    true if the rar did not contain any executables but did contain another
-    archive file, false otherwise.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarFileHasExecutable" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each rar file analyzed by the SafeBrowsing download service, records if
-    the rar contained an executable file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarFileSuccess" enum="BooleanSuccess"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each rar file analyzed by the SafeBrowsing download service, records if
-    the unpacking was 100% successful.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarHeadersEncrypted" enum="Boolean"
-    expires_after="M83">
-  <obsolete>
-    Marked obsolete 07-2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether the RAR headers are encrypted, preventing any meaningful
-    content analysis. This is in contrast to encryption of the content of the
-    archive, which still exposes file name information. This histogram is
-    recorded every time a RAR archive is downloaded.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarOpenSuccess" enum="BooleanSuccess"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each rar file analyzed by the SafeBrowsing download service, records if
-    the file could be opened. This should be close to 100% success because the
-    library doesn't actually open the file; it is handed an open file handle and
-    the Open() function call sets that as the file handle to use.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.RarValidArchive" enum="BooleanSuccess"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each rar file analyzed by the SafeBrowsing download service, records if
-    the unrar library considers this file a valid RAR archive. It includes
-    checking the following, and more: magic number is present, valid RAR version
-    format can be parsed, headers are valid, etc.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.SignedBinaryDownload"
-    enum="SBClientDownloadIsSignedBinary" expires_after="M80">
-  <obsolete>
-    Removed in M78, since the metrics were not being actively used and there was
-    no near-term plan to begin using them.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Records the number of signed vs. unsigned executables that are downloaded.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.SignedOrWhitelistedDownload" units="units"
-    expires_after="2016-03-21">
-  <obsolete>
-    Removed in Chrome 50. Replaced by SBClientDownload.CheckWhitelistResult.*.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Counter which is incremented whenever an executable is downloaded which is
-    either signed or whose URL matches the download whitelist.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.UnsupportedScheme"
-    enum="SBClientDownloadExtensions" expires_after="M80">
-  <obsolete>
-    Removed M76, since there had been no such downloads for over a year.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records how often different file extensions are downloaded with schemes that
-    aren't supported by Safe Browsing (e.g. ftp, gopher, content, cid, etc).
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipArchiveUncompressedSizeOverflow"
-    enum="Boolean" expires_after="M79">
-  <obsolete>
-    Removed in M79 due to lack of use, and no future plans for use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether the total uncompressed size of a ZIP overflowed our total.
-    This is logged once per ZIP file scanned.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipCompressionRatio" units="%"
-    expires_after="M79">
-  <obsolete>
-    Removed in M79 due to lack of use, and no future plans for use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the compression ratio for each scanned ZIP archive. This is logged
-    once per ZIP file scanned, unless
-    SBClientDownload.ZipArchiveUncompressedSizeOverflow is true.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipEntrySize" units="MB"
-    expires_after="2020-04-26">
-  <obsolete>
-    Removed in M79 due to lack of use, and no future plans for use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the uncompressed size of each entry in a scanned ZIP file. This
-    histogram is logged once per entry in the ZIP.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileArchivedBinariesCount" units="count"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The original number of archived_binaries found in a zip-like file when it's
-    scanned, if at least one is found. The actual number sent in the download
-    request may be capped below this value.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileContainsAppDirectory" enum="Boolean"
-    expires_after="2018-12-06">
-  <obsolete>
-    Removed in 12/2018 during a refactoring. The data was not being actively
-    used.
-  </obsolete>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    A Mac-only metric that records whether a downloaded zip file contains an
-    .app directory, signifying the presence of installable software.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileFailureByType"
-    enum="SBClientDownloadExtensions" expires_after="M78">
-  <obsolete>
-    Removed 09/19, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Counts of ZIP-like file types that failed to be successfully analyzed by the
-    SafeBrowsing download service.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileHasArchiveButNoExecutable"
-    enum="Boolean" expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    For each zip file analyzed by the SafeBrowsing download service, records
-    true if the zip did not contain any executables but did contain another zip
-    file, false otherwise.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileHasExecutable" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    This histogram was marked obsolete in 05/2020 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    For each zip file analyzed by the SafeBrowsing download service, records if
-    the zip contained an executable file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileLocalFileHeadersSkipped" units="count"
-    expires_after="M75">
-  <obsolete>
-    Removed 04/19. This approach to measuring platform-dependent extraction does
-    not work, so the data was not useful.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of Local File Headers (identified by their magic number) present
-    in the file, that were not extracted during ZIP inspection. A non-zero entry
-    implies some potential files were not extracted. That could be intended, or
-    it could indicate ZIPs with platform-dependent extraction. This metric is
-    sampled with small probability during each ZIP download.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipFileSuccessByType"
-    enum="SBClientDownloadExtensions" expires_after="M81">
-  <obsolete>
-    Removed 09/19, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Counts of ZIP-like file types were successfully analyzed by the SafeBrowsing
-    download service.
-  </summary>
-</histogram>
-
-<histogram name="SBClientDownload.ZipTooBigToUnpack" enum="Boolean"
-    expires_after="M78">
-  <obsolete>
-    Removed in M77, since the metric was not being actively used and there were
-    no near-term plans to begin using it.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records whether a given ZIP download was too big to unpack, as specified by
-    configuration option set in SafeBrowsing download service. This metric is
-    logged each time the user downloads a ZIP file.
-  </summary>
-</histogram>
-
-<histogram name="SBClientMalware.ClassificationStart" enum="BooleanHit"
-    expires_after="2020-09-04">
-  <obsolete>
-    Removed in 07-2020 since the SBClientMalware feature was removed.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The number of pages that we could have possibly classified (essentially the
-    number of top page navigations by users with SBClientMalware enabled). The
-    name is slightly misleading as it is recorded before
-    &quot;Preclassification&quot; happens.
-  </summary>
-</histogram>
-
-<histogram name="SBClientMalware.PreClassificationCheckFail"
-    enum="SBClientDetectionPreClassificationCheckFail"
-    expires_after="2020-09-04">
-  <obsolete>
-    Removed in 07-2020 since the SBClientMalware feature was removed.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the number of malware classifications that were skipped because a
-    pre-classification check failed.
-  </summary>
-</histogram>
-
-<histogram name="SBClientMalware.ResourceUrlMatchedBadIp"
-    enum="BooleanMatchedBadIp" expires_after="2020-09-04">
-  <obsolete>
-    Removed in 07-2020 since the SBClientMalware feature was removed.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    True if at least one resource url matched the malware IP list. Recorded when
-    client side malware feature extraction is done.
-  </summary>
-</histogram>
-
-<histogram name="SBClientMalware.UnexpectedPageId" enum="BooleanHit"
-    expires_after="2014-03-31">
-  <obsolete>
-    Removed 03/2014. That part of the code got deleted.
-  </obsolete>
-  <owner>noelutz@chromium.org</owner>
-  <summary>
-    Counts the number of times the page ID that completed the page load does not
-    match the browse info page ID. We expect that number to be zero.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.CheckNoPendingClassificationFailed"
-    units="units" expires_after="2015-09-15">
-  <obsolete>
-    Removed in M47.
-  </obsolete>
-  <owner>noelutz@chromium.org</owner>
-  <summary>
-    The number of times client-side phishing classifier expected to have no
-    pending classifications running but that check failed.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.ClientDeterminesPhishing"
-    enum="BooleanIsPhishing" expires_after="M80">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The counts for phishing verdicts given by client side model.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.GrabPhishingThumbnail" units="ms"
-    expires_after="2015-09-15">
-  <obsolete>
-    Removed in M47
-  </obsolete>
-  <owner>noelutz@chromium.org</owner>
-  <summary>Time spent generating the thumbnail.</summary>
-</histogram>
-
-<histogram name="SBClientPhishing.InitPrivateNetworksFailed" units="units"
-    expires_after="2014-05-30">
-  <obsolete>
-    Removed in Chrome 37, which now uses //net's internal matching.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    The number of times that the phishing detection service could not be
-    initialized due to an error parsing the private IP networks. This would
-    indicate a bug.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.InvalidWhitelistExpression" units="units"
-    expires_after="2013-04-25">
-  <obsolete>
-    Removed 12/2011. Whitelist entries are no longer part of
-    ClientPhishingResponse.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of whitelist_expression entries in a ClientPhishingResponse that
-    could not be canonicalized.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.PreClassificationCheckFail"
-    enum="SBClientDetectionPreClassificationCheckFail"
-    expires_after="2021-01-10">
-  <obsolete>
-    This was replaced by SBClientPhishing.PreClassificationCheckResult in
-    08-2020, since that histogram is easier to reason about.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Records the number of phishing classifications that were skipped because a
-    pre-classification check failed.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.ServerDeterminesPhishing"
-    enum="BooleanIsPhishing" expires_after="M77">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The counts for phishing verdicts given by server side model.
-  </summary>
-</histogram>
-
-<histogram name="SBClientPhishing.SkipClassificationReason"
-    enum="SBClientPhishingSkipClassificationReason" expires_after="2020-02-16">
-  <obsolete>
-    Removed in M77 due to lack of use.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The counts for various reasons why a phishing classification is skipped.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.Activations" enum="DownloadItem.DangerType"
-    expires_after="M78">
-  <obsolete>
-    Removed in M77, since the information was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Count of times download feedback has been started, broken down by danger
-    type.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.ActiveFeedbacks" units="units"
-    expires_after="M83">
-  <obsolete>
-    Marked obsolete 07-2020 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    When a new download feedback request is added, records the number of
-    download requests currently active and/or pending.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.Eligible" enum="DownloadItem.DangerType"
-    expires_after="M81">
-  <obsolete>
-    Removed in M85, since the histogram is not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Count of times eligible download notifications are shown. Broken down by
-    danger type.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.EmptyFilePathFailure" enum="Boolean"
-    expires_after="M78">
-  <obsolete>
-    Removed in M77, since the information was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Count of times download feedback cannot be sent due to empty file path.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.FileErrors"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2020-09-27">
-  <obsolete>
-    Removed in M86, since the information was not being used.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The net error or response code that caused the TwoPhaseUploader to fail
-    while uploading the file. This is logged whenever the TwoPhaseUploader fails
-    while uploading the file.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.MetadataErrors"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M82">
-  <obsolete>
-    Removed in M86, since the information was not being used.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The net error or response code that caused the TwoPhaseUploader to fail
-    while uploading metadata. This is logged whenever the TwoPhaseUploader fails
-    while uploading metadata.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.Shown" enum="DownloadItem.DangerType"
-    expires_after="2013-11-02">
-  <obsolete>
-    Starting with M32, replaced by SBDownloadFeedback.Eligible.
-  </obsolete>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Count of times download feedback button has been shown, broken down by
-    danger type.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.SizeEligibleKB" units="KB"
-    expires_after="2020-02-16">
-  <obsolete>
-    Removed in M77, since the information was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Size of downloads that were of the correct danger type, regardless if they
-    meet the max file size check or if they are actually uploaded or not.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.SizeFailure" units="bytes"
-    expires_after="M83">
-  <obsolete>
-    Marked obsolete 07-2020 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Size of downloads that failed to be uploaded to the feedback service.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.SizeSuccess" units="bytes"
-    expires_after="M83">
-  <obsolete>
-    Marked obsolete 07-2020 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Size of downloads that were successfully uploaded to the feedback service.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.UploadRequestedByServer"
-    enum="DownloadUploadRequestedByServer" expires_after="M78">
-  <obsolete>
-    Removed in M77, since the information was not being used.
-  </obsolete>
-  <owner>vakh@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    For each non-SAFE file, records whether the server requested that that file
-    be uploaded.
-
-    Logged before checking the file size, so it may be dropped there.
-  </summary>
-</histogram>
-
-<histogram name="SBDownloadFeedback.UploadResult"
-    enum="SBDownloadFeedbackUploadResult" expires_after="M83">
-  <obsolete>
-    Marked obsolete 07-2020 due to lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <owner>mattm@chromium.org</owner>
-  <summary>
-    Final result of attempt to upload binary to download feedback service.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.BLAHashTime" units="ms" expires_after="2017-09-27">
-  <obsolete>
-    Blacklist Load analysis was removed in M63.
-  </obsolete>
-  <owner>caitkp@google.com</owner>
-  <summary>
-    The elapsed time to compute the hash of a blacklisted module.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.BLASignatureTime" units="ms" expires_after="2017-09-27">
-  <obsolete>
-    Blacklist Load analysis was removed in M63.
-  </obsolete>
-  <owner>caitkp@google.com</owner>
-  <summary>
-    The elapsed time to validate the signature of a blacklisted module.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.IncidentCount" units="units" expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>caitkp@google.com</owner>
-  <summary>
-    The number of incidents collated into a single safe browsing incident
-    report.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.PruneRatio" units="%" expires_after="2015-08-26">
-  <obsolete>
-    Removed 08/2015.
-  </obsolete>
-  <owner>caitkp@google.com</owner>
-  <summary>
-    The percentage of incidents pruned from a safe browsing incident report on
-    account of having been previously reported.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.PSSDataStoreSize" units="bytes" expires_after="M81">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>grt@google.com</owner>
-  <summary>
-    The size, in bytes, of a profile's platform state store. This histogram is
-    logged on each write, which always replaces any previous contents.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.PSSLoadResult" enum="PlatformStateStoreLoadResult"
-    expires_after="2020-07-06">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>grt@google.com</owner>
-  <summary>The result of loading data from the platform state store.</summary>
-</histogram>
-
-<histogram name="SBIRS.ReportUploadTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>caitkp@google.com</owner>
-  <summary>The elapsed time to upload a safe browsing incident report.</summary>
-</histogram>
-
-<histogram name="SBIRS.StateStoreInit" enum="StateStoreInitResult"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>proberge@google.com</owner>
-  <summary>
-    The result of initializing the state store and comparing the preferences to
-    the platform-specific state store.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.SuspiciousModuleDetectionTime" units="ms"
-    expires_after="2017-09-20">
-  <obsolete>
-    Suspicious Module detection was removed in M63.
-  </obsolete>
-  <owner>proberge@google.com</owner>
-  <summary>
-    The elapsed time to check loaded modules against the module whitelist.
-  </summary>
-</histogram>
-
-<histogram name="SBIRS.SuspiciousModuleReportCount" units="modules"
-    expires_after="2017-09-20">
-  <obsolete>
-    Suspicious Module detection reporting removed in M63.
-  </obsolete>
-  <owner>proberge@google.com</owner>
-  <summary>The number of suspicious modules found.</summary>
-</histogram>
-
-<histogram name="SBIRS.SuspiciousModuleReportingTime" units="ms"
-    expires_after="2017-09-20">
-  <obsolete>
-    Suspicious Module detection reporting removed in M63.
-  </obsolete>
-  <owner>proberge@google.com</owner>
-  <summary>
-    The elapsed time to create incidents for suspicious modules.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.Abort" enum="ContentResourceType"
-    expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SBOffDomainInclusion2.Abort in December 2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis was aborted. This histogram is suffixed with the abort
-    reason.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.Detected" enum="ContentResourceType"
-    expires_after="2015-01-10">
-  <obsolete>
-    Removed 01/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which an off-domain
-    inclusion was detected by the OffDomainInclusionDetector.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.EmptyMainFrameURL"
-    enum="ContentResourceType" expires_after="2015-01-29">
-  <obsolete>
-    Removed 01/2015. Moved to SBOffDomainInclusion.Abort.EmptyMainFrameURL.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the main frame URL
-    was unexpectedly empty in the OffDomainInclusionDetector.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.InHistory" enum="ContentResourceType"
-    expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SBOffDomainInclusion2.InHistory in December 2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis concluded in no inclusion whitelist hit but a browsing
-    history hit.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.InvalidMainFrameURL"
-    enum="ContentResourceType" expires_after="2015-01-29">
-  <obsolete>
-    Removed 01/2015 (was never reported, confirming experiment that handling it
-    is irrelevant).
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the main frame URL
-    was unexpectedly invalid (and not empty) in the OffDomainInclusionDetector.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.RequestAnalyzed"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SBOffDomainInclusion2.RequestAnalyzed in December 2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request analyzed by the
-    OffDomainInclusionDetector.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.Suspicious" enum="ContentResourceType"
-    expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SBOffDomainInclusion2.Suspicious in December 2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which an off-domain
-    inclusion was detected by the OffDomainInclusionDetector and considered
-    suspicious.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion.Whitelisted" enum="ContentResourceType"
-    expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SBOffDomainInclusion2.Suspicious in December 2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis concluded in an inclusion whitelist hit.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion2.Abort" enum="ContentResourceType2"
-    expires_after="2016-05-16">
-  <obsolete>
-    Removed 2016-05 as the OffDomainInclusionDetector was removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis was aborted. This histogram is suffixed with the abort
-    reason.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion2.InHistory" enum="ContentResourceType2"
-    expires_after="2016-05-16">
-  <obsolete>
-    Removed 2016-05 as the OffDomainInclusionDetector was removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis concluded in no inclusion whitelist hit but a browsing
-    history hit.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion2.RequestAnalyzed"
-    enum="ContentResourceType2" expires_after="2016-05-16">
-  <obsolete>
-    Removed 2016-05 as the OffDomainInclusionDetector was removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request analyzed by the
-    OffDomainInclusionDetector.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion2.Suspicious" enum="ContentResourceType2"
-    expires_after="2016-05-16">
-  <obsolete>
-    Removed 2016-05 as the OffDomainInclusionDetector was removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which an off-domain
-    inclusion was detected by the OffDomainInclusionDetector and considered
-    suspicious.
-  </summary>
-</histogram>
-
-<histogram name="SBOffDomainInclusion2.Whitelisted" enum="ContentResourceType2"
-    expires_after="2016-05-16">
-  <obsolete>
-    Removed 2016-05 as the OffDomainInclusionDetector was removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the resource type of each resource request for which the off-domain
-    inclusion analysis concluded in an inclusion whitelist hit.
-  </summary>
-</histogram>
-
-<histogram name="Scheduler.CancelableTaskTracker.TaskCanceled"
-    enum="BooleanCanceled" expires_after="2020-05-01">
-  <obsolete>
-    2020-02-25: Replaced by Scheduler.CancelableTaskTracker.TaskState, which
-    allows correlation of live/canceled with same/off-sequence states.
-  </obsolete>
-  <owner>wez@chromium.org</owner>
-  <owner>scheduler-dev@chromium.org</owner>
-  <summary>
-    True if a task posted to CancelableTaskTracker was canceled before it got
-    the chance to run. Recorded for every task posted via CancelableTaskTracker,
-    immediately before it would be run.
-  </summary>
-</histogram>
-
-<histogram name="Scheduler.CancelableTaskTracker.TaskDuration" units="ms"
-    expires_after="2020-05-01">
-  <obsolete>
-    2020-02-25: Replaced by Scheduler.CancelableTaskTracker.TaskDuration2_*
-    which correllate duration with liveness, off-sequence and task priority
-    states.
-  </obsolete>
-  <owner>wez@chromium.org</owner>
-  <owner>scheduler-dev@chromium.org</owner>
-  <summary>
-    Time taken for a task posted to a CancelableTaskTracker to run. Durations
-    are not recorded for canceled tasks.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.ActivateDuration" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by ActivateDuration2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the compositor to simply activate the pending tree.
-    Does not include any PrepareTiles or raster time.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameIntervalCritical"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameIntervalCritical2, due to inefficient bucketing
-    scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameIntervalNotCritical"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameIntervalNotCritical2, due to inefficient bucketing
-    scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is not set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameQueueDurationCritical"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameQueueDurationCritical2, due to inefficient
-    bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the main side to start the BeginMainFrame in response
-    to the compositor's SendBeginMainFrame when the on_critical_path flag is
-    set.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameQueueDurationCritical2"
-    units="microseconds" expires_after="2020-02-05">
-  <obsolete>
-    Replaced by SendBeginMainFrameToCommit.BeginMainSentToStarted of
-    CompositorLatency metrics as of 02/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    How long it takes for the main side to start the BeginMainFrame in response
-    to the compositor's SendBeginMainFrame when the on_critical_path flag is
-    set.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameQueueDurationNotCritical"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameQueueDurationNotCritical2, due to inefficient
-    bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the main side to start the BeginMainFrame in response
-    to the compositor's SendBeginMainFrame when the on_critical_path flag is not
-    set.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameStartToCommitDuration"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameStartToCommitDuration2, due to inefficient
-    bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time from when the main side actually starts the BeginMainFrame to when
-    the commit completes on the impl side.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameStartToCommitDuration2"
-    units="microseconds" expires_after="M85">
-  <obsolete>
-    Replaced by SendBeginMainFrameToCommit of CompositorLatency metrics as of
-    02/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    The time from when the main side actually starts the BeginMainFrame to when
-    the commit completes on the impl side.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.BeginMainFrameToCommitDuration"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by BeginMainFrameQueueDurationCritical,
-    BeginMainFrameQueueDurationNotCritical, and
-    BeginMainFrameStartToCommitDuration.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the blink main thread to respond to the compositor's
-    SendBeginMainFrame.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.ActivateDuration2" units="microseconds"
-    expires_after="2018-08-28">
-  <obsolete>
-    Removed in 08/2018, M69. Since there is no impl thread on Browser side,
-    there is no activation state for Browser.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the compositor to simply activate the pending tree.
-    Does not include any PrepareTiles or raster time.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.BeginMainFrameIntervalCritical2"
-    units="microseconds" expires_after="2018-07-04">
-  <obsolete>
-    Removed in 06/2018, M69, due to too much noise in the collected data.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_HIGH_RESOLUTION_TIMES for
-    the solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.BeginMainFrameIntervalNotCritical2"
-    units="microseconds" expires_after="2018-07-11">
-  <obsolete>
-    Removed in 07/2018, M69. All begin frames are in critical path for browser,
-    no data is reported.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is not set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.BeginMainFrameQueueDurationNotCritical2"
-    units="microseconds" expires_after="2018-07-11">
-  <obsolete>
-    Removed in 07/2018, M69. All begin frames are in critical path for browser,
-    no data is reported.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the main side to start the BeginMainFrame in response
-    to the compositor's SendBeginMainFrame when the on_critical_path flag is not
-    set.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.BeginMainFrameStartToCommit"
-    units="microseconds" expires_after="2016-06-29">
-  <obsolete>
-    Replaced by BeginMainFrameStartToCommitDuration. This was recorded as a
-    result of a typo in the code that didn't include &quot;Duration&quot;.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time from when the main side actually starts the BeginMainFrame to when
-    the commit completes on the impl side.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.BeginMainFrameStartToCommit2"
-    units="microseconds" expires_after="2016-06-29">
-  <obsolete>
-    Replaced by BeginMainFrameStartToCommitDuration2. This was recorded as a
-    result of a typo in the code that didn't include &quot;Duration&quot;.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time from when the main side actually starts the BeginMainFrame to when
-    the commit completes on the impl side.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.CommitInterval2" units="microseconds"
-    expires_after="2018-07-04">
-  <obsolete>
-    Removed in 06/2018, M69, due to too much noise in the collected data.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time delta between the *draw* times of back-to-back BeginMainFrames that
-    result in a commit.
-
-    The interval is only recorded when the BeginMainFrames are running and
-    committing continuously, where continuously means when another
-    BeginMainFrame is requested by the next BeginImplFrame after activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_HIGH_RESOLUTION_TIMES for
-    the solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.DrawInterval2" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Removed in 06/2018, M69, due to too much noise in the collected data.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames,
-    regardless of whether or not they result in a swap.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_HIGH_RESOLUTION_TIMES for
-    the solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.DrawIntervalWithCompositedAnimations2"
-    units="microseconds" expires_after="2018-07-13">
-  <obsolete>
-    Removed in 07/2018, M69, due to too much noise in the data.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames,
-    regardless of whether or not they result in a swap, when there is at least
-    one composited animation.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.DrawIntervalWithMainThreadAnimations2"
-    units="microseconds" expires_after="2018-07-13">
-  <obsolete>
-    Removed in 07/2018, M69, due to too much noise in the data.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames of new
-    active trees only, regardless of whether or not they result in a swap, when
-    there is at least one main thread animation.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.MainAndImplFrameTimeDelta2"
-    units="microseconds" expires_after="2018-08-28">
-  <obsolete>
-    Removed in 08/2018, M69, since there is no impl thread in Browser side, this
-    metric does not record any meaningful data.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    Recorded every time the compositor draws with a new active tree. A value of
-    0 indicates the main-side started and finished within the same frame
-    interval as the impl-side. Positive values correspond to how old any
-    main-side updates are compared to the impl-side updates. If there are no
-    mid-frame updates, this metric is a good proxy for how well the main and
-    impl threads are synchronized.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.PendingTreeDuration" units="microseconds"
-    expires_after="2018-07-13">
-  <obsolete>
-    Removed in 07/2018, M69. Since there is no pending tree in Browser, no data
-    is ever reported.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Time between creating a pending tree and activating that tree. This differs
-    from Scheduling.ActivateDuration in that it includes time taken to raster
-    the pending tree, not just the time to activate it.
-
-    The interval is recorded each time a pending tree is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.PendingTreeRasterDuration"
-    units="microseconds" expires_after="2018-07-13">
-  <obsolete>
-    Removed in 07/2018, M69. Since there is no pending tree in Browser, no data
-    is ever reported.
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    Time between starting raster work on the pending tree and when it is ready
-    to activate. Unlike PendingTreeDuration which - includes the time to commit
-    to this tree, the raster duration and the time for which the pending tree
-    waits before it can be activated - this only measures the time taken to
-    rasterize tiles required for activation.
-
-    The interval is recorded each time we are notifed that a pending tree is
-    ready for activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.ReadyToActivateToActivationDuration2.Impl"
-    units="microseconds" expires_after="2018-07-13">
-  <obsolete>
-    Removed in 07/2018, M69. No data reported because there is no pending tree
-    on impl thread for browser side.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long does the pending tree wait after it is ready to be activated and
-    before it is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution. Impl side invalidation initiated pending tree
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Browser.ReadyToActivateToActivationDuration2.Main"
-    units="microseconds" expires_after="M85">
-  <obsolete>
-    Replaced by EndCommitToActivation of CompositorLatency metrics as of
-    08/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    How long does the pending tree wait after it is ready to be activated and
-    before it is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution. Commit initiated pending tree.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.CommitInterval" units="microseconds"
-    expires_after="2018-07-04">
-  <obsolete>
-    Replaced by CommitInterval2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time delta between the *draw* times of back-to-back BeginMainFrames that
-    result in a commit.
-
-    The interval is only recorded when the BeginMainFrames are running and
-    committing continuously, where continuously means when another
-    BeginMainFrame is requested by the next BeginImplFrame after activation.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.CommitToReadyToActivateDuration"
-    units="microseconds" expires_after="2016-06-23">
-  <obsolete>
-    Replaced by CommitToReadyToActivateDuration2, due to inefficient bucketing
-    scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes for the compositor to rasterize pending tree content after
-    a commit before it is ready for activation.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.DrawDuration" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by DrawDuration2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>How long it takes the compositor to draw a frame.</summary>
-</histogram>
-
-<histogram name="Scheduling.DrawInterval" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by DrawInterval2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames,
-    regardless of whether or not they result in a swap.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.DrawIntervalWithMainThreadCompositableAnimations2"
-    units="microseconds" expires_after="2018-05-02">
-  <obsolete>
-    Removed 05/2018 because the experiment described in Issue 754471 is
-    completed.
-  </obsolete>
-  <owner>paint-dev@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames of new
-    active trees only, regardless of whether or not they result in a swap, when
-    there is at least one main thread animation that could be composited but
-    not, due to running experiment.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.ImageInvalidationUpdateDuration"
-    units="microseconds" expires_after="2018-04-10">
-  <obsolete>
-    Removed 03/28/2018
-  </obsolete>
-  <owner>khushalsagar@chromium.org</owner>
-  <summary>
-    Duration for updating animated images and invalidating layers for images
-    invalidated on the sync tree in the compositor. This interval is recorded
-    each time the sync tree is updated after a commit or an impl-side
-    invalidation.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.MainAndImplFrameTimeDelta" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by MainAndImplFrameTimeDelta2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    Recorded every time the compositor draws with a new active tree. A value of
-    0 indicates the main-side started and finished within the same frame
-    interval as the impl-side. Positive values correspond to how old any
-    main-side updates are compared to the impl-side updates. If there are no
-    mid-frame updates, this metric is a good proxy for how well the main and
-    impl threads are synchronized.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.PrepareTilesDuration" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by PrepareTIlesDuration2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long it takes the compositor to PreapreTiles, which determines what
-    rasterization work to do.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.ReadyToActivateToActivationDuration"
-    units="microseconds" expires_after="2018-07-13">
-  <obsolete>
-    Replaced by ReadyToActivateToActivationDuration2, due to inefficient
-    bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    How long does the pending tree wait after it is ready to be activated and
-    before it is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.ActivateDuration2" units="microseconds"
-    expires_after="2020-02-16">
-  <obsolete>
-    Replaced by Activation stage of CompositorLatency metrics as of 08/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    How long it takes for the compositor to simply activate the pending tree.
-    Does not include any PrepareTiles or raster time.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.BeginMainFrameIntervalCritical2"
-    units="microseconds" expires_after="2020-02-16">
-  <obsolete>
-    This is no longer usefull and would not be replaced, as of 08/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_HIGH_RESOLUTION_TIMES for
-    the solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.BeginMainFrameIntervalNotCritical2"
-    units="microseconds" expires_after="2020-02-16">
-  <obsolete>
-    This is no longer usefull and would not be replaced. as of 02/2020
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    This is the time delta between back-to-back BeginMainFrames completions on
-    the compositor side when the on_critical_path flag is not set, regardless of
-    whether they abort (have no updates) or commit (have updates).
-
-    The interval is only recorded when the BeginMainFrames are running
-    continuously; sepcifically when another BeginMainFrame is requested by the
-    next BeginImplFrame after a) an abort or b) activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.CommitInterval2" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    This is no longer usefull and would not be replaced. as of 02/2020
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    The time delta between the *draw* times of back-to-back BeginMainFrames that
-    result in a commit.
-
-    The interval is only recorded when the BeginMainFrames are running and
-    committing continuously, where continuously means when another
-    BeginMainFrame is requested by the next BeginImplFrame after activation.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_HIGH_RESOLUTION_TIMES for
-    the solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.DrawIntervalWithCompositedAnimations2"
-    units="microseconds" expires_after="2021-04-19">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <owner>flackr@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames,
-    regardless of whether or not they result in a swap, when there is at least
-    one composited animation.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2"
-    units="microseconds" expires_after="2021-04-19">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <owner>flackr@chromium.org</owner>
-  <summary>
-    The time delta between the draw times of back-to-back BeginImplFrames of new
-    active trees only, regardless of whether or not they result in a swap, when
-    there is at least one main thread animation.
-
-    The interval is only recorded when every BeginImplFrame wants to draw.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.MainAndImplFrameTimeDelta2"
-    units="microseconds" expires_after="M81">
-  <obsolete>
-    This is no longer usefull and would not be replaced. as of 02/2020
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    Recorded every time the compositor draws with a new active tree. A value of
-    0 indicates the main-side started and finished within the same frame
-    interval as the impl-side. Positive values correspond to how old any
-    main-side updates are compared to the impl-side updates. If there are no
-    mid-frame updates, this metric is a good proxy for how well the main and
-    impl threads are synchronized.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.PendingTreeDuration" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    This duration is reported in EndCommitToActivation and Activation of
-    CompositorLatency metrics, and is removeded as of 03/2020.
-  </obsolete>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    Time between creating a pending tree and activating that tree. This differs
-    from Scheduling.ActivateDuration in that it includes time taken to raster
-    the pending tree, not just the time to activate it.
-
-    The interval is recorded each time a pending tree is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.Renderer.ReadyToActivateToActivationDuration2"
-    units="microseconds" expires_after="M81">
-  <obsolete>
-    Replaced by EndCommitToActivation of CompositorLatency metrics as of
-    08/2020.
-  </obsolete>
-  <owner>vmiura@chromium.org</owner>
-  <owner>sadrul@chromium.org</owner>
-  <summary>
-    How long does the pending tree wait after it is ready to be activated and
-    before it is activated.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.SwapAckWasFast" enum="BooleanWasFast"
-    expires_after="2018-07-15">
-  <obsolete>
-    Removed in 07/2018, M69. The swap ack is always received within 8 seconds.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>
-    True if the swap ack was received within approximately 8 seconds of the
-    swap. Although 8 seconds isn't exactly fast, it is a threshold that
-    represents a hang or the appearance of a hang.
-  </summary>
-</histogram>
-
-<histogram name="Scheduling.SwapToAckLatency" units="microseconds"
-    expires_after="2016-06-23">
-  <obsolete>
-    Replaced by SwapToAckLatency2, due to inefficient bucketing scheme.
-  </obsolete>
-  <owner>brianderson@chromium.org</owner>
-  <summary>How long it takes the swap ack to return after a swap.</summary>
-</histogram>
-
-<histogram name="Sdch3.AdvertisedWithSecureScheme" enum="BooleanHttps"
-    expires_after="2015-08-27">
-  <obsolete>
-    Experiment complete, histogram gathering code removed.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    Whether an SDCH dictionary was advertised over a secure scheme or not. This
-    histogram is logged inside SdchManager at advertisement time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Advertisement_Count" units="units"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The number of dictionaries advertised in an HTTP GET transaction that
-    supports SDCH. Note that only non-zero advertisements are logged.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.BlacklistReason" enum="SdchProblemCode"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The reason why a blacklist blocking a request from advertising SDCH was
-    implemented. There is one entry in this histogram per inhibited request.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Dictionary size loaded" units="bytes"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Each sample is the byte count for a dictionary that is loaded by Chrome. A
-    dictionary is loaded shortly after the first Google query performed in each
-    session, and allows future SDCH transactions to be encoded/decoded using
-    that dictionary.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.DictionaryFate" enum="SdchDictionaryFate"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The fate, both on input and output, of dictionary requests. There is
-    intended to be two entries in this histogram for each Get-Dictionary seen
-    (except failed requests are not currently tracked).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.DictionaryUseCount" units="units"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The number of times a dictionary has been successfully used for decoding,
-    recorded at the time it is evicted from the manager.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment2_Decode" units="units"
-    expires_after="2014-07-30">
-  <obsolete>
-    Replaced by Sdch3.Experiment3_Holdback.
-  </obsolete>
-  <summary>
-    Duration in time from when a request was made, until all bytes were
-    received. During the running of an SDCH latency experiment, these packets
-    were part of an SDCH encoded transmission made after the link had proven it
-    was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment2_Holdback" units="units"
-    expires_after="2014-07-30">
-  <obsolete>
-    Replaced by Sdch3.Experiment3_Holdback.
-  </obsolete>
-  <summary>
-    Duration in time from when a request was made, until all bytes were
-    received. During the running of an SDCH latency experiment, these packets
-    were part of a holdback, which precluded SDCH despite the fact that the link
-    had proven it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment3_Decode" units="units"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Duration in time from the first byte of a request was received, until all
-    bytes were received. During the running of an SDCH latency experiment, these
-    packets were part of an SDCH encoded transmission made after the link had
-    proven it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment3_Holdback" units="units"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Duration in time from the first byte of a request was received, until all
-    bytes were received. During the running of an SDCH latency experiment, these
-    packets were part of a holdback, which precluded SDCH despite the fact that
-    the link had proven it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Decode" units="units"
-    expires_after="2014-06-25">
-  <obsolete>
-    Replaced by Sdch3.Experiment2_Decode.
-  </obsolete>
-  <summary>
-    Duration in time from when a request was made, until all bytes were
-    received. During the running of an SDCH latency experiment, these packets
-    were part of an SDCH encoded transmission made after the link had proven it
-    was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback" units="units"
-    expires_after="2014-06-25">
-  <obsolete>
-    Replaced by Sdch3.Experiment2_Holdback.
-  </obsolete>
-  <summary>
-    Duration in time from when a request was made, until all bytes were
-    received. During the running of an SDCH latency experiment, these packets
-    were part of a holdback, which precluded SDCH despite the fact that the link
-    had proven it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback_1st_To_2nd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 1st **NON**-SDCH encoded packet to receipt of the 2nd packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-    During the running of an SDCH latency experiment, these packets were part of
-    a holdback, which precluded SDCH despite the fact that the link had proven
-    it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback_1st_To_Last_a" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The duration between receipt of the 1st holdback (non-SDCH encoded) packet
-    and receipt of the last packet. Only groups that are part of the holdback
-    (i.e., could have been sdch encoded) are sampled.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback_2nd_To_3rd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 2nd **NON**-SDCH encoded packet to receipt of the 3rd packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-    During the running of an SDCH latency experiment, these packets were part of
-    a holdback, which precluded SDCH despite the fact that the link had proven
-    it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback_3rd_To_4th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 3rd **NON**-SDCH encoded packet to receipt of the 4th packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-    During the running of an SDCH latency experiment, these packets were part of
-    a holdback, which precluded SDCH despite the fact that the link had proven
-    it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Experiment_Holdback_4th_To_5th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 4th **NON**-SDCH encoded packet to receipt of the 5th packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-    During the running of an SDCH latency experiment, these packets were part of
-    a holdback, which precluded SDCH despite the fact that the link had proven
-    it was capable of handling SDCH compression.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.FilterUseBeforeDisabling" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If SDCH decoding was disabled client side, this records how many URLs were
-    processed by the SDCH filter before disabling this feature. The most common
-    number is 1, which happens when there is one home-page tab that contains
-    SDCH encoded data, for which there is no dictionary loaded into the Chrome
-    process (yet), since Chrome was just restarted. Large values in this
-    histogram are indicative of flaky decompression, that works for a while, and
-    then is disabled. Values of 2 or 3 may appear if a user has more than one
-    home page with a query, and restarts there browser.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.FirstUseInterval" units="ms" expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The amount of time between creation/load of an SDCH dictionary and its first
-    use.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_1st_To_2nd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 1st SDCH encoded packet and receipt of the 2nd packet, for
-    processing by the SDCH filter. Packet count boundaries are calculated each
-    time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_1st_To_Last_a" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The duration between receipt of the 1st SDCH encoded packet and receipt of
-    the last packet, for processing by the SDCH filter.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_2nd_To_3rd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 2nd SDCH encoded packet and receipt of the 3rd packet, for
-    processing by the SDCH filter. Packet count boundaries are calculated each
-    time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_3rd_To_4th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 3rd SDCH encoded packet and receipt of the 4th packet, for
-    processing by the SDCH filter. Packet count boundaries are calculated each
-    time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_4th_To_5th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 4th SDCH encoded packet and receipt of the 5th packet, for
-    processing by the SDCH filter. Packet count boundaries are calculated each
-    time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Bytes_Processed_a" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    (discontinued 7/29/2009, and replaced by
-    Sdch3.Network_Decode_Bytes_Processed_b) The number of bytes processed
-    (received over the net or from cache) by the SDCH filter chain.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Bytes_Processed_b" units="bytes"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The number of bytes processed (received over the net or from cache) by the
-    SDCH filter chain.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Bytes_VcdiffOut_a" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The number of bytes emitted after decoding by the SDCH filter.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Latency_F_a" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The duration between putting the first byte of a request (such as a GET) on
-    the wire, until the last by of compressed SDCH encoded content is received
-    (with durations over 10 minutes discarded). During a planned latency
-    experiment, some clients will receive encoded SDCH data, and other will
-    received mere gzip'ed data (that passes through the SDCH filter unchanged).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Packets_b" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    An approximation to the total number of SDCH encoded packets received for
-    processing by the SDCH filter. Packet count boundaries are calculated each
-    time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Decode_Ratio_a" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The ratio of the number of bytes read from the network (or cache) and fed to
-    the filter chain (usually the gunzip filter) vs. the number of bytes emitted
-    by the SDCH filter to be rendered. This is commonly described as the SDCH
-    compression ratio.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_1st_To_2nd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 1st **NON**-SDCH encoded packet to receipt of the 2nd packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_1st_To_Last_a" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The duration between receipt of the 1st **NON**-SDCH encoded packet to
-    receipt of the last packet, for processing by the SDCH filter.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_2nd_To_3rd_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 2nd **NON**-SDCH encoded packet to receipt of the 3rd packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_3rd_To_4th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 3rd **NON**-SDCH encoded packet to receipt of the 4th packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_4th_To_5th_c" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    Sampling only transmissions with 5 or more packets, the duration between
-    receipt of the 4th **NON**-SDCH encoded packet to receipt of the 5th packet,
-    for processing by the SDCH filter. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_Latency_F_a" units="ms"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The duration between putting the first byte of a request (such as a GET) on
-    the wire, until the last by gzip compressed content is received and
-    passed-through unchanged by the SDCH filter (with durations over 10 minutes
-    discarded). During a planned latency experiment, some clients will receive
-    encoded SDCH data, and other will received mere gzip'ed data (that passes
-    through the SDCH filter unchanged).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.Network_Pass-through_Packets_b" units="units"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    The total number of **NON**-SDCH encoded packets received for processing by
-    the SDCH filter in one URL fetch. Packet count boundaries are calculated
-    each time a read from the filter is called, assuming 1430 bytes of data per
-    packet since the last boundary calculation. This *tends* to properly count
-    small packets, but can err if small packets come at roughly the same time.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.NetworkBytesSavedByCompression" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    The absolute difference in bytes between the amount of data entering the
-    SDCH filter and the amount of data exiting the SDCH filter.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.NetworkBytesSpent" units="bytes"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    Absolute sizes, in bytes, of SDCH dictionaries fetched over the network.
-    These are logged in SdchOwner when dictionary fetches complete.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.PartialBytesIn" units="bytes" expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode INCOMPLETE_SDCH_CONTENT reports that the VCDIFF
-    decoder still has internally buffered data that has never been read, this
-    histogram reports the number of bytes that were received over the net (or
-    from the cache) and fed to the start of the filter chain (usually to the
-    gunzip filter).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.PartialVcdiffIn" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode INCOMPLETE_SDCH_CONTENT reports that the VCDIFF
-    decoder still has internally buffered data that has never been read, this
-    histogram reports the number of bytes that were received over the net (or
-    from the cache) and fed to VCDIFF decoder (usually after gunzipping).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.PartialVcdiffOut" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode INCOMPLETE_SDCH_CONTENT reports that the VCDIFF
-    decoder still has internally buffered data that has never been read, this
-    histogram reports the number of bytes that were output by the VCDIFF decoder
-    (and sent toward the renderer).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.PersistenceFailureReason"
-    enum="SdchPersistenceFailureReason" expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Tracks failures that occur when reading in or writing out persisted
-    dictionary information.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.ProblemCodes_3" enum="SdchProblemCode"
-    expires_after="2014-11-13">
-  <obsolete>
-    Removed 2014-11. Sdch3.ProblemCodes_5 used instead.
-  </obsolete>
-  <summary>Each sample is the report of a distinct problem code.</summary>
-</histogram>
-
-<histogram name="Sdch3.ProblemCodes_4" enum="SdchProblemCode"
-    expires_after="2014-11-13">
-  <obsolete>
-    Removed 2014-11. Sdch3.ProblemCodes_5 used instead.
-  </obsolete>
-  <summary>Each sample is the report of a distinct problem code.</summary>
-</histogram>
-
-<histogram name="Sdch3.ProblemCodes_5" enum="SdchProblemCode"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>Each sample is the report of a distinct problem code.</summary>
-</histogram>
-
-<histogram name="Sdch3.ResponseCorruptionDetection.Cached"
-    enum="SdchResponseCorruptionDetectionCauses" expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Attempted SDCH decoding can fail at the Read() filter processing stage. In
-    some of those cases, the request is corrupted enough that it must be either
-    retried or failed completely. This histogram records the details of why the
-    request was considered corrupted, for results returned from the cache.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.ResponseCorruptionDetection.Uncached"
-    enum="SdchResponseCorruptionDetectionCauses" expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    Attempted SDCH decoding can fail at the Read() filter processing stage. In
-    some of those cases, the request is corrupted enough that it must be either
-    retried or failed completely. This histogram records the details of why the
-    request was considered corrupted for results returned from the network.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.TimeWeightedMemoryUse" units="bytes"
-    expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <owner>ellyjones@chromium.org</owner>
-  <summary>
-    Measures the time-weighted memory use of SDCH dictionaries, in bytes. The
-    numerator is bytes of dictionary times seconds that dictionary was in
-    memory, and the denominator is seconds that the Chrome process lives.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UnflushedBufferSize" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode UNFLUSHED_CONTENT reports that the SDCH filter is
-    still buffering output of the VCDIFF decoder that has never been read, this
-    histogram reports the number of bytes that were in that buffer.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UnflushedBytesIn" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode UNFLUSHED_CONTENT reports that the SDCH filter is
-    still buffering output of the VCDIFF decoder that has never been read, this
-    histogram reports the number of bytes that were received over the net (or
-    from the cache) and fed to the start of the filter chain (usually to the
-    gunzip filter).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UnflushedVcdiffIn" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode UNFLUSHED_CONTENT reports that the SDCH filter is
-    still buffering output of the VCDIFF decoder that has never been read, this
-    histogram reports the number of bytes that were received over the net (or
-    from the cache) and fed to VCDIFF decoder (usually after gunzipping).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UnflushedVcdiffOut" units="bytes"
-    expires_after="2016-11-10">
-  <obsolete>
-    Removed 2016-11.
-  </obsolete>
-  <summary>
-    If/when a ProblemCode UNFLUSHED_CONTENT reports that the SDCH filter is
-    still buffering output of the VCDIFF decoder that has never been read, this
-    histogram reports the number of bytes that were output by the VCDIFF decoder
-    (and sent toward the renderer).
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UsageInterval" units="ms" expires_after="2015-12-14">
-  <obsolete>
-    Use Sdch3.UsageInterval2 instead.
-  </obsolete>
-  <summary>
-    The amount of time from the last time an SDCH dictionary was used. For the
-    first use of a dictionary, the maximum time is used.
-  </summary>
-</histogram>
-
-<histogram name="Sdch3.UsageInterval2" units="ms" expires_after="2017-09-14">
-  <obsolete>
-    Removed 2017-9.
-  </obsolete>
-  <summary>
-    The amount of time from the last time an SDCH dictionary was used. Not
-    recorded on first dictionary use. First use is recorded as
-    Sdch3.FirstUseInterval.
-  </summary>
-</histogram>
-
-<histogram name="Search.AddSearchProvider" enum="AddSearchProvider"
-    expires_after="2015-11-30">
-  <obsolete>
-    Replaced by Search.AddSearchProvider2, which is also now obsolete.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures how much the user modifies their search engines, whether through
-    window.external.AddSearchProvider or chrome://settings.
-  </summary>
-</histogram>
-
-<histogram name="Search.AddSearchProvider2" enum="AddSearchProvider"
-    expires_after="2016-05-10">
-  <obsolete>
-    AddSearchProvider was removed 05/2016.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures usage of window.external.AddSearchProvider and user interaction
-    with the resulting confirmation dialog (if any). Only works on Views
-    platforms (Win, Linux, CrOS).
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchAllCapsResultsSeen"
-    enum="ContextualSearchResultsSeen" expires_after="2017-05-08">
-  <obsolete>
-    Removed 05/2017 because it's no longer ever used.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether search results were seen during a contextual search where the
-    selected text consisted of all capital letters. Only logged when contextual
-    search is triggered due to a tap. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchBlacklistSeen"
-    enum="ContextualSearchBlacklistSeen" expires_after="2017-05-11">
-  <obsolete>
-    Discontinued on 5/2017 due to experiment being completed.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>pedrosimonetti@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The details (blacklist reason and whether the results were seen) of every
-    search term issued by a tap gesture. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchDurationNonPrefetched" units="ms"
-    expires_after="2017-03-23">
-  <obsolete>
-    Discontinued on 2/2017 Due to data being buggy and not useful.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The time from opening the panel until the SERP is fully loaded. Applies only
-    to non-prefetched requests. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchDurationPrefetched" units="ms"
-    expires_after="2017-03-23">
-  <obsolete>
-    Discontinued on 2/2017 Due to data being buggy and not useful.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The time from opening the panel until the SERP is fully loaded. Applies only
-    to prefetched requests. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchIconSpriteAnimated"
-    enum="ContextualSearchIconSpriteAnimated" expires_after="2017-04-07">
-  <obsolete>
-    Contextual Search icon sprite removed 04/2017.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether search results were seen, whether the search provider icon sprite
-    was animated when the panel first appeared, and the triggering gesture. If
-    animation is disabled due to a field trial, we still log
-    &quot;animated&quot; if the animation would have run otherwise.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPeekPromoCount" units="count"
-    expires_after="2017-11-08">
-  <obsolete>
-    Removed because the feature no longer exists.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>pedrosimonetti@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of times the Peek Promo was seen. This histogram will be emitted
-    when the Panel closes. The panel is always visible when the Peek Promo is
-    shown, so this histogram will always be emitted after a Promo is shown
-    (except in the case of a crash). This histogram does not care whether the
-    Panel was opened.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPeekPromoCountUntilOpened"
-    units="count" expires_after="2017-11-08">
-  <obsolete>
-    Removed because the feature no longer exists.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>pedrosimonetti@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of times the Peek Promo was seen until the Panel was opened. This
-    histogram will be emitted when the Panel closes, if the Panel was opened
-    with the Peek Promo visible. If the Panel is not opened, nothing will be
-    emitted.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPeekPromoOutcome"
-    enum="ContextualSearchPeekPromoOutcome" expires_after="2017-11-08">
-  <obsolete>
-    Removed because the feature no longer exists.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>pedrosimonetti@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The outcome of the Contextual Search Peek Promo for those who have seen the
-    promo and for those who would have seen the promo if it was enabled, so we
-    can compare the effect of the promo on users opening the Panel. This
-    histogram will be emitted when the Panel closes, if the conditions to
-    display the Peek Promo are met, regardless of whether the Peek Promo was
-    actually visible (the Promo is controlled by Finch) and regardless of
-    whether the Panel was opened.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPrefetchSummary"
-    enum="ContextualSearchPrefetchSummary" expires_after="2017-03-23">
-  <obsolete>
-    Discontinued on 2/2017 Due to data not being useful.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    A summary histogram for prefetch timings, indicating fully preloaded, etc.
-    Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchRecentScrollNotSeen" units="ms"
-    expires_after="2017-02-28">
-  <obsolete>
-    Removed 02/2017.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The duration since a recent scroll when the results were not seen. Recorded
-    when the UX is hidden. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchRecentScrollSeen" units="ms"
-    expires_after="2017-02-28">
-  <obsolete>
-    Removed 02/2017.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The duration since a recent scroll when the results were seen. Recorded when
-    the UX is hidden. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchResultsSeenSelectionWasUrl"
-    enum="ContextualSearchSeenByGesture" expires_after="2017-05-08">
-  <obsolete>
-    Removed 05/2017 because it's no longer ever used.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether search results were seen (Contextual Search panel was opened) when
-    the selection was part of a URL, broken down by original triggering gesture.
-    Includes both users that have enabled Contextual Search and users that are
-    undecided (have neither enabled or disabled the feature). Implemented for
-    Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchSecondTapSeen"
-    enum="ContextualSearchResultsSeen" expires_after="2017-12-01">
-  <obsolete>
-    Removed 11/2017 because the data is no longer valuable.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether results were seen for a Tap during suppression when Tap Suppression
-    is enabled. Recorded when the UX is hidden. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchSerpLoadedOnClose"
-    enum="ContextualSearchLoaded" expires_after="2017-03-23">
-  <obsolete>
-    Removed 02/2017 because the data is no longer valuable.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether the SERP was fully loaded when an opened panel was closed.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchShouldTranslate"
-    enum="ContextualSearchShouldTranslate" expires_after="2019-04-05">
-  <obsolete>
-    Removed in M75 because the data is no longer needed.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Emitted when a translate one-box should be forced, to indicate if it
-    actually was forced or simply would have been forced if not disabled by a
-    flag in the variations_service.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchStartedWithCapitalResultsSeen"
-    enum="ContextualSearchResultsSeen" expires_after="2017-05-11">
-  <obsolete>
-    Removed 05/2017 because the data is no longer needed.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether search results were seen during a contextual search where the
-    selected text started with a capital letter but was not all capital letters.
-    Only logged when contextual search is triggered due to a tap. Implemented
-    for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchTapSuppressionSeen"
-    enum="ContextualSearchResultsSeen" expires_after="2017-12-01">
-  <obsolete>
-    Removed 11/2017 because the data is no longer valuable.
-  </obsolete>
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    Whether results were seen for a Tap before suppression when Tap Suppression
-    is enabled. Recorded when the UX is hidden. Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.DefaultSearchProvider" enum="OmniboxSearchEngine"
-    expires_after="2014-02-28">
-  <obsolete>
-    Made obsolete around Chrome 32. Use Search.DefaultSearchProviderType
-    instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The id of the default search engine that is loaded after Chrome startup. See
-    src/chrome/browser/search_engines/prepopulate_engines.json for more info.
-  </summary>
-</histogram>
-
-<histogram name="Search.DesktopSearch.RedirectionInfobarCloseAction"
-    enum="DesktopSearchRedirectionInfobarCloseAction"
-    expires_after="2016-05-24">
-  <obsolete>
-    Removed 05/2016 because desktop searches are no longer opened in the default
-    browser.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The action performed by the user to close the infobar explaining that a
-    desktop search has been redirected to the default search engine.
-  </summary>
-</histogram>
-
-<histogram name="Search.DesktopSearch.URLAction" enum="DesktopSearchURLAction"
-    expires_after="2016-05-24">
-  <obsolete>
-    Removed 05/2016 because desktop searches are no longer opened in the default
-    browser.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The action performed when a desktop search URL is passed to the browser
-    through the command line.
-  </summary>
-</histogram>
-
-<histogram name="Search.GsaProcessMemoryPss" units="KB"
-    expires_after="2017-06-20">
-  <obsolete>
-    Removed 06/2017, no longer recorded.
-  </obsolete>
-  <owner>lizeb@chromium.org</owner>
-  <summary>
-    On Android, when Chrome connects to a bound service exposed by GSA, the
-    memory footprint of the GSA process in KB, as measured by PSS. Reported at
-    most once per Chrome startup.
-  </summary>
-</histogram>
-
-<histogram name="Search.MigratedPrefToDictionaryValue" enum="BooleanHit"
-    expires_after="2017-01-10">
-  <obsolete>
-    Removed after migrator is deleted in 12/2016.
-  </obsolete>
-  <owner>caitkp@chromium.org</owner>
-  <summary>
-    The number of times that a user-selected DSE was migrated from separate
-    String/List/..Value preferences to the new single DictionaryValue used in
-    M36.
-  </summary>
-</histogram>
-
-<histogram
-    name="Security.HTTPBad.NavigationStartedAfterUserWarnedAboutSensitiveInput"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2018-12 after HTTPBad was rolled out for all HTTP pages. This metric
-    was recorded only after sensitive input events, which were removed.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Records the time from when a page was put into a warning state because of a
-    sensitive input on an HTTP page until a navigation starts. Recorded at most
-    once per main-frame navigation. The Finch trial 'mark-non-secure-as'
-    controls whether the user sees an omnibox warning for this state, or just a
-    console warning.
-  </summary>
-</histogram>
-
-<histogram name="Security.HTTPBad.UserWarnedAboutSensitiveInput"
-    enum="BooleanShown" expires_after="2016-11-10">
-  <obsolete>
-    Removed on 2016-11-10 because this is replaced by two separate metrics:
-    Security.HTTPBad.UserWarnedAboutSensitiveInput.CreditCard and
-    Security.HTTPBad.UserWarnedAboutSensitiveInput.Password.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Whether a &quot;Not Secure&quot; warning was shown in the omnibox because a
-    security-sensitive form field was rendered in a non-secure context. Logged
-    at most once per main-frame navigation.
-  </summary>
-</histogram>
-
-<histogram name="Security.HTTPBad.UserWarnedAboutSensitiveInput.CreditCard"
-    enum="BooleanShown" expires_after="2018-12-20">
-  <obsolete>
-    Removed 2018-12 after HTTPBad was rolled out for all HTTP pages, and
-    discrete credit card / password tracking was removed.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Whether a &quot;Not Secure&quot; warning was shown in the omnibox because a
-    credit card form field was rendered in a non-secure context. Logged at most
-    once per main-frame navigation.
-  </summary>
-</histogram>
-
-<histogram name="Security.HTTPBad.UserWarnedAboutSensitiveInput.Password"
-    enum="BooleanShown" expires_after="2018-12-20">
-  <obsolete>
-    Removed 2018-12 after HTTPBad was rolled out for all HTTP pages, and
-    discrete credit card / password tracking was removed.
-  </obsolete>
-  <owner>elawrence@chromium.org</owner>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Whether a &quot;Not Secure&quot; warning was shown in the omnibox because a
-    password form field was rendered in a non-secure context. Logged at most
-    once per main-frame navigation.
-  </summary>
-</histogram>
-
-<histogram
-    name="Security.HTTPBad.WebContentsDestroyedAfterUserWarnedAboutSensitiveInput"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2018-12 after HTTPBad was rolled out for all HTTP pages. This metric
-    was recorded only after sensitive input events, which were removed.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Records the time delta between when a page was put into a warning state
-    because of a sensitive input on an HTTP page and when the WebContents was
-    destroyed. Recorded at most once per main-frame navigation, and it is not
-    recorded if the user starts a navigation before the WebContents is
-    destroyed. The Finch trial 'mark-non-secure-as' controls whether the user
-    sees an omnibox warning for this state, or just a console warning.
-  </summary>
-</histogram>
-
-<histogram name="Security.PageInfo.Action.HttpsUrl.Valid"
-    enum="WebsiteSettingsAction" expires_after="2018-02-01">
-  <obsolete>
-    Removed 2018-01-31, split into ValidEV and ValidNonEV.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Tracks Page Info bubble actions that take place on a valid HTTPS URL with no
-    security issues (e.g. no mixed content).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Security.TimeOnPage" units="units"
-    expires_after="2019-03-15">
-  <obsolete>
-    Removed March 2019 in favor of Security.TimeOnPage2.
-  </obsolete>
-  <owner>cthomp@chromium.org</owner>
-  <summary>
-    Records the time spent on the page (the time that the page was in the
-    foreground from the start of the navigation to the page visit completing due
-    to a new navigation or the tab being closed). This aggregates all foreground
-    time over the entire visit (multiple times in the foreground are added
-    together). For pages that were never backgrounded, this histogram
-    (accidentally) collects 0 instead of the actual foreground time.
-  </summary>
-</histogram>
-
-<histogram name="Security.TreatInsecureOriginAsSecure" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed April 2020 as it is no longer used.
-  </obsolete>
-  <owner>mkwst@chromium.org</owner>
-  <summary>
-    Records the number of origins which will be treated as secure based on their
-    presence in the '--unsafely-treat-insecure-origin-as-secure' command-line
-    flag.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SendTabToSelf.DeviceCount" units="device_counts"
-    expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>sebsg@chromium.org</owner>
-  <owner>tgupta@chromium.org</owner>
-  <summary>
-    Record how many valid devices are shown when user trigger to see the device
-    list.
-  </summary>
-</histogram>
-
-<histogram name="SendTabToSelf.Notification" enum="SendTabToSelfNotification"
-    expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>sebsg@chromium.org</owner>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>tgupta@chromium.org</owner>
-  <summary>
-    The use of desktop notification for SendTabToSelf.
-
-    These notifications are tied to a sync type so there is a distinction
-    between user initiated actions (Opened, Dismissed) and actions that are
-    initiated by changes to the sync model (Shown, DismissedRemotely).
-  </summary>
-</histogram>
-
-<histogram name="SendTabToSelf.Sync.AddEntryStatus"
-    enum="SendTabToSelfAddEntryStatus" expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    The result of the add entry method when a tab is shared via SendTabToSelf
-  </summary>
-</histogram>
-
-<histogram name="SendTabToSelf.Sync.ApplySyncChangesStatus"
-    enum="SendTabToSelfApplySyncChanges" expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>sebsg@chromium.org</owner>
-  <summary>
-    The result of the ApplySyncChanges method when a tab is shared via
-    SendTabToSelf
-  </summary>
-</histogram>
-
-<histogram name="SendTabToSelf.Sync.ModelLoadedInTime" enum="Boolean"
-    expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>tgupta@chromium.org</owner>
-  <summary>
-    Whether or not the SendTabToSelf model was loaded in time to perform the
-    necessary update.
-  </summary>
-</histogram>
-
-<histogram name="SendTabToSelf.Sync.NotifyLocalDevice"
-    enum="SendTabToSelfNotifyLocalDevice" expires_after="M84">
-  <obsolete>
-    Removed 05/2020.
-  </obsolete>
-  <owner>jeffreycohen@chromium.org</owner>
-  <owner>tgupta@chromium.org</owner>
-  <summary>
-    The number of entry that are sent to the SendTabToSelf NotificationHandler.
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.ISensor.Activation.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from activating a sensor in the ISensor API, used in
-    the implementation of W3C sensors on Windows. This includes both errors and
-    successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.ISensor.Start.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from starting a sensor in the ISensor API, used in the
-    implementation of W3C sensors on Windows. This includes both errors and
-    successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.ISensor.Stop.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from stopping a sensor in the ISensor API, used in the
-    implementation of W3C sensors on Windows. This includes both errors and
-    successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.WinRT.Activation.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from activating a sensor in the
-    Windows.Devices.Sensors WinRT API, used in the implementation of W3C sensors
-    on Windows. This includes both errors and successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.WinRT.Start.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from starting a sensor in the Windows.Devices.Sensors
-    WinRT API, used in the implementation of W3C sensors on Windows. This
-    includes both errors and successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="Sensors.Windows.WinRT.Stop.Result" enum="Hresult"
-    expires_after="M82">
-  <obsolete>
-    Removed in M82 after the WinRT backend experiment concluded.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <owner>wensh@microsoft.com</owner>
-  <summary>
-    The HRESULTs returned from stopping a sensor in the Windows.Devices.Sensors
-    WinRT API, used in the implementation of W3C sensors on Windows. This
-    includes both errors and successes (S_OK).
-  </summary>
-</histogram>
-
-<histogram name="SequencedWorkerPool.ShutdownDelayTime" units="ms"
-    expires_after="2018-02-22">
-  <obsolete>
-    Removed 02/2018. SequencedWorkerPool has been removed.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    How long it takes to wait for tasks that block shutdown to complete.
-  </summary>
-</histogram>
-
-<histogram name="SequencedWorkerPool.TaskCount" units="units"
-    expires_after="2016-03-07">
-  <obsolete>
-    Histogram wasn't even reported anymore when ownership was taken in 11/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    How many pending tasks there are on each request for work from a worker
-    thread.
-  </summary>
-</histogram>
-
-<histogram name="SequencedWorkerPool.UnrunnableTaskCount" units="units"
-    expires_after="2016-03-07">
-  <obsolete>
-    Histogram wasn't even reported anymore when ownership was taken in 11/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>How many tasks we skip over to find the next runnable task.</summary>
-</histogram>
-
-<histogram name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time"
-    units="ms" expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken for the browser to find and possibly start an active worker
-    to dispatch a FetchEvent for a main frame resource request. BEWARE: This
-    metric includes the time taken for redirects. It starts when the URLRequest
-    is created, and ends when the worker is ready. For context, a FetchEvent can
-    only be dispatched to an ACTIVATED worker that is running (it has been
-    successfully started). The measurements starts when the browser process
-    receives the request. The browser then finds the worker appropriate for this
-    request (if there is none, this metric is not recorded). If that worker is
-    already started, the browser process can send the request to it, so the
-    measurement ends quickly. Otherwise the browser process has to start the
-    worker and the measurement ends when the worker is successfully started (we
-    do not include in the time it takes for the worker to become ACTIVATED). The
-    metric is not recorded in the following situations: 1) The worker was in
-    state INSTALLED or ACTIVATING, and the browser had to wait for it to become
-    ACTIVATED. This is to avoid including the time to execute the activate event
-    handlers in the worker's script. 2) The worker was started for the fetch AND
-    DevTools was attached during startup. This is intended to avoid including
-    the time for debugging. 3) The request is for New Tab Page. This is because
-    it tends to dominate the stats and makes the results largely skewed.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type"
-    enum="ServiceWorkerPreparationType" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The type of preparation needed for the browser to find and possibly start an
-    active worker to dispatch a FetchEvent for a main frame resource request.
-    See details at ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time.
-    The suffixed histograms for .Time record the time required for each type.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ActivateEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.ActivateEvent.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerGlobalScope.onactivate. Includes the time for
-    waitUntil() promise to settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.BackgroundFetchedEvent.Time" units="ms"
-    expires_after="2018-08-14">
-  <obsolete>
-    Removed 08/2018, and renamed to BackgroundFetchSuccessEvent. See
-    ServiceWorker.BackgroundFetchSuccessEvent.Time instead.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    The time taken between dispatching a BackgroundFetchedEvent to a Service
-    Worker and receiving a message that it finished handling the event. Includes
-    the time for the waitUntil() promise to settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ContextRequestHandlerStatus"
-    enum="ServiceWorkerContextRequestHandlerStatus" expires_after="2019-03-13">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The result of ServiceWorkerContextRequestHandler handling a request for a
-    service worker script. The histogram is suffixed to distinguish new vs
-    installed workers and main vs imported scripts.
-
-    Note that since M64, this no longer includes most script loads because those
-    are handled by ServiceWorkerInstalledScriptsManager, which doesn't record
-    this histogram.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.DiskCacheMigrator.MigrationResult"
-    enum="ServiceWorkerDiskCacheMigrationStatus" expires_after="2015-12-15">
-  <obsolete>
-    Removed because the migrator was removed as of 12/2015.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    Records result of ServiceWorkerDiskCacheMigrator::Start that migrates
-    resources in BlockFile backend to Simple backend.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.DiskCacheMigrator.MigrationTime" units="ms"
-    expires_after="2015-12-15">
-  <obsolete>
-    Removed because the migrator was removed as of 12/2015.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerDiskCache migration from BlockFile to Simple.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.DiskCacheMigrator.NumberOfMigratedResources"
-    units="count" expires_after="2015-12-15">
-  <obsolete>
-    Removed because the migrator was removed as of 12/2015.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    The counts of resources migrated by ServiceWorkerDiskCacheMigrator. This
-    includes the main script and imported scripts.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.EventDispatchingDelay" units="ms"
-    expires_after="2018-11-01">
-  <obsolete>
-    Removed Oct 2018 (M72)
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time taken between sending an event IPC from the browser process to a
-    Service Worker and executing the event handler in the Service Worker.
-
-    For subresource fetch events (_FETCH_SUB_RESOURCE suffix) When NetS13nSW
-    (https://crbug.com/715640) is enabled, this is the time between sending a
-    DispatchFetchEvent message from the main thread and executing the event
-    handler in the Service Worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.EventHandledRatioType.Fetch"
-    enum="ServiceWorkerEventHandleRatioType" expires_after="2018-07-02">
-  <obsolete>
-    Removed July 2018 (M69)
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Records the proportion of (non foreign) fetch events that are handled
-    compared to the number of events that are fired for a ServiceWorker.
-    Recorded each time the ServiceWorker is stopped when at least one event was
-    fired.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.EventHandledRatioType.ForeignFetch"
-    enum="ServiceWorkerEventHandleRatioType" expires_after="2018-07-02">
-  <obsolete>
-    Removed July 2018 (M69)
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Records the proportion of foreign fetch events that are handled compared to
-    the number of events that are fired for a ServiceWorker. Recorded each time
-    the ServiceWorker is stopped when at least one event was fired.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.FetchEvent.Time" units="ms"
-    expires_after="2015-07-14">
-  <obsolete>
-    Removed on 2015-07-13; please use ServiceWorker.FetchEvent.HasResponse.Time
-    or ServiceWorker.FetchEvent.Fallback.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerGlobalScope.onfetch. Includes the time for
-    the respondWith() promise to settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.FetchEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.FetchEvent.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerGlobalScope.onfetch. Includes the time for
-    the respondWith() promise to settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.FetchRespondWithDataPipeCreation.Time"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Expired after M85.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    Measures how long the service worker thread is blocked creating a
-    mojo::DataPipe during FetchEvent.respondWith() processing.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ForeignFetch.OriginCount" units="units"
-    expires_after="2018-04-09">
-  <obsolete>
-    Removed April 2018.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The number of origins a particular service worker with foreign fetch
-    registrations will intercept fetches from. A value of zero indicates that
-    the foreign fetch service worker intercepts requests from any origin.
-    Recorded at the end of a successful install event, if the service worker
-    registered for foreign fetch. A service worker that registers for foreign
-    fetch must always intercept fetches from at least one origin or intercept
-    fetches from all origins.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ForeignFetch.ScopeCount" units="units"
-    expires_after="2018-04-09">
-  <obsolete>
-    Removed April 2018.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The number of foreign fetch scopes a particular service worker registered
-    for. Recorded at the end of every successful install event. A value of zero
-    indicates that the service worker did not register for foreign fetch.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ForeignFetchEvent.Fallback.Time" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2018
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The time taken between dispatching a ForeignFetchEvent to a Service Worker
-    and receiving a fallback-to-network reply. Includes the time for the
-    waitUntil() promise to settle, if any.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ForeignFetchEvent.HasResponse.Time" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2018
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    The time taken between dispatching a ForeignFetchEvent to a Service Worker
-    and receiving a response. Includes the time for the respondWith() promise to
-    settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ForeignFetchEvent.WaitUntil.Time" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2018
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    The time taken between dispatching a ForeignFetchEvent to a Service Worker
-    and finishing the ForeignFetch. Includes the time for the waitUntil()
-    promise to settle. If there is no waitUntil promise, this will be almost the
-    same with HasResponse.Time or Fallback.Time.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.InstallEvent.Status"
-    enum="ServiceWorkerStatusCode" expires_after="2021-02-16">
-  <obsolete>
-    Removed 10/2020. Replaced with ServiceWorker.InstallEvent.All.Status.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>The result of dispatching the install event to the worker.</summary>
-</histogram>
-
-<histogram name="ServiceWorker.InstallEvent.Time" units="ms"
-    expires_after="2021-02-01">
-  <obsolete>
-    Removed 10/2020. Replaced with ServiceWorker.InstallEvent.All.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The time taken between dispatching an InstallEvent to a Service Worker and
-    receiving a message that it finished handling the event. Includes the time
-    for the waitUntil() promise to settle.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.InstallEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.InstallEvent.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerGlobalScope.oninstall. Includes the time for
-    the waitUntil() promise to settle.
-  </summary>
-</histogram>
-
-<histogram
-    name="ServiceWorker.LoadTiming.MainFrame.MainResource.ForwardServiceWorkerToWorkerReady"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2018-11 in favor of
-    ServiceWorker.LoadTiming.MainFrame.MainResource.ForwardServiceWorkerToWorkerReady2.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The time taken from (a) a resource loading request is routed to service
-    worker path, to (b) a service worker is ready to handle the request.
-
-    Recorded for each navigation request (including redirects) where there is a
-    fetch event handler and the fetch event was successfully dispatched to the
-    service worker.
-  </summary>
-</histogram>
-
-<histogram
-    name="ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted"
-    units="ms" expires_after="2021-10-31">
-  <obsolete>
-    Removed 2018-11 in favor of
-    ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted2.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The time taken from (a) response headers from service worker are received,
-    to (b) reading response body is completed. Recorded when a fetch event
-    handler handled the request.
-
-    Recorded for each navigation request (including redirects) where there is a
-    fetch event handler and the fetch event was successfully dispatched to the
-    service worker.
-  </summary>
-</histogram>
-
-<histogram
-    name="ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2018-12 in favor of
-    ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The time taken from (a) response headers from service worker are received,
-    to (b) reading response body is completed. Only recorded when a fetch event
-    handler handled the request.
-
-    Recorded for each subresource request where there is a fetch event handler
-    and the fetch event was successfully dispatched to the service worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.MainFramePageLoad.CoreTransition"
-    enum="CorePageTransition" expires_after="2018-01-30">
-  <obsolete>
-    Removed 2018-01 in favor of PageLoad.Clients.ServiceWorker.PageTransition.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The transition type for main frame page loads controlled by a service
-    worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.MainFramePageLoad.RedirectChainLength"
-    units="urls" expires_after="2018-01-30">
-  <obsolete>
-    Removed 2018-01.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    Total length of the server redirects during main frame page loads controlled
-    by a service worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.MainResourceRequestDestination"
-    enum="ServiceWorkerMainResourceRequestDestination"
-    expires_after="2018-12-01">
-  <obsolete>
-    Removed 2018-11, see https://crbug.com/902100
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    Describes whether a main resource request (i.e., a request for a main frame,
-    subframe, or shared worker) was routed to service worker or network and why.
-    The purpose is to debug why ServicifiedServiceWorker has a lower count of
-    ServiceWorker.MainResource.FetchEvent.Status than the control:
-    https://crbug.com/866335.
-
-    Recorded for every main resource request that is seen by
-    ServiceWorkerControlleeRequestHandler (usually means all http(s) requests).
-    If redirects occur, it is recorded for each redirect.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.MessageEvent.Time" units="ms"
-    expires_after="2016-04-18">
-  <obsolete>
-    Removed 2016-04 in favor of ServiceWorker.ExtendableMessageEvent.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>Execution time of ServiceWorkerGlobalScope.onmessage.</summary>
-</histogram>
-
-<histogram name="ServiceWorker.MessageEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.MessageEvent.Time.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>Execution time of ServiceWorkerGlobalScope.onmessage.</summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationHintPrecision" enum="BooleanEnabled"
-    expires_after="2017-03-29">
-  <obsolete>
-    This experiment was turned down, see https://crbug.com/616502.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The precision of the speculative launch of Service Workers for navigation
-    hints. Recorded when the worker is stopped. If there was no main/sub frame
-    fetch event fired on the worker, this value is false. This means that the
-    speculative launch wasn't helpful.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.ConcurrentTime" units="ms"
-    expires_after="2017-06-07">
-  <obsolete>
-    Removed June 2017 in favor of ServiceWorker.NavPreload.ConcurrentTime, see
-    https://crbug.com/728035.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The duration of time when both (1) a service worker is being found and
-    possibly started up, (2) the navigation preload request is in-flight. The
-    measurement ends once either the worker is prepared, or the navigation
-    preload response is received (OnReceiveResponse() is called). This is a
-    rough estimate of the performance win of using navigation preload, ignoring
-    concurrency overhead. This histogram is recorded when a navigation preload
-    response is succesfully forwarded to the service worker's fetch event, with
-    the same restrictions as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    additionally recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.FinishedBeforeStartWorker"
-    enum="BooleanNavPreloadFinishedFirst" expires_after="2017-06-07">
-  <obsolete>
-    Removed June 2017 in favor of ServiceWorker.NavPreload.FinishedFirst, see
-    https://crbug.com/728035.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Whether the navigation preload response arrived before the activated and
-    running service worker was prepared. This histogram is recorded when a
-    navigation preload response is succesfully forwarded to the service worker's
-    fetch event, with the same restrictions as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    additionally recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.HeaderSize" units="bytes"
-    expires_after="M85">
-  <obsolete>
-    Expired June 2020.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The size of Service-Worker-Navigation-Preload header when the navigation
-    preload request is to be sent. The default value of the header is
-    &quot;true&quot;, so the default size is 4.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.NavPreloadAfterSWStart"
-    units="ms" expires_after="2017-06-07">
-  <obsolete>
-    Removed June 2017. No replacement exists. See https://crbug.com/728035.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    This is recorded in the case where the activated and running service worker
-    was prepared before the navigation preload response arrived. It is the
-    remaining time it took to receive the response after the worker was
-    prepared.
-
-    This histogram is recorded when a navigation preload response is succesfully
-    forwarded to the service worker's fetch event (for the case mentioned
-    above), with the same restrictions as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    additionally recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.ResponseTime" units="ms"
-    expires_after="2017-06-07">
-  <obsolete>
-    Removed June 2017 in favor of ServiceWorker.NavPreload.ResponseTime. See
-    https://crbug.com/728035.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken for the navigation preload response to start, i.e., when
-    OnReceiveResponse() is called. This histogram is recorded when a navigation
-    preload response is successfully forwarded to the service worker's fetch
-    event, with the same restrictions as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    additionally recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavigationPreload.SWStartAfterNavPreload"
-    units="ms" expires_after="2017-06-07">
-  <obsolete>
-    Removed June 2017 in favor of ServiceWorker.NavPreload.WorkerWaitTime. See
-    https://crbug.com/728035.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    This is recorded in the case where the navigation preload response arrived
-    before the activated and running service worker was prepared. It is the
-    remaining time it took to prepare the worker after the response arrived.
-
-    This histogram is recorded when a navigation preload response is succesfully
-    forwarded to the service worker's fetch event (for the case mentioned
-    above), with the same restrictions as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    additionally recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavPreload.ConcurrentTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The duration of time when both (1) a service worker is being found and
-    possibly started up, (2) the navigation preload request is in-flight. The
-    measurement ends once either the worker is prepared, or the navigation
-    preload response is received (OnReceiveResponse() is called). This is a
-    rough estimate of the performance win of using navigation preload, ignoring
-    concurrency overhead. This histogram is recorded when a navigation preload
-    response is succesfully forwarded to the service worker's fetch event, with
-    the same restrictions enumerated 1) through 3) for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    only recorded to the appropriate suffixed histograms.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavPreload.FinishedFirst"
-    enum="BooleanNavPreloadFinishedFirst" expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Whether the navigation preload response arrived before the activated and
-    running service worker was prepared. This histogram is recorded when a
-    navigation preload response is succesfully forwarded to the service worker's
-    fetch event, with the same restrictions numbered 1) through 3) for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    only recorded to the appropriate suffixed histograms.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavPreload.ResponseTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken for the navigation preload response to start, i.e., when
-    OnReceiveResponse() is called. This histogram is recorded when a navigation
-    preload response is successfully forwarded to the service worker's fetch
-    event, with the same restrictions numbered 1) through 3) for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    only recorded to the appropriate suffixed histograms.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavPreload.WorkerPreparationType"
-    enum="ServiceWorkerPreparationType" expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The type of preparation needed for the browser to find and possibly start an
-    active worker to dispatch a FetchEvent for a main frame resource request,
-    when navigation preload also occurred.
-
-    This histogram is recorded when a navigation preload response is succesfully
-    forwarded to the service worker's fetch event (for the case mentioned
-    above), with the same restrictions numbered 1) through 3) as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    only recorded to the appropriate suffixed histograms.
-
-    This is similar to
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_NavigationPreloadEnabled.
-    The difference is ServiceWorker.NavPreload.WorkerPreparationType gets logged
-    if the navigation preload successfully occurred, at the same time as the
-    other ServiceWorker.NavPreload.* metrics so is more safely comparable to
-    them. We could deprecate the Type_NavigationPreloadEnabled histogram if it
-    turns out there is no significant difference.
-
-    It will be removed after NetS13nSW ships. https://crbug.com/715640
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NavPreload.WorkerWaitTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    This is recorded in the case where the navigation preload response arrived
-    before the activated and running service worker was prepared. It is the
-    remaining time it took to prepare the worker after the response arrived.
-
-    This histogram is recorded when a navigation preload response is succesfully
-    forwarded to the service worker's fetch event (for the case mentioned
-    above), with the same restrictions numbered 1) through 3) as for
-    ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The sample is
-    only recorded to the appropriate suffixed histograms.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.NotificationClickEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.NotificationClickEvent.Time.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Execution time of ServiceWorkerGlobalScope.onnotificationclick.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.PushEventExecutionTime" units="ms"
-    expires_after="2015-05-28">
-  <obsolete>
-    Removed 2015-05 in favor of ServiceWorker.PushEvent.Time.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <summary>Execution time of ServiceWorkerGlobalScope.onpush.</summary>
-</histogram>
-
-<histogram name="ServiceWorker.RegistrationCount" units="registrations"
-    expires_after="2020-08-25">
-  <obsolete>
-    No longer needed as found the cause of stability issue to be number of
-    registrations rather than size of registrations. Removed in July 2020.
-  </obsolete>
-  <owner>nidhijaju@google.com</owner>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    Number of service worker registrations to be added in
-    ServiceWorkerRegistry::DidGetAllRegistrations().
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.RegistrationInfo.ScopeLength" units="characters"
-    expires_after="2020-08-25">
-  <obsolete>
-    No longer needed as found the cause of stability issue to be number of
-    registrations rather than size of registrations. Removed in July 2020.
-  </obsolete>
-  <owner>nidhijaju@google.com</owner>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The length of the scope url in the ServiceWorkerRegistrationInfo is measured
-    for each service worker registration to give a better idea of the data
-    structure as a whole. This metric is collected in
-    ServiceWorkerRegistration::GetInfo().
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.RequestTimeouts.Count"
-    enum="ServiceWorkerMetrics.EventType" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The number of Service Worker request timeouts, by request type.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.ScriptLoadSuccess" enum="BooleanSuccess"
-    expires_after="2018-06-26">
-  <obsolete>
-    Removed June 2018 (M69). This was recorded as 100% success since service
-    worker script streaming launched in M64, since load failures didn't reach
-    this UMA. When there is an error reading the script from storage, it's
-    typically recorded as a start worker failure under
-    SERVICE_WORKER_ERROR_DISK_CACHE.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Whether loading the service worker script succeeded. Only recorded for
-    installed service workers. Recorded by the browser process when reported
-    back by the renderer during worker startup.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.StartHintPrecision" enum="BooleanEnabled"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The precision of the speculative launch of Service Workers for navigation
-    hints. Recorded when the worker is stopped. True if a fetch event for a
-    main/sub frame navigation was fired on the worker before it stopped;
-    otherwise, false. False means the speculative launch wasn't helpful.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.StartNewWorker.Status"
-    enum="ServiceWorkerStatusCode" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The result of trying to start a Service Worker that has not yet installed.
-    See also ServiceWorker.StartWorker.Status for installed workers.
-  </summary>
-</histogram>
-
-<histogram
-    name="ServiceWorker.StartWorker.InstalledScriptsSender.FinishedReason"
-    enum="ServiceWorkerInstalledScriptsManager.FinishedReason"
-    expires_after="M78">
-  <obsolete>
-    Removed from code in July 2019 since ServiceWorkerScriptStreaming
-    successfully launched.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    The result of sending installed scripts over
-    ServiceWorkerInstalledScriptsSender. This is recorded after every start
-    worker attempt that sent the scripts through
-    ServiceWorkerInstalledScriptsSender.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.StopWorker.Status"
-    enum="ServiceWorkerStopStatus" expires_after="2015-10-09">
-  <obsolete>
-    Removed from code in Oct 2015, replaced with ServiceWorker.WorkerStopped.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The result of trying to stop a Service Worker. Recorded only for installed
-    Service Workers that succesfully stopped or were detected as stalling. If a
-    worker stalled and later stopped, it will be recorded as both STALLED and
-    STALLED_THEN_STOPPED.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.Storage.DiskCacheMigrationResult"
-    enum="ServiceWorkerDiskCacheMigrationResult" expires_after="2015-12-15">
-  <obsolete>
-    Removed because the migrator was removed as of 12/2015.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    Records the final result of diskcache migration in ServiceWorkerStorage.
-    ServiceWorker.DiskCacheMigrator.MigrationResult records more detailed status
-    of migration operations.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.SubresourceNotifyStartLoadingResponseBodyDelay"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Expired after M85.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    The time between when the ServiceWorkerSubresourceLoader receives a Response
-    and when it notifies the loader's client that the body has started loading.
-    This is different from SubresourceStartBlobReadingDelay in that notifying
-    the client about the Response may take place some time later than when the
-    blob body reading begins. This will be triggered for every successful
-    subresource load handled by a ServiceWorker with servification enabled.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.SubresourceStartBlobReadingDelay" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    The time between when the ServiceWorkerSubresourceLoader receives a Response
-    with a blob body and when the main blob data starts to get read. This will
-    be triggered for every successful subresource load handled by a
-    ServiceWorker with ServiceWorker servification enabled.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.TerminateThread.Time" units="ms"
-    expires_after="2017-06-15">
-  <obsolete>
-    Removed in June 2017.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    The time taken in the renderer process between the main thread asking the
-    worker thread to terminate and getting ACK that it terminated.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.TimeBetweenEvents" units="ms"
-    expires_after="2017-06-15">
-  <obsolete>
-    Removed in June 2017.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Called at the beginning of each ServiceWorkerVersion::Dispatch*Event
-    function: the time elapsed since idle. Generally this is the time between
-    one event ending and one event starting, if the worker remained running in
-    the interim.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.UnhandledEventRatio" units="%"
-    expires_after="2015-07-07">
-  <obsolete>
-    Removed 2015-06 in favor of ServiceWorker.EventHandledStatus*.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Records the ratio of unhandled events to all events that are dispatched to
-    each ServiceWorker. Recorded when each ServiceWorkerVersion is destructed.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.UpdateCheck.Result"
-    enum="ServiceWorkerStatusCode" expires_after="2020-07-17">
-  <obsolete>
-    Removed 2020-07 because we could confirm byte-for-byte update checking for
-    imported scripts works.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Records the result of byte-for-byte update checking. If it's not OK, it
-    means that script comparison doesn't work well. Recorded only when
-    ServiceWorkerImportedScriptUpdateCheck is enabled.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.UpdateCheck.UpdateFound" enum="BooleanFound"
-    expires_after="2020-07-17">
-  <obsolete>
-    Removed 2020-07 because we could confirm byte-for-byte update checking for
-    imported scripts works.
-  </obsolete>
-  <owner>shimazu@chromium.org</owner>
-  <summary>
-    Records the result of byte-for-byte update checking. Recorded only when
-    ServiceWorkerImportedScriptUpdateCheck is enabled and
-    ServiceWorker.UpdateCheck.Result is OK.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.URLRequestJob.FallbackedRequestMode"
-    enum="FetchRequestMode" expires_after="M77">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    Records the the mode of request that was fallbacked to the network by the
-    Service Worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.URLRequestJob.MainResource.Result"
-    enum="ServiceWorkerURLRequestJobResult" expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Records the result of a main resource request forwarded to a Service Worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.URLRequestJob.MainResource.StatusZeroError"
-    enum="ServiceWorkerResponseError" expires_after="M77">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Records the error provided when the renderer returns a response with status
-    code zero to a main resource request forwarded to a Service Worker (i.e.,
-    ServiceWorker.URLRequestJob.MainResource.Result was
-    REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO).
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.URLRequestJob.Subresource.Result"
-    enum="ServiceWorkerURLRequestJobResult" expires_after="M80">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Records the result of a subresource request forwarded to a Service Worker.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.URLRequestJob.Subresource.StatusZeroError"
-    enum="ServiceWorkerResponseError" expires_after="M77">
-  <obsolete>
-    No longer recorded since NetS13nSW shipped on Dec 2018.
-  </obsolete>
-  <owner>falken@chromium.org</owner>
-  <summary>
-    Records the error provided when the renderer returns a response with status
-    code zero to a subresource request forwarded to a Service Worker (i.e.,
-    ServiceWorker.URLRequestJob.Subresource.Result was
-    REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO).
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.VersionInfo.ClientCount" units="clients"
-    expires_after="2020-08-25">
-  <obsolete>
-    No longer needed as found the cause of stability issue to be number of
-    registrations rather than size of registrations. Removed in July 2020.
-  </obsolete>
-  <owner>nidhijaju@google.com</owner>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    Number of clients associated with each service worker version, for better
-    estimation of the size of ServiceWorkerRegistrationInfo. This metric is
-    collected in ServiceWorkerVersion::GetInfo(), and clients for all versions
-    (active, waiting, and installing) are counted for now.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorker.VersionInfo.ScriptURLLength" units="characters"
-    expires_after="2020-08-25">
-  <obsolete>
-    No longer needed as found the cause of stability issue to be number of
-    registrations rather than size of registrations. Removed in July 2020.
-  </obsolete>
-  <owner>nidhijaju@google.com</owner>
-  <owner>bashi@chromium.org</owner>
-  <owner>chrome-worker@google.com</owner>
-  <summary>
-    The length of the script url in ServiceWorkerVersionInfo is measured for
-    each service worker version to give a better idea of the memory size of
-    ServiceWorkerRegistrationInfo as a whole. This metric is collected in
-    ServiceWorkerVersion::GetInfo().
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.Cache.AddResponseType"
-    enum="FetchResponseType" expires_after="M77">
-  <obsolete>
-    This histogram was removed in M77.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    Records the response type to be added in the Cache by Cache.add()/addAll().
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.DiskCacheCreateEntryResult"
-    enum="NetErrorCodes" expires_after="2020-04-19">
-  <obsolete>
-    Expired 2020-04.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    The network result code produced by disk_cache::Backend::CreateEntry() when
-    cache_storage is attempting to put a new request/response pair on disk.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.IndexSizeDifference" units="bytes"
-    expires_after="2020-04-19">
-  <obsolete>
-    No longer used. Removed in April 2020.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The absolute difference between the ServiceWorker Cache size saved to the
-    CacheStorage index and the actual cache size when opened.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.PeakParallelSharedOps" units="operations"
-    expires_after="M85">
-  <obsolete>
-    Replaced in M78 with ServiceWorkerCache.PeakParallelSharedOps2 that uses a
-    smaller histogram range with the same number of buckets in order to improve
-    bucket granularity.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    The peak number of shared operations that ran simultaneously during a single
-    &quot;batch&quot; of operations. A batch is defined as the time from when an
-    idle scheduler begins running a shared operation until the count of running
-    shared operations drops back to zero.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.PeakParallelSharedOps2" units="operations"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85 since the parallel operation trial launched already. Also,
-    this histogram did not provide very useful information.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    The peak number of shared operations that ran simultaneously during a single
-    &quot;batch&quot; of operations. A batch is defined as the time from when an
-    idle scheduler begins running a shared operation until the count of running
-    shared operations drops back to zero.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.Response.HasDeprecatedURL" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    This histogram was removed in M77 when we began deleting entries with the
-    deprecated url field.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    True if a response read from the CacheStorage has a url field. This field
-    was deprecated in M57.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.Scheduler.IsOperationSlow" enum="Boolean"
-    expires_after="M85">
-  <obsolete>
-    This histogram was removed in M85 in favor of the OperationDuration2
-    histograms that provide full timing information for operations.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    An operation is slow (true) if it takes at least 10 seconds to run. If an
-    operation never completes, it will still be recorded as slow.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.Scheduler.OperationDuration" units="ms"
-    expires_after="2018-11-28">
-  <obsolete>
-    This histogram was deprecated in M72 in favor of
-    ServiceWorkerCache.Scheduler.OperationDuration2.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    The time in ms from when an operation is started until it completes.
-  </summary>
-</histogram>
-
-<histogram name="ServiceWorkerCache.Scheduler.QueueDuration" units="ms"
-    expires_after="2018-11-28">
-  <obsolete>
-    This histogram was deprecated in M72 in favor of
-    ServiceWorkerCache.Scheduler.QueueDuration2.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    The time in ms from when an operation was queued until its task is posted.
-  </summary>
-</histogram>
-
-<histogram name="Servicification.Startup" enum="ServicificationStartupMode"
-    expires_after="2019-02-26">
-  <obsolete>
-    Removed 2019-02 in favour of Servicification.Startup2. The data was
-    incompelete since it was only recorded the first time when the
-    ServiceManager was launched.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <owner>hnakashima@chromium.org</owner>
-  <owner>mheikal@chromium.org</owner>
-  <summary>
-    Histogram of how Chrome is launched, either in ServiceManager only mode or
-    as full browser, as well as either cold start or warm start. See
-    go/servicification_startup_metrics for more details.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.Actions" enum="SessionRestoreActions"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The actions that have occurred in a session restore timeline. These are to
-    be interpreted as raw event counts. Tabs are almost certainly deferred due
-    to the existence memory pressure, but this may not always be the case.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.AllTabsLoaded" units="ms" expires_after="M81">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    The time from SessionRestore start until all tabs have finished loading.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.command_size" units="bytes"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    The size of the commands written to disk. See CommandStorageBackend for
-    details.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FirstTabPainted" units="ms"
-    expires_after="2014-10-29">
-  <obsolete>
-    Removed 2014-10 in favor of SessionRestore.ForegroundTabFirstPaint and
-    ultimately SessionRestore.ForegroundTabFirstPaint3.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <owner>sky@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="SessionRestore.ForegroundTabFirstLoaded" units="ms"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    The time from SessionRestore start until a visible tab has finished loading.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.ForegroundTabFirstPaint" units="ms"
-    expires_after="2015-07-31">
-  <obsolete>
-    Removed 2015-03-13 in favor of SessionRestore.ForegroundTabFirstPaint2 and
-    ultimately SessionRestore.ForegroundTabFirstPaint3.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <owner>sky@chromium.org</owner>
-  <summary>
-    Deprecated 2015-03-13 in favor of SessionRestore.ForegroundTabFirstPaint2
-    and ultimately SessionRestore.ForegroundTabFirstPaint3.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.ForegroundTabFirstPaint2" units="ms"
-    expires_after="2015-06-19">
-  <obsolete>
-    Removed 2015-05 in favor of SessionRestore.ForegroundTabFirstPaint3.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <owner>sky@chromium.org</owner>
-  <summary>
-    The time from SessionRestore start until a visible tab's first paint. This
-    metric only records paints that have occurred after a tab has loaded.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.ForegroundTabFirstPaint3" units="ms"
-    expires_after="never">
-  <obsolete>
-    Removed 06/2019 in favor of SessionRestore.ForegroundTabFirstPaint4.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    The time from SessionRestore start until a visible tab's first paint.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FrameUniqueNameFromRequestedNameSize"
-    units="characters" expires_after="2018-05-08">
-  <obsolete>
-    Removed 2018-05-02. This data was used to confirm that the unique name
-    generation change succeeded in reducing memory usage, and is no longer
-    needed.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    The size of a unique name derived from the browsing context name. Emitted
-    when generating a unique name for a new subframe or when a subframe's
-    browsing context name is changed before the first real load is committed.
-    Only applies to subframes as main frames always have an empty unique name.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FrameUniqueNameLength" units="bytes"
-    expires_after="2017-08-09">
-  <obsolete>
-    Removed 2017-08 due to unique name generation change. Please use
-    SessionRestore.FrameUniqueNameFromRequestedNameSize and
-    SessionRestore.FrameUniqueNameWithFramePathSize instead.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    Records the length of unique names for web frames that are saved as part of
-    session restore data. It is logged each time the unique name changes, which
-    typically happens when a web frame is first created or its name is changed
-    by mutating window.name.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FrameUniqueNameOriginalRequestedNameSize"
-    units="characters" expires_after="2018-05-08">
-  <obsolete>
-    Removed 2018-05-02. This data was used to confirm that the unique name
-    generation change succeeded in reducing memory usage, and is no longer
-    needed.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    The size of the browsing context name (based on the iframe name attribute or
-    window.name) when generating the unique name. Emitted when generating a
-    unique name for a new subframe or when a subframe's browsing context name is
-    changed before the first real load is committed. Only applies to subframes
-    as main frames always have an empty unique name.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FrameUniqueNameWithFramePathSize"
-    units="characters" expires_after="2018-05-08">
-  <obsolete>
-    Removed 2018-05-02. This data was used to confirm that the unique name
-    generation change succeeded in reducing memory usage, and is no longer
-    needed.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    The size of a unique name when falling back to the frame path algorithm. The
-    fallback path is used when the browsing context name is empty or non-unique.
-    Emitted when generating a unique name for a new subframe or when a
-    subframe's browsing context name is changed before the first real load is
-    committed. Only applies to subframes as main frames always have an empty
-    unique name.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.FrameUniqueNameWithFramePathSizePerComponent"
-    units="characters per depth" expires_after="2018-05-08">
-  <obsolete>
-    Removed 2018-05-02. This data was used to confirm that the unique name
-    generation change succeeded in reducing memory usage, and is no longer
-    needed.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    The size of a unique name when falling back to the frame path algorithm,
-    divided by the depth of the frame. Used to normalize sizes for deeper nodes
-    in a frame tree. Emitted when generating a unique name for a new subframe or
-    when a subframe's browsing context name is changed before the first real
-    load is committed. Only applies to subframes as main frames always have an
-    empty unique name.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.last_session_file_size" units="KB"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>The size, in k, of the last session file on disk.</summary>
-</histogram>
-
-<histogram name="SessionRestore.NavEntryCommittedLongPeriod" units="units"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Like NavEntryCommittedPeriod, but specifically to provide a clearer
-    breakdown of samples in the 10 minutes - 8 hours range.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.NavEntryCommittedPeriod" units="ms"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Milliseconds between subsequent Save() operations due to a nav entry being
-    committed (new tab created + nav initiated).
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.NavigationListPrunedLongPeriod" units="units"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Like NavListPrunedPeriod, but specifically to provide a clearer breakdown of
-    samples in the 10 minutes - 8 hours range.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.NavigationListPrunedPeriod" units="ms"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Milliseconds between subsequent Save() operations due to the navigation list
-    being pruned (typically a change in back/forward stacks).
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.ParallelTabLoads" units="units"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    The number of tabs that were loaded simultaneously when restoring a session.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.read_session_file_time" units="ms"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Amount of time to read and assemble the commands from the last session.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.RestoredSubframeURL" enum="BooleanRestoredURL"
-    expires_after="M77">
-  <obsolete>
-    Removed in July 2019 / M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    How often history navigations in subframes restore a different URL than the
-    frame's default src URL. This indicates how much users rely on subframe
-    session history items.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.RestoredTab.SiteEngagementScore" units="score"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The site engagement score associated with a tab restored by session restore,
-    recorded at the moment the tab is restored.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.RestoreSubframeFramePathLength" units="bytes"
-    expires_after="M80">
-  <obsolete>
-    Removed in July 2019 / M77, since new approach landed in r493153 (M62).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    Records the length of unique names that include frame paths, for subframes
-    that are restoring a different URL than the frame's default src URL during a
-    history navigation. Large values here would indicate a possible challenge
-    for the plan to truncate frame unique names (to save memory).
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.SaveLongPeriod" units="units"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Like SavePeriod, but specifically to provide a clearer breakdown of samples
-    in the 10 minutes - 8 hours range.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.SavePeriod" units="ms"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Amount of time between subsequent SessionService Save() operations (aka
-    updates to session data).
-
-    Periods longer than 10 minutes are grouped together; see SaveLongPeriod for
-    resolution.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.SubFrameUniqueNameChangedBeforeFirstCommit"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed 2019-05 as data is no longer needed.
-  </obsolete>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    How often a subframe is assigned a new name between the initial empty
-    document and the first navigation.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.TabActions" enum="SessionRestoreTabActions"
-    expires_after="M81">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    A breakdown of key events that occur to individual tabs as they are
-    processed by an ongoing session restore.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.TabClosedLongPeriod" units="units"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    TabClosedPeriod, but specifically to provide a clearer breakdown of samples
-    in the 10 minutes - 8 hours range.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.TabClosedPeriod" units="ms"
-    expires_after="2017-02-24">
-  <obsolete>
-    Removed 2017-02 as not actionable.
-  </obsolete>
-  <summary>
-    Milliseconds between subsequent Save() operations due to a tab being closed.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.TabCount" units="tabs"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of tabs involved in a single session restore event.
-  </summary>
-</histogram>
-
-<histogram name="SessionRestore.TabLoadTimeout" enum="BooleanTimedOut"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05. Not actively used in current projects.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The boolean indicates whether the tab load was initiated because a previous
-    tab load completed (including the tab was closed) or whether the tab load
-    was initiated because a timer fired to start the next load (true) during
-    session restore.
-  </summary>
-</histogram>
-
-<histogram name="SessionStorageDatabase.Commit" enum="LevelDBStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed during the SessionStorage onion soup refactoring.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>The result of a commit to the sessionStorage database.</summary>
-</histogram>
-
-<histogram name="Settings.DefaultSearchProvider" enum="OmniboxSearchEngine"
-    expires_after="2013-08-20">
-  <obsolete>
-    Removed in Chrome 30. Use Search.DefaultSearchProviderType instead.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The id of the default search engine domain that is specified in user
-    preferences when a profile is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Settings.EnforcementGroupDeterminedFromTrial"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed from the codebase in M85. This trial has long been obsolete.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Whether the SettingsEnforcement group was successfully determined from the
-    field trial or if it had to revert to the hardcoded default.
-  </summary>
-</histogram>
-
-<histogram name="Settings.HomePageDomain" enum="OmniboxSearchEngine"
-    expires_after="2013-08-20">
-  <obsolete>
-    Removed in Chrome 30. Replaced by Settings.HomePageEngineType.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The id of the home page domain that is specified in user preferences when a
-    profile is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Settings.HomePageIsNewTabPage" enum="Boolean"
-    expires_after="2013-08-06">
-  <obsolete>
-    Removed 08/05/2013. Replaced by
-    Settings.GivenShowHomeButton_HomePageIsNewTabPage.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Whether or not the home page user preference is set to the default NTP value
-    when a profile is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Settings.HomePageIsNewTabPage.PulledFromSync" enum="Boolean"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The value of the home-page-is-new-tab-page pref when pulled down from sync
-    to update an out-of-sync local pref store.
-  </summary>
-</histogram>
-
-<histogram name="Settings.HomePageIsNewTabPage.PushedToSync" enum="Boolean"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The value of the home-page-is-new-tab-page pref when pushed up to sync from
-    a change made locally.
-  </summary>
-</histogram>
-
-<histogram name="Settings.InitializedFromMasterPrefs" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logged on first run when generating the Preferences file from
-    master_preferences. True if serializing the generated Preferences file to
-    disk was successful, false otherwise. Note: this event does not occur if
-    there is no master_preferences file on first run.
-  </summary>
-</histogram>
-
-<histogram name="Settings.JsonDataSizeKilobytes" units="KB"
-    expires_after="2015-01-31">
-  <obsolete>
-    Removed 02/2015. Replaced by Settings.JsonDataReadSizeKilobytes.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The size of the JSON settings content about to be written to disk in
-    kilobytes. Suffixed with the name of the JSON file being written to disk.
-  </summary>
-</histogram>
-
-<histogram name="Settings.JsonDataWriteCount" units="count"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed 11/2018 due to lack of use.
-  </obsolete>
-  <owner>raymes@chromium.org</owner>
-  <summary>
-    The number of writes of a JSON file that occur in every 5 minute period of
-    running Chrome. Suffixed with the name of the corresponding JSON file.
-  </summary>
-</histogram>
-
-<histogram name="Settings.LegacyMachineIdGenerationSuccess"
-    enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed 07/2019. LegacyMachineIdGeneration failed extremely rarely.
-  </obsolete>
-  <owner>proberge@chromium.org</owner>
-  <summary>
-    Whether generation of the RLZ deterministic machine-specific device id was
-    successful when creating the ProfilePrefStore.
-  </summary>
-</histogram>
-
-<histogram name="Settings.LoadCompletedTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019. Non MD version of Settings has been deprecated.
-  </obsolete>
-  <owner>stevenjb@chromium.org</owner>
-  <summary>
-    The amount of time between the RenderFrameHost StartProvisionalLoad event
-    and the RenderFrameHost DocumentOnLoadCompleted event for the settings page.
-  </summary>
-</histogram>
-
-<histogram name="Settings.LoadDocumentTime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 07/2019. Non MD version of Settings has been deprecated.
-  </obsolete>
-  <owner>stevenjb@chromium.org</owner>
-  <summary>
-    The amount of time between the RenderFrameHost StartProvisionalLoad and
-    DidFinishDocumentLoad events for the settings page.
-  </summary>
-</histogram>
-
-<histogram name="Settings.MachineIdGenerationSuccess" enum="BooleanSuccess"
-    expires_after="2017-10-02">
-  <obsolete>
-    Removed in Chrome 63, as we verified that machine id generation was not
-    flaky.
-  </obsolete>
-  <owner>proberge@chromium.org</owner>
-  <summary>
-    Whether generation of the deterministic machine-specific device id was
-    successful when initializing the PrefHashStore.
-  </summary>
-</histogram>
-
-<histogram name="Settings.MigratedHashesFromLocalState" enum="BooleanMigrated"
-    expires_after="2016-07-14">
-  <obsolete>
-    Removed in Chrome 54, as we stopped legacy migration of preferences.
-  </obsolete>
-  <owner>csharp@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Whether, while loading a profile, any preference hashes were migrated from
-    Local State to either Preferences or Protected Preferences.
-  </summary>
-</histogram>
-
-<histogram name="Settings.PinnedTabs" units="units" expires_after="M86">
-  <obsolete>
-    Removed September 2020; no longer necessary.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>The number of pinned tabs opened when a profile is loaded.</summary>
-</histogram>
-
-<histogram name="Settings.RegisterProfilePrefsTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during RegisterProfilePrefs.
-  </summary>
-</histogram>
-
-<histogram name="Settings.ShowHomeButton.PulledFromSync" enum="BooleanEnabled"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The enabled state of the Home button pref when pulled down from sync to
-    update an out-of-sync local pref store.
-  </summary>
-</histogram>
-
-<histogram name="Settings.ShowHomeButton.PushedToSync" enum="BooleanEnabled"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The enabled state of the Home button pref when pushed up to sync from a
-    change made locally.
-  </summary>
-</histogram>
-
-<histogram name="Settings.StartupPageDomains" enum="OmniboxSearchEngine"
-    expires_after="2013-08-20">
-  <obsolete>
-    Removed in Chrome 30. Replaced by Settings.StartupPageEngineTypes.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The ids of startup page domains that are specified in user preferences when
-    a profile is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Settings.StartupPageLoadSettings.PulledFromSync"
-    enum="SessionStartupPref" expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The startup page setting when pulled down from sync to update an out-of-sync
-    local pref store.
-  </summary>
-</histogram>
-
-<histogram name="Settings.StartupPageLoadSettings.PushedToSync"
-    enum="SessionStartupPref" expires_after="2018-08-30">
-  <obsolete>
-    Removed in Aug 2018.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The startup page setting when pushed up to sync from a change made locally.
-  </summary>
-</histogram>
-
-<histogram name="Settings.StartupPageLoadURLs" units="units"
-    expires_after="M80">
-  <obsolete>
-    Not needed. Removed August 2019.
-  </obsolete>
-  <owner>mpearson@chromium.org</owner>
-  <summary>
-    The number of URLs to be loaded on startup when a profile is loaded, if the
-    startup page setting is set to load URLs.
-  </summary>
-</histogram>
-
-<histogram name="Settings.StartupURLsMigration" enum="StartupURLsMigration"
-    expires_after="2015-12-03">
-  <obsolete>
-    Removed 12/2015.
-  </obsolete>
-  <owner>mad@chromium.org</owner>
-  <summary>The startup URLs pref migration steps.</summary>
-</histogram>
-
-<histogram name="Settings.StartupURLsResetTime" units="ms"
-    expires_after="2015-12-03">
-  <obsolete>
-    Removed 12/2015.
-  </obsolete>
-  <owner>mad@chromium.org</owner>
-  <summary>
-    The time elapsed in milliseconds in between startup URLs pref migration. A
-    value of 0 indicates that the last migration time was in the future due to
-    e.g. an incorrect system time.
-  </summary>
-</histogram>
-
-<histogram name="Settings.SyncSetup.DisplayedSwaaState"
-    enum="SyncSetupSettignsDisplayedSwaaState" expires_after="M85">
-  <obsolete>
-    Removed March 2020.
-  </obsolete>
-  <owner>msalama@chromium.org</owner>
-  <owner>chrome-signin-team@google.com</owner>
-  <summary>
-    Tracks the sWAA value we show to the user in chrome://settings/syncSetup for
-    sync users. This tracks as well the different states for which sWAA can be
-    off. This is recorded everytime the sWAA state is calculated/refreshed. Only
-    Desktop.
-  </summary>
-</histogram>
-
-<histogram name="Settings.TrackedPreferenceMigrated" enum="TrackedPreference"
-    expires_after="2014-07-29">
-  <obsolete>
-    Removed 2014-07.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logs the tracked preference id when it is migrated to the new MAC algorithm.
-    This should only happen once per pref per profile.
-  </summary>
-</histogram>
-
-<histogram name="Settings.TrackedPreferencesAlternateStoreVersion"
-    enum="PrefHashStoreVersion" expires_after="2014-06-14">
-  <obsolete>
-    Removed 2014-06.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The version of a PrefHashStore, reported once for each alternate
-    PrefHashStore (not associated to the default profile) from a delayed task on
-    startup.
-  </summary>
-</histogram>
-
-<histogram name="Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom"
-    enum="PrefHashStoreVersion" expires_after="2014-06-14">
-  <obsolete>
-    Removed 2014-06.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The previous version of an alternate PrefHashStore (not associated to the
-    default profile) that was updated from a delayed task on startup. This
-    should match Settings.TrackedPreferencesAlternateStoreVersion fairly closely
-    for all versions but VERSION_LATEST which should never be reported here.
-  </summary>
-</histogram>
-
-<histogram name="Settings.TrackedPreferencesInitializedForUnloadedProfile"
-    enum="BooleanHit" expires_after="2014-02-17">
-  <obsolete>
-    Removed 2014-02 in favor of
-    Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Preference tracking was initialized for an unloaded profile. This should
-    happen at most once per profile.
-  </summary>
-</histogram>
-
-<histogram name="Settings.TrackedSplitPreferenceChanged" units="units"
-    expires_after="M81">
-  <obsolete>
-    No longer used. Removed 2020-04.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The number of items that had changed in a dictionary pref when
-    Settings.TrackedPreferenceChanged is reported for that pref.
-  </summary>
-</histogram>
-
-<histogram name="Settings.ZoomLevelPreferencesMigrated" enum="BooleanMigrated"
-    expires_after="2015-08-21">
-  <obsolete>
-    Removed 2015-08-18.
-  </obsolete>
-  <owner>wjmaclean@chromium.org</owner>
-  <summary>
-    Tracks migration to per-partition zoom-level preferences during profile
-    initialization.
-  </summary>
-</histogram>
-
-<histogram name="SettingsAppMonitor.InitializationResult" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019. All signs indicate that it is exceptionally rare for
-    initialization to fail.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    Indicates whether or not the Windows Settings app monitor was initialized.
-  </summary>
-</histogram>
-
-<histogram name="SettingsPage.PrivacyElementInteractions"
-    enum="SettingsPrivacyElementInteractions" expires_after="M84">
-  <obsolete>
-    Removed 04/2020. Replaced with Settings.PrivacyElementInteractions to stick
-    to naming conventions.
-  </obsolete>
-  <owner>harrisonsean@chromium.org</owner>
-  <owner>msramek@chromium.org</owner>
-  <owner>sauski@chromium.org</owner>
-  <summary>
-    Which privacy related settings elements a user interacted with. Recorded
-    every time a user interacts with an element of interest.
-  </summary>
-</histogram>
-
-<histogram name="SettingsPage.SettingsPageInteractions"
-    enum="SettingsPageInteractions" expires_after="M83">
-  <obsolete>
-    Removed 03/2020. Recording too much duplicate data with route navigation
-    histogram (WebUI.Settings.PathVisited).
-  </obsolete>
-  <owner>harrisonsean@chromium.org</owner>
-  <owner>msramek@chromium.org</owner>
-  <summary>
-    Which settings a user interacted with. Recorded every time a user interacts
-    with a setting.
-  </summary>
-</histogram>
-
-<histogram name="SettingsResetPrompt.DelayBeforePromptParam" units="seconds"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019.
-  </obsolete>
-  <owner>alito@chromium.org</owner>
-  <summary>
-    The feature parameter determining the amount of time to wait after startup
-    before attempting to show the settings reset prompt. Logged once after
-    startup.
-  </summary>
-</histogram>
-
-<histogram name="SettingsResetPrompt.NumberOfExtensionsDisabled"
-    units="extensions" expires_after="2018-01-16">
-  <obsolete>
-    Removed on 2018-01-16.
-  </obsolete>
-  <owner>alito@chromium.org</owner>
-  <summary>
-    The number of extensions that were disabled after the user accepted the
-    settings reset prompt.
-  </summary>
-</histogram>
-
-<histogram name="SettingsResetPrompt.NumberOfExtensionsToDisable"
-    units="extensions" expires_after="2018-01-16">
-  <obsolete>
-    Removed on 2018-01-16.
-  </obsolete>
-  <owner>alito@chromium.org</owner>
-  <summary>
-    The number of extensions that will be disabled if the user accepts the
-    settings reset prompt. Logged once after startup.
-  </summary>
-</histogram>
-
-<histogram name="SettingsResetPrompt.TimeUntilDeclined" units="ms"
-    expires_after="2017-04-10">
-  <obsolete>
-    Removed in M59 in April 2017 and replaced by
-    SettingsResetPrompt.TimeUntilCanceled and
-    SettingsResetPrompt.TimeUntilDismissed.
-  </obsolete>
-  <owner>alito@chromium.org</owner>
-  <summary>
-    The time between the settings reset prompt dialog being shown and the user
-    declining the prompt.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.ApplyArchivePatchTime" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The elapesed time to apply a patch to a previous version's chrome.7z archive
-    to generate a new chrome.7z archive. This histogram only applies to diff
-    updates.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.CumulativeDiskUsage" units="MB"
-    expires_after="M82">
-  <obsolete>
-    Expired in M82, then replaced by Setup.Install.CumulativeDiskUsage2 on
-    06/2020.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The cumulative disk usage in MB during install or uninstall attempt,
-    recorded right after the install/uninstall attempt on windows only.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.DeleteAppHost" enum="BooleanDeletedOrNot"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-02
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    Hit following a successful install or update when the legacy
-    &quot;app_host.exe&quot; binary is deleted from the filesystem.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.HasArchivePatch" enum="Boolean"
-    expires_after="M82">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    True if the chrome.packed.7z archive contains a patch (in which case a diff
-    update is taking place) or false if it contains a full archive (in which
-    case a new install or a full update is taking place).
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.LzmaUnPackNTSTATUS" enum="NTSTATUS"
-    expires_after="M82">
-  <obsolete>
-    Removed 03/2020.
-  </obsolete>
-  <owner>zmin@chromium.org</owner>
-  <summary>
-    Record the NTSTATUS code of unpacking the contents of a 7z file.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Setup.Install.LzmaUnPackResult"
-    enum="WinGetLastError" expires_after="2021-03-06">
-  <obsolete>
-    Removed 03/2020.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <summary>
-    Record the return value of unpacking the contents of a 7z file.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.MultiChromeFrameRemoved"
-    enum="MultiChromeFrameRemovalResult" expires_after="M85">
-  <obsolete>
-    Removed 2020-02
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    Hit following a successful install or update when data from a legacy
-    multi-install Chrome Frame is deleted from the registry.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.NumDeleteOldVersionsAttemptsBeforeAbort"
-    units="Attempts" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Number of calls to DeleteOldVerions() made by a --delete-old-versions
-    process that didn't delete all files that belong to old versions of Chrome.
-    A --delete-old-versions process exits when another process tries to acquire
-    the SetupSingleton or after too many unsuccessful attempts to delete all old
-    files. A --delete-old-versions process that successfully acquires the
-    SetupSingleton records to either the
-    Setup.Install.NumDeleteOldVersionsAttemptsBeforeAbort histogram or the
-    Setup.Install.NumDeleteOldVersionsAttemptsBeforeSuccess histogram.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.NumDeleteOldVersionsAttemptsBeforeSuccess"
-    units="Attempts" expires_after="M77">
-  <obsolete>
-    Removed 06/2019. 50th percentile: 1.5. 75th percentile: 1.77. 99th
-    percentile: 2.75.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Number of calls to DeleteOldVersions() made by a --delete-old-versions
-    process that successfully deleted all files that belong to old versions of
-    Chrome. A --delete-old-versions process that successfully acquires the
-    SetupSingleton records to either the
-    Setup.Install.NumDeleteOldVersionsAttemptsBeforeAbort histogram or the
-    Setup.Install.NumDeleteOldVersionsAttemptsBeforeSuccess histogram.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.SingletonAcquisitionResult"
-    enum="SetupSingletonAcquisitionResult" expires_after="M77">
-  <obsolete>
-    Removed 06/2019 because it is not used.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The result of trying to acquire a setup singleton. On Windows, a setup.exe
-    process must hold the setup singleton of a Chrome installation when it makes
-    changes to it.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.StrandedChromeIsUsed" enum="BooleanUsage"
-    expires_after="2017-03-09">
-  <obsolete>
-    Removed 2017-01
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The disposition of a stranded Chrome install discovered while updating
-    multi-install Chrome Binaries. This metric is only logged in an edge case.
-    The buckets indicate whether or not the &quot;stranded&quot; Chrome install
-    has been used in the last 28 days. If so, it respresents a Chrome that has
-    not been updating due to a logic flaw in the installer and will be repaired
-    in the current update. If not, it likely represents Chrome Binaries that
-    were previously used by Chrome Frame that has since been uninstalled and
-    that will be uninstalled in a future update.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.UncompressArchivePatchTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The elapsed time to uncompress a chrome.7z patch. This histogram only
-    applies to diff updates.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.UncompressFullArchiveTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The elapsed time to uncompress a full chrome.7z archive. This histogram only
-    applies to new installs and to full updates.
-  </summary>
-</histogram>
-
-<histogram name="Setup.Install.UnpackFullArchiveTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The elapsed time to unpack the uncompressed chrome.7z archive. This
-    histogram applies to all installs and updates.
-  </summary>
-</histogram>
-
-<histogram name="SharedMemory.CreateError" enum="SharedMemoryCreateError"
-    expires_after="M81">
-  <obsolete>
-    Not accessed in months. Primary error was CREATE_FILE_MAPPING_FAILURE by
-    far. Removed 2020-03.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    A histogram entry is emitted each time a shared memory object is constructed
-    (for example, base::ReadOnlySharedMemoryRegion or the deprecated
-    base::SharedMemory). The value of the entry indicates the type of error
-    encountered during construction.
-  </summary>
-</histogram>
-
-<histogram name="SharedMemory.CreateMacError" enum="MachKernReturn"
-    expires_after="M85">
-  <obsolete>
-    Not accessed in months and no data reported for it at all. Removed 2020-03.
-  </obsolete>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Emitted each time a shared memory region could not be created due to a
-    failed Mac system call. The value of the entry indicates the return value of
-    the failed call.
-  </summary>
-</histogram>
-
-<histogram name="SharedMemory.CreateWinError" enum="WinGetLastError"
-    expires_after="M82">
-  <obsolete>
-    Not accessed in months. Primary error was #1455 by far. Removed 2020-03.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    A histogram entry is emitted each time a shared memory object could not be
-    created due to a failed Windows system call (for example,
-    base::ReadOnlySharedMemoryRegion or the deprecated base::SharedMemory). The
-    value of the entry indicates the result of the GetLastError() API call.
-  </summary>
-</histogram>
-
-<histogram name="SharedMemory.TimeSpentMakingAnonymousMemory" units="ms"
-    expires_after="2015-06-03">
-  <obsolete>
-    Removed 2015-06 because the Finch experiment SharedMemoryCreateStrategy has
-    finished running.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    The time spent making a new region of shared, anonymous memory. This metric
-    is not emitted if the shared memory region is read only.
-  </summary>
-</histogram>
-
-<histogram name="SharedWorker.RendererSurviveForWorkerTime" units="ms"
-    expires_after="2017-08-24">
-  <obsolete>
-    Replaced with BrowserRenderProcessHost.KeepAliveDuration as of Aug 2017.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    A survival time of RenderProcessHostImpl for the In-renderer Shared Worker
-    from when FastShutdownIfPossible() is called.
-  </summary>
-</histogram>
-
-<histogram name="SharedWorker.TimeToDeleted" units="ms" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The lifetime of a SharedWorkerHost. This roughly corresponds to the lifetime
-    of SharedWorker.
-  </summary>
-</histogram>
-
-<histogram name="SharedWorker.TimeToScriptLoaded" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time from the creation of SharedWorkerHost until when WorkerScriptLoaded
-    is called.
-  </summary>
-</histogram>
-
-<histogram name="SharedWorker.TimeToScriptLoadFailed" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>horo@chromium.org</owner>
-  <summary>
-    The time from the creation of SharedWorkerHost until when
-    WorkerScriptLoadFailed is called.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallContextMenuPhoneNumberParsingDelay"
-    units="microseconds" expires_after="M84">
-  <obsolete>
-    Removed in M84 after gathering enough data as a baseline.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Time taken to find a phone number in highlighted text for context menu.
-    Desktop only.
-
-    Note: This metric drops reports on clients with low-resolution clocks, which
-    means these reports will be biased against a portion of the population on
-    Windows. See Windows.HasHighResolutionTimeTicks for the affected sample.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallDialIntent" enum="BooleanEmpty"
-    expires_after="M81">
-  <obsolete>
-    Removed in M81 in favor of Sharing.ClickToCallDialerPresent
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Logged when a user taps a Click to Call notification and a dial intent is
-    fired to open the dialer. Distinguishes between empty string (no phone
-    number) and not empty. Android only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallHelpTextClicked" enum="SharingDialogType"
-    expires_after="M81">
-  <obsolete>
-    Removed in M81 as there was not a lot of usage of the help link.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Logged whenever a user clicks on the help text in a Click to Call dialog.
-    The value is used to distinguish which dialog type was shown. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallPhoneCall" units="ms" expires_after="M82">
-  <obsolete>
-    Removed in M82 after collecting enough data. See https://crbug.com/1053140.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    The time from opening the dialer until a phone call is initiated. This is
-    logged when we detect an outgoing phone call after opening the dialer as
-    part of the Click to Call feature. Android only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallPhoneNumberDigits" units="digits"
-    expires_after="M83">
-  <obsolete>
-    Removed in M82 as the experiment has been stopped.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="SharingClickToCallEntryPoint"
-       and name="SharingClickToCallSendToDevice" -->
-
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    The number of digits in a phone number. Logged when right clicking on a
-    selected phone number or tel link, showing the Click to Call dialog and when
-    selecting a device. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallPhoneNumberLength" units="characters"
-    expires_after="M83">
-  <obsolete>
-    Removed in M82 as the experiment has been stopped.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="SharingClickToCallEntryPoint"
-       and name="SharingClickToCallSendToDevice" -->
-
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    The number of characters in a phone number including digits and non-digits.
-    Logged when right clicking on a selected phone number or tel link, showing
-    the Click to Call dialog and when selecting a device. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallPhoneNumberRegexVariantResult"
-    enum="PhoneNumberRegexVariantResult" expires_after="M83">
-  <obsolete>
-    Removed in M82 as the experiment has been stopped.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="PhoneNumberRegexVariant"
-       and name="SharingClickToCallSendToDevice" -->
-
-  <owner>knollr@chromium.org</owner>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <summary>
-    The result of comparing a phone number regex variant against the simple
-    version. Logged after right clicking on a selection and when selecting a
-    device from the context menu. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.ClickToCallReceiveDeviceState"
-    enum="ClickToCallDeviceState" expires_after="M82">
-  <obsolete>
-    Removed in M82 after collecting enough data. See https://crbug.com/1053140.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    The device state when receiving a Click to Call message. Indicates if the
-    screen is on or off and if Chrome is running in foreground. Recorded when
-    handling a Click to Call message. Android only.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.DownloadQRCode.Failed.Time" units="ms"
-    expires_after="M87">
-  <obsolete>
-    Removed 06/2020. Never launched.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <owner>src/components/send_tab_to_self/OWNERS</owner>
-  <summary>
-    Records how long it took to the failed attempt to save the QR code image.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.DownloadQRCode.Succeeded.Time" units="ms"
-    expires_after="M87">
-  <obsolete>
-    Removed 06/2020. Never launched.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <owner>src/components/send_tab_to_self/OWNERS</owner>
-  <summary>
-    Records how long it took to successfully save the QR code image.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.SendAckMessageSuccess" enum="BooleanSuccess"
-    expires_after="M78">
-  <obsolete>
-    Replaced by SendAckMessageResult in M78.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Whether an ack message was sent successfully by the Sharing service. Logged
-    in the callback for sending the message to FCM. All platforms.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.SendMessageSuccess" enum="BooleanSuccess"
-    expires_after="M78">
-  <obsolete>
-    Replaced by SendMessageResult in M78.
-  </obsolete>
-  <owner>mvanouwerkerk@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Whether a SharingMessage was sent successfully by the Sharing service.
-    Success requires receiving an ack message before the timeout. Logged after
-    the send message callback is run. Not logged for sending ack messages. All
-    platforms.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.VapidKeyCreationResult"
-    enum="SharingVapidKeyCreationResult" expires_after="M85">
-  <obsolete>
-    Removed 2020-06 as the result is always successful.
-  </obsolete>
-  <owner>alexchau@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Result of Sharing VAPID key generation during registration. Logged after
-    Sharing VAPID key generation is attempted.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.AddIceCandidate" enum="BooleanSuccess"
-    expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Result of parsing received ice candidate. Logged when trying to add received
-    ice candidate.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.ConnectionErrorReason"
-    enum="SharingWebRtcConnectionErrorReason" expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Error reason for closing a WebRTC connection. Logged when a p2p WebRTC
-    connection is closed.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.ConnectionType"
-    enum="SharingWebRtcConnectionType" expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Type of routing used to establish a connection with a remote device. Logged
-    when a p2p connection is established using WebRTC by SharingService.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.OnMessageReceivedResult"
-    enum="SharingWebRtcOnMessageReceivedResult" expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Result of receiving and handling a message via WebRTC. Logged after
-    receiving a message from remote device via WebRTC.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.SendMessageResult"
-    enum="SharingWebRtcSendMessageResult" expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Result of sending a SharingMessage by SharingService via WebRTC. Logged
-    after sending the message.
-  </summary>
-</histogram>
-
-<histogram name="Sharing.WebRtc.Timeout" enum="SharingWebRtcTimeoutState"
-    expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    State of the WebRTC connection when it timed out. Logged when the connection
-    has been inactive for 30 seconds.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sharing.WebRtc.TimingEvents" units="ms"
-    expires_after="M88">
-  <obsolete>
-    Removed 2020-09 as the WebRTC experiment is shut down.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="SharingWebRtcTimingEventRole"
-       and name="SharingWebRtcTimingEvent" -->
-
-  <owner>himanshujaju@chromium.org</owner>
-  <owner>knollr@chromium.org</owner>
-  <summary>
-    Sharing WebRTC timing events logged during an active WebRTC connection.
-  </summary>
-</histogram>
-
-<histogram name="ShortcutsProvider.QueryIndexTime" units="ms"
-    expires_after="2020-09-19">
-  <obsolete>
-    Removed 09/11/2020 as it has been unused for a while with no expectation to
-    be used in the future.
-  </obsolete>
-  <owner>manukh@chromium.org</owner>
-  <owner>chrome-omnibox-team@google.com</owner>
-  <summary>
-    The time it takes for the ShortcutsProvider to perform a query after the
-    user has typed N characters.
-  </summary>
-</histogram>
-
-<histogram name="Shutdown.browser_exit.time" units="units"
-    expires_after="2016-10-11">
-  <obsolete>
-    Replaced by Shutdown.browser_exit.time2 to get more resolution into the tail
-    of the distribution (10/2016).
-  </obsolete>
-  <owner>hashimoto@chromium.org</owner>
-  <summary>
-    Time for shutdown initiated by the browser exit menu command.
-  </summary>
-</histogram>
-
-<histogram name="Shutdown.end_session.time" units="units"
-    expires_after="2016-10-11">
-  <obsolete>
-    Replaced by Shutdown.end_session.time2 to get more resolution into the tail
-    of the distribution (10/2016).
-  </obsolete>
-  <owner>hashimoto@chromium.org</owner>
-  <summary>
-    Time for shutdown initiated by an end session (user logs off, shuts down or
-    reboots without explicitly exiting).
-  </summary>
-</histogram>
-
-<histogram name="Shutdown.window_close.time" units="ms"
-    expires_after="2016-10-11">
-  <obsolete>
-    Replaced by Shutdown.window_close.time2 to get more resolution into the tail
-    of the distribution (10/2016).
-  </obsolete>
-  <owner>hashimoto@chromium.org</owner>
-  <summary>
-    Time for shutdown initiated by the last browser window being closed.
-  </summary>
-</histogram>
-
-<histogram name="SignedExchange.LoadResult" enum="SignedExchangeLoadResult"
-    expires_after="2019-09-20">
-  <obsolete>
-    Removed 2/2019 in favor of SignedExchange.LoadResult2.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Records the result of loading a resource from Signed HTTP Exchange. Emitted
-    each time a response is handled as Signed Exchange.
-  </summary>
-</histogram>
-
-<histogram name="SignedExchange.Prefetch.LoadResult"
-    enum="SignedExchangeLoadResult" expires_after="2019-10-11">
-  <obsolete>
-    Removed 2/2019 in favor of SignedExchange.Prefetch.LoadResult2.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Records if the prefetched Signed Exchange was properly formatted and passed
-    verification steps. Reported for each completed SignedExchange prefetch.
-  </summary>
-</histogram>
-
-<histogram name="Signin.AccountTracker.DeprecatedServiceFlagDeleted"
-    enum="BooleanDeletedOrNot" expires_after="2019-05-30">
-  <obsolete>
-    Instrumentation code has been removed as the conversion has been completed.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>sdefresne@chromium.org</owner>
-  <summary>
-    This histogram records the removal of the ServiceState property from the
-    identities known to the AccountTracker. It records whether the deprecated
-    flag was found in the loaded data and had to be deleted.
-
-    This histogram will be used to check whether the migration has completed for
-    all active installs on a given platform or not (and whether the code can be
-    removed).
-
-    This is recorded on each profile load.
-  </summary>
-</histogram>
-
-<histogram name="Signin.AddAccount" enum="BooleanSuccess" expires_after="M80">
-  <obsolete>
-    Removed 2019-07 as it was never used by the sign-in team.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Track when chrome successfully adds an account. Failures are not tracked.
-  </summary>
-</histogram>
-
-<histogram name="Signin.AndroidSigninPromoAction"
-    enum="AndroidSigninPromoAction" expires_after="2016-05-12">
-  <obsolete>
-    Removed this histogram since we have had newly designed histograms
-    Signin.SigninStartedAccessPoint, Signin.SigninCompletedAccessPoint, and
-    Signin.SigninReason.
-  </obsolete>
-  <owner>guohui@chromium.org</owner>
-  <summary>Track how a user interfacts with the android signin promo.</summary>
-</histogram>
-
-<histogram name="Signin.AndroidTimeBetweenUpdateAccountList" units="ms"
-    expires_after="2020-03-14">
-  <obsolete>
-    Removed on 2020-03 as it is not needed by the signin team.
-  </obsolete>
-  <owner>bsazonov@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Duration of time between UpdateAccountList calls. Recorded when
-    OAuth2TokenServiceDelegateAndroid::UpdateAccountList completes.
-  </summary>
-</histogram>
-
-<histogram name="Signin.ChromePrimaryAccountStateOnWebSignout"
-    enum="ChromePrimaryAccountStateInGaiaCookies" expires_after="M80">
-  <obsolete>
-    Removed 2019-09. No longer useful after Dice is launched.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Logs the state of the Chrome account when the user signs out on the web.
-    This assumes that a logout of the web is always a complete logout of all the
-    web accounts (e.g. single session signout is not supported).
-  </summary>
-</histogram>
-
-<histogram name="Signin.DiceEnabledForProfile" enum="Boolean"
-    expires_after="2017-11-10">
-  <obsolete>
-    Replaced by Signin.DiceMigrationStatus. Does not have any meaningful
-    information.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Whether Dice is enabled for the current profile, recorded at startup.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Signin.DiceMigrationNotReady.Reason"
-    enum="AccountReconcilorInconsistencyReason" expires_after="2020-04-19">
-  <obsolete>
-    Removed M80. Dice migration is complete.
-  </obsolete>
-  <owner>msalama@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Tracks the reason of why DICE migration is not ready. It is computed by Dice
-    reconcilor delegate on every reconciliation cycle.
-  </summary>
-</histogram>
-
-<histogram name="Signin.DiceMigrationStatus" enum="SigninDiceMigrationStatus"
-    expires_after="2020-04-19">
-  <obsolete>
-    Removed 03/2020, as it was equivalent to Signin.SigninAllowed.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    The Dice migration status, recorded at startup for each profile.
-  </summary>
-</histogram>
-
-<histogram name="Signin.DuringFirstRun" enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed M77 in favor of Signin.SigninCompletedAccessPoint
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Track if the profile sign in took place during First Run or not. Logged at
-    signin time. True means signin took place during First Run, False means
-    anytime after.
-  </summary>
-</histogram>
-
-<histogram name="Signin.ElapsedTimeFromInstallToSignin" units="minutes"
-    expires_after="M77">
-  <obsolete>
-    Removed M77 as not relevant.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Track how many minutes of local system time elapsed from when Chrome was
-    installed to when Signin occured for this profile.
-  </summary>
-</histogram>
-
-<histogram name="Signin.MultiloginFinished" enum="GoogleServiceAuthError"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed in M76. Use Signin.OAuthMultiloginResponseStatus instead.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Reconds finished calls to Gaia Multilogin endpoint, both successful or not,
-    and return the GoogleAuthError state NONE is a success, other values are
-    failures.
-  </summary>
-</histogram>
-
-<histogram name="Signin.MultiloginRetry" enum="GoogleServiceAuthError"
-    expires_after="2019-11-01">
-  <obsolete>
-    Removed in M76, because multilogin switched to a new error type.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Retry reason of failed Multilogin call during Chrome reconcile.
-  </summary>
-</histogram>
-
-<histogram name="Signin.OAuth2TokenGetFailure" enum="GoogleServiceAuthError"
-    expires_after="2020-04-19">
-  <obsolete>
-    Replaced on 2020-04 by Signin.OAuth2TokenGetResult.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Reason fetching an OAuth2 Token failed. Available on all OSes.
-  </summary>
-</histogram>
-
-<histogram name="Signin.Reconciler.AddedToChrome" units="units"
-    expires_after="2014-09-25">
-  <obsolete>
-    Removed 2014-09 because chrome no longer tries to reconcile from the cookie
-    jar to the browser.
-  </obsolete>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    How many accounts were added to the browser's token service because they
-    were in the cookie jar.
-  </summary>
-</histogram>
-
-<histogram name="Signin.Reconciler.Duration" units="units"
-    expires_after="2019-04-05">
-  <obsolete>
-    Removed in favor of Signin.Reconciler.Duration.UpTo3mins.
-  </obsolete>
-  <owner>rogerta@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>Records the execution time of the account reconciler.</summary>
-</histogram>
-
-<histogram name="Signin.RefreshTokenAnnotationRequest" enum="BooleanSuccess"
-    expires_after="2018-01-12">
-  <obsolete>
-    Removed this histogram along with the code that was logging it.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>
-    Track when chrome successfully sends RefreshTokenAnnotationRequest.
-  </summary>
-</histogram>
-
-<histogram name="Signin.RequestHeaderOperation.Dice"
-    enum="SigninRequestHeaderOperation" expires_after="M77">
-  <obsolete>
-    Removed 2019-07, replaced with a log message.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Tracks when Chrome adds or removes the Desktop Identity Consistency HTTP
-    header to Gaia.
-  </summary>
-</histogram>
-
-<histogram name="Signin.RequestHeaderOperation.Mirror"
-    enum="SigninRequestHeaderOperation" expires_after="M77">
-  <obsolete>
-    Removed 2019-07, replaced with a log message.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Tracks when Chrome adds or removes the the X-Chrome-Connected HTTP header to
-    Gaia.
-  </summary>
-</histogram>
-
-<histogram name="Signin.SignedInDurationBeforeSignout" units="minutes"
-    expires_after="M77">
-  <obsolete>
-    Removed in 7/2019 as the information it provides is no longer useful.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Track how many minutes of real time (not browser active time) elapsed
-    between profile signin and signout.
-  </summary>
-</histogram>
-
-<histogram name="Signin.SigninSource" enum="SigninSource"
-    expires_after="2015-12-07">
-  <obsolete>
-    Removed this histogram since we have had newly designed histograms
-    Signin.SigninStartedAccessPoint, Signin.SigninCompletedAccessPoint, and
-    Signin.SigninReason.
-  </obsolete>
-  <owner>noms@chromium.org</owner>
-  <summary>
-    Logs the original source that displayed the signin or reauth Gaia page,
-    before the page is displayed.
-  </summary>
-</histogram>
-
-<histogram name="Signin.SwitchSyncAccount.Source"
-    enum="SigninSwitchSyncAccountSource" expires_after="M77">
-  <obsolete>
-    Obsolete after Unified Consent launch.
-  </obsolete>
-  <owner>bsazonov@chromium.org</owner>
-  <summary>
-    Tracks the usage of different flows that switch sync accounts. Logged after
-    accounts have been switched.
-  </summary>
-</histogram>
-
-<histogram name="Signin.TokenServiceDiceCompatible" enum="Boolean"
-    expires_after="M80">
-  <obsolete>
-    Removed M80. Obsolete after Dice migration completed.
-  </obsolete>
-  <owner>msalama@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    Tracks the state of kTokenServiceDiceCompatible preference. This is recorded
-    at every startup, if the account consistency method is in Dice migration and
-    is not ready yet to migrate to Dice.
-  </summary>
-</histogram>
-
-<histogram name="Signin.TokenStateTransition" enum="SigninTokenStateTransition"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-09. Obsolete after Dice is launched.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    Tracks the changes of refresh token states for all accounts. Tokens can have
-    three states: Regular (retrieved from Gaia), Invalid (created by Chrome and
-    known to be invalid) or None (no token). Recorded when a token is loaded or
-    changed.
-  </summary>
-</histogram>
-
-<histogram name="Signin.XDevicePromo.BrowsingSessionDuration" units="minutes"
-    expires_after="2019-02-12">
-  <obsolete>
-    Obsolete because the XDevicePromo never shipped.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    How long a browsing session was measured to be. Logged when a Browser window
-    becomes active if the previous activation was longer than the minimum
-    configured in the &quot;CrossDevicePromo&quot; experiment. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Signin.XDevicePromo.BrowsingSessionDurationComputed"
-    units="minutes" expires_after="2019-02-12">
-  <obsolete>
-    Obsolete because the XDevicePromo never shipped.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    How often browsers are considered activated, which in turn triggers the
-    CrossDevicePromo. Logged every time a Browser window becomes active. We need
-    this to estimate QPS for RPC calls. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Signin.XDevicePromo.Eligibility"
-    enum="SigninXDevicePromoEligibility" expires_after="2019-02-12">
-  <obsolete>
-    Obsolete because the XDevicePromo never shipped.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    The reasons for which a profile is or is not eligible for the Desktop Cross
-    Device Sign In Promo. Logged every time a new Browsing session is detected
-    as part of a Browser window becoming active. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Signin.XDevicePromo.Initialized"
-    enum="SigninXDevicePromoInitialized" expires_after="2019-02-12">
-  <obsolete>
-    Obsolete because the XDevicePromo never shipped.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <owner>mlerman@chromium.org</owner>
-  <summary>
-    Tracks if profiles initialized the XDevicePromo, and if not, why. Logged at
-    Profile startup and (if not initialized then) when a new browsing session is
-    detected during Browser window activation. Desktop only.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.DiskOpenStream2NonTinyLatency"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed 2020-08.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The time to open the stream 2 file successfully on disk cache entry open
-    with known key, when the size of payload is greater than 32 bytes.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.DiskOpenStream2TinyLatency" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-08.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The time to open the stream 2 file successfully on disk cache entry open
-    with known key, when the size of payload is 32 bytes or less.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.EntryCreatedAndStream2Omitted"
-    enum="SimpleCache.EntryCreatedAndStream2Omitted" expires_after="2018-02-08">
-  <obsolete>
-    Removed 2018-02. Not creating stream 2 on CreateEntry entries is indeed a
-    good idea, since stream 2 writes are done on things opened with OpenEntry.
-    (Which also means this metric wasn't good at evaluating the prevalence of
-    stream 2 in general).
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Whether, upon creation of a new cache entry, the file for stream 2 was
-    omitted since that stream was empty.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.EntryCreationResult"
-    enum="BooleanSuccess" expires_after="M85">
-  <obsolete>
-    Removed 2020-08. Look at SyncOpenResult and SyncCreateResult.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For entry creation operations that were sent to the disk, the result of
-    creation.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.EntryOpenedAndStream2Removed"
-    enum="SimpleCache.EntryOpenedAndStream2Removed" expires_after="M85">
-  <obsolete>
-    Removed 2020-08-17
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Whether, upon opening of an existing cache entry, stream 2 was empty and the
-    file for that stream was therefore removed.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.EntryOperationsPending" units="units"
-    expires_after="2019-03-12">
-  <obsolete>
-    Removed 2019-03.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    At the time that operations are run, the number of pending operations on a
-    particular entry.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.EntryTrailerSize" units="bytes"
-    expires_after="2020-05-27">
-  <obsolete>
-    Removed 2020-05 due to excessive quantities of data.
-  </obsolete>
-  <owner>wanderview@chromium.org</owner>
-  <summary>
-    The number of bytes read at the end of the entry file in order to process
-    the EOF footer and the stream 0 data.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.Eviction.CacheSizeOnStart" units="bytes"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 2013 in favour of SimpleCache.Eviction.CacheSizeOnStart2
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The size of the cache at the beginning of an eviction.</summary>
-</histogram>
-
-<histogram name="SimpleCache.Eviction.MaxCacheSizeOnStart" units="bytes"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 2013 in favour of SimpleCache.Eviction.MaxCacheSizeOnStart2
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The maximum allowed size of the cache at the beginning of an eviction.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.Eviction.SizeOfEvicted" units="bytes"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 2013 in favour of SimpleCache.Eviction.SizeOfEvicted2
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The number of bytes to be erased in an eviction.</summary>
-</histogram>
-
-<histogram name="SimpleCache.Eviction.SizeWhenDone" units="bytes"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 2013 in favour of SimpleCache.Eviction.SizeWhenDone2
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The size of the cache after running an eviction.</summary>
-</histogram>
-
-<histogram name="SimpleCache.FileDescriptorLimitHard" units="file descriptors"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-07-03
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The maximum limit of how many file descriptors a process can open. Emitted
-    each time the browser is launched, if the limit could be retrieved. (This is
-    the highest value we could raise the current limit to if we liked.)
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.FileDescriptorLimitSoft" units="file descriptors"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-07-03. Consider Memory.Browser.OpenFDsSoftLimit for similar
-    information.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The current limit of how many file descriptors a process can open. Emitted
-    each time the browser is launched, if the limit could be retrieved. (We can
-    raise this to the maximum limit if we like, without root access.)
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.FileDescriptorLimitStatus"
-    enum="SimpleCache.FileDescriptorLimitStatus" expires_after="M77">
-  <obsolete>
-    Removed 2019-07-03
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The result of trying to get the file descriptor limit. Emitted each time the
-    browser is launched.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.GlobalOpenEntryCount" units="units"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-07-03.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The number of open entries across all caches backed by the Simple Cache. An
-    entry is opened whenever a caller asks to open it to read or write cache
-    data, and remains open until the last caller asks to close it. Logged
-    whenever an entry is opened or closed.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.HeaderSizeChange"
-    enum="SimpleCacheHeaderSizeChange" expires_after="2018-06-06">
-  <obsolete>
-    Removed 2018-06-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    How the header size has changed in a Simple Cache entry, emitted every time
-    a write operation occurs on the header stream. (This includes the initial
-    write, rewrites, and other writes that we couldn't classify.)
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.HeaderSizeDecreaseAbsolute"
-    units="bytes" expires_after="2018-06-06">
-  <obsolete>
-    Removed 2018-06-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The absolute size decrease of the header stream of a Simple Cache entry,
-    emitted every time the headers are rewritten with a smaller size.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.HeaderSizeDecreasePercentage"
-    units="%" expires_after="2018-06-06">
-  <obsolete>
-    Removed 2018-06-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The relative size decrease of the header stream of a Simple Cache entry,
-    emitted every time the headers are rewritten with a smaller size.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.HeaderSizeIncreaseAbsolute"
-    units="bytes" expires_after="2018-06-06">
-  <obsolete>
-    Removed 2018-06-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The absolute size increase of the header stream of a Simple Cache entry,
-    emitted every time the headers are rewritten with a larger size.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.HeaderSizeIncreasePercentage"
-    units="%" expires_after="2018-06-06">
-  <obsolete>
-    Removed 2018-06-05
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The relative size increase of the header stream of a Simple Cache entry,
-    emitted every time the headers are rewritten with a larger size.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexCorrupt" enum="BooleanCorrupt"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85, but code was missing at that point already.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>For each index load, whether the index file was corrupt.</summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexEntriesLoaded" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>Number of entries loaded from the index file on start.</summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexEntriesRestored" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Number of entries restored from disk when there was no index or the index
-    was corrupted.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexInitializationWaiters"
-    units="units" expires_after="M85">
-  <obsolete>
-    Removed in M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    At the time of index initialization, the number of enqueued jobs awaiting
-    index initialization.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexLoadTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85, but didn't actually work before that.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Time (as measured on the worker pool) spent loading the index file.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.IndexStale" enum="BooleanStale"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 07/2013, and replaced by IndexFileStateOnLoad.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>For each index load, whether the index file was stale.</summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexWriteInterval.Background"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The interval between index saves, for apps in the background.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexWriteInterval.Foreground"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The interval between index saves, for apps in the foreground.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.IndexWriteToDiskTime" units="ms"
-    expires_after="2015-09-22">
-  <obsolete>
-    Removed 2013-05 in favour of
-    SimpleCache.SimpleIndexWriteToDiskTime.Background and
-    SimpleCache.SimpleIndexWriteToDiskTime.Foreground.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The amount of time spend writing the index file to disk, measured starting
-    at the beginning of the write on the callback thread, and calculated using
-    the completion time on the worker pool.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexWriteToDiskTime.Background"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed in M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The amount of time spend writing the index file to disk, for apps in the
-    background, measured starting at the beginning of the write on the callback
-    thread, and calculated using the completion time on the worker pool.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.IndexWriteToDiskTime.Foreground"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed in M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The amount of time spend writing the index file to disk, for apps in the
-    foreground, measured starting at the beginning of the write on the callback
-    thread, and calculated using the completion time on the worker pool.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.KeyMatchedOnOpen" enum="BooleanMatched"
-    expires_after="2016-05-20">
-  <obsolete>
-    Removed 2016-05 as the match checking was moved back into the entry itself,
-    so this result is now reported in the SimpleCache.x.SyncOpenResult
-    histograms.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For each call to OpenEntry, whether the key on disk matched the request key.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.LastClusterLossPercent" units="%"
-    expires_after="2018-01-23">
-  <obsolete>
-    Removed 2018-01; not viewed as actionable.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For each file in the Simple Cache, the percentage of disk space used by the
-    cluster loss, the unused disk space in the last 4096 byte cluster of the
-    file.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.LastClusterSize" units="bytes"
-    expires_after="2018-01-23">
-  <obsolete>
-    Removed 2018-01; not viewed as actionable.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For each file in the Simple Cache, the number of bytes in the last 4096 byte
-    cluster when the entry is saved to disk.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.NumOpsBlockedByPendingDoom"
-    units="Ops" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Number of operations that were queued behind a particular doom operation
-    (with a mass doom counting as a single operation).
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.QueueLatency.CreateEntry" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Delay between when the I/O portion of CreateEntry is enqueued and when its
-    execution begins.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.QueueLatency.OpenEntry" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Delay between when the I/O portion of OpenEntry is enqueued and when its
-    execution begins.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.QueueLatency.OpenOrCreateEntry"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <owner>bingler@chromium.org</owner>
-  <summary>
-    Delay between when the I/O portion of OpenOrCreateEntry is enqueued and when
-    its execution begins.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.QueueLatency.PendingDoom" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Delay between when an operation is deferred due to a pending doom for its
-    key, and when it can resume execution.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.ReadIsParallelizable"
-    enum="SimpleCacheReadParallelizable" expires_after="2018-07-17">
-  <obsolete>
-    Removed 2018-07-02. See https://crrev.com/c/1122706
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For each Read operation, whether it could have been issued in parallel of a
-    previous Read operation.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.ReadResult"
-    enum="SimpleCacheReadResult" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The outcome of Entry::ReadData in the simple cache.</summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.ReadStream1FromPrefetched"
-    enum="Boolean" expires_after="M85">
-  <obsolete>
-    Removed pre-M85
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Whether a read from stream 1 (conventionally used for payload body) was
-    satisfied from prefetched data. Reported only on the first read operation on
-    the stream (including if there are multiple readers, or even some writers).
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.SyncCheckEOFHasCrc"
-    enum="BooleanHasCrc" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    For each EOFRecord found with a valid magic number, indicates if the record
-    also contains a CRC.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.SyncCreateResult"
-    enum="SimpleCacheSyncCreateResult" expires_after="M85">
-  <obsolete>
-    Removed pre-M85. Consider SyncCreatePlatformFileError
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The result, at the synchronous layer, reported when attempting to create a
-    new cache entry.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.SyncKeySHA256Result"
-    enum="SimpleCacheSyncSHA256Result" expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The result of the the key SHA256 check done when opening stream 0 for each
-    entry.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.SyncOpenDidPrefetch" enum="Boolean"
-    expires_after="2019-01-04">
-  <obsolete>
-    Replaced Dec, 2018 by SimpleCache.SyncOpenPrefetchMode. The new histogram is
-    an enumeration that can distinguish between full file prefetching from
-    trailer prefetching.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Whether an attempt was made to prefetch the entire file when executing
-    disk_cache::Backend::OpenEntry.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.SyncOpenEntryAge" units="hours"
-    expires_after="M85">
-  <obsolete>
-    Removed pre-M85.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    The age of the entry (time since last modified), when opened at the
-    synchronous layer.
-  </summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.WriteDependencyType"
-    enum="SimpleCacheWriteDependencyType" expires_after="2018-07-17">
-  <obsolete>
-    Removed 2018-07-02. See https://crrev.com/c/1122706
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>
-    Shows whether a write operation depends on the previous operation in queue
-    particularly in the aspect of its possibility to run in parallel.
-  </summary>
-</histogram>
-
-<histogram name="SimpleCache.WriteResult" enum="SimpleCacheWriteResult"
-    expires_after="2013-09-02">
-  <obsolete>
-    Replaced 2013/09/03 by WriteResult2, which adds &quot;fast empty
-    return&quot;, which previously showed up as &quot;success&quot;.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The outcome of Entry::WriteData in the simple cache.</summary>
-</histogram>
-
-<histogram base="true" name="SimpleCache.WriteResult2"
-    enum="SimpleCacheWriteResult" expires_after="M85">
-  <obsolete>
-    Removed pre-M85. SyncWriteResult may be of interest.
-  </obsolete>
-  <owner>morlovich@chromium.org</owner>
-  <summary>The outcome of Entry::WriteData in the simple cache.</summary>
-</histogram>
-
-<histogram name="SingleThreadedCompositorLatency" units="microseconds"
-    expires_after="2020-08-31">
-  <obsolete>
-    Removed on 9/2019: metric is not monitored for the UI compositor.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Tracks the duration of stages in the pipeline while processing a single
-    frame on the single thread compositor, where the Main frame did not miss its
-    deadline.
-
-    A Main frame that missed its deadline is a frame such that
-    SubmitCompositorFrame happened before a commit and activation happened. E.g.
-    BeginImplFrame1 -&gt; BeginMainFrame1 -&gt; SubmitCompositorFrame -&gt;
-    BeginImplFrame2 -&gt; Commit1 -&gt; Activate1 -&gt; SubmitCompositorFrame
-  </summary>
-</histogram>
-
-<histogram name="SingleThreadedCompositorLatency.MissedFrame"
-    units="microseconds" expires_after="2020-08-31">
-  <obsolete>
-    Removed on 9/2019: metric is not monitored for the UI compositor.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Tracks the duration of stages in the pipeline while processing a single
-    frame on the single thread compositor, where the Main frame missed its
-    deadline.
-
-    A Main frame that missed its deadline is a frame such that
-    SubmitCompositorFrame happened before a commit and activation happened. E.g.
-    BeginImplFrame1 -&gt; BeginMainFrame1 -&gt; SubmitCompositorFrame -&gt;
-    BeginImplFrame2 -&gt; Commit1 -&gt; Activate1 -&gt; SubmitCompositorFrame
-  </summary>
-</histogram>
-
-<histogram name="SingleThreadedCompositorLatency.MissedFrameLatencyIncrease"
-    units="microseconds" expires_after="2020-08-31">
-  <obsolete>
-    Removed on 9/2019. Did not provide enough information about latency.
-  </obsolete>
-  <owner>sadrul@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    The latency increase of an abnormally long activation stage on the single
-    thread compositor pipeline when the frame is missed.
-
-    These latency increases are determined by comparing the stage duration to
-    the times from past non-missed frames. These times are also reported to
-    &quot;SingleThreadedCompositorLatency.MissedFrame.&lt;StageName&gt;&quot;
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.EngagementPercentageForHTTPS"
-    units="units" expires_after="2017-04-18">
-  <obsolete>
-    Removed in M60. See crbug.com/712493.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    The percentage of total site engagement accumulated by this profile for
-    HTTPS URLs as a proportion of all engagement for HTTPS and HTTP URLs.
-    Recorded at startup per non-incognito profile, and then upon the first
-    engagement-increasing event every hour thereafter.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.EngagementScore.HTTP" units="units"
-    expires_after="2017-04-18">
-  <obsolete>
-    Removed in M60. See crbug.com/712493.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Distribution of the engagement scores accumulated by a user, recorded at
-    startup per non-incognito profile, and then upon the first
-    engagement-increasing event every hour thereafter. Limited specifically to
-    HTTP URLs.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.EngagementScore.HTTPS" units="units"
-    expires_after="2017-04-18">
-  <obsolete>
-    Removed in M60. See crbug.com/712493.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Distribution of the engagement scores accumulated by a user, recorded at
-    startup per non-incognito profile, and then upon the first
-    engagement-increasing event every hour thereafter. Limited specifically to
-    HTTPS URLs.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.EngagementScore.IsZero" enum="Boolean"
-    expires_after="M81">
-  <obsolete>
-    Removed in M81.
-  </obsolete>
-  <owner>charleszhao@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <owner>kcarattini@chromium.org</owner>
-  <summary>
-    The distribution of zero versus non-zero engagement scores accumulated by
-    the user, recorded at the same time as
-    SiteEngagementService.EngagementScore.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.PercentOriginsWithMaxEngagement"
-    units="units" expires_after="2020-06-01">
-  <obsolete>
-    Removed in M81.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    The percentage of all origins recorded by the site engagement service which
-    have reached the absolute site engagement point cap, recorded at startup per
-    non-incognito profile, and then upon the first engagement-increasing event
-    every hour thereafter.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.ScoreDecayedFrom"
-    units="engagement score" expires_after="2020-06-01">
-  <obsolete>
-    Removed in M81.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    The site engagement score of an origin prior to applying decay. Recorded at
-    the first engagement event after decay, independently per decay event.
-  </summary>
-</histogram>
-
-<histogram name="SiteEngagementService.ScoreDecayedTo" units="engagement score"
-    expires_after="M81">
-  <obsolete>
-    Removed in M81.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    The site engagement score of an origin once decay has occured. Recorded at
-    the first engagement event after decay, independently per decay event.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolatedCodeCache.Behaviour" units="units"
-    expires_after="2018-10-10">
-  <obsolete>
-    Split this histogram into SiteIsolatedCodeCache.JS.Behaviour and
-    SiteIsolatedCodeCache.WASM.Behaviour to collect statistics for JS and WASM
-    code caches in separate histograms.
-  </obsolete>
-  <owner>mythria@chromium.org</owner>
-  <summary>
-    The behaviour of site isolated javascript code cache recorded for each cache
-    transaction. It records if the request was serviced and if serviced how it
-    was serviced for ex: hit, miss, update.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.AllResponses" units="units" expires_after="M80">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of all network responses received by a renderer. Each response is
-    corresponding to one URL requested by a renderer. Incremented when the first
-    network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.CurrentRendererProcessCount" units="units"
-    expires_after="2020-04-19">
-  <obsolete>
-    Deprecated in March 2020; see Memory.RenderProcessHost.Count.* instead.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The count of all renderer processes, including WebUI and extensions.
-    Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.Flags.IsolateOrigins" enum="BooleanEnabled"
-    expires_after="M82">
-  <obsolete>
-    Deprecated in March 2020. For about:flags usage, see Launch.FlagsAtStartup.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    True if the --isolate-origins mode was enabled from the command line,
-    about:flags, or enterprise policy. Recorded on browser startup and then once
-    every 24 hours.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.Flags.SitePerProcess" enum="BooleanEnabled"
-    expires_after="M82">
-  <obsolete>
-    Deprecated in March 2020. For about:flags usage, see Launch.FlagsAtStartup.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    True if the --site-per-process mode was enabled from the command line,
-    about:flags, or enterprise policy. Recorded on browser startup and then once
-    every 24 hours.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateAllSitesProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since site-per-process has already shipped on desktop in M67 (see
-    https://crbug.com/810843).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The upper bound of the predicted renderer process count if we isolated all
-    sites, subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateAllSitesProcessCountLowerBound"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since site-per-process has already shipped on desktop in M67 (see
-    https://crbug.com/810843).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The lower bound of the predicted renderer process count if we isolated all
-    sites, subject to the process limit. Happens to be the number of unique
-    sites. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateAllSitesProcessCountNoLimit"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since site-per-process has already shipped on desktop in M67 (see
-    https://crbug.com/810843).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The predicted renderer process count if we isolated all sites and if there
-    were no process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateAllSitesTotalProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since site-per-process has already shipped on desktop in M67 (see
-    https://crbug.com/810843).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The predicted total process count if we isolated all sites, subject to the
-    process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateExtensionsProcessCountEstimate"
-    units="units" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since isolate-extensions has already shipped in M56 (see
-    https://crbug.com/545200).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The upper bound of the predicted renderer process count if we isolated only
-    Chrome extensions, subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateExtensionsProcessCountLowerBound"
-    units="units" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since isolate-extensions has already shipped in M56 (see
-    https://crbug.com/545200).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The lower bound of the predicted renderer process count if we isolated only
-    Chrome extensions, subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateExtensionsProcessCountNoLimit"
-    units="units" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since isolate-extensions has already shipped in M56 (see
-    https://crbug.com/545200).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted renderer process count if we isolated only Chrome extensions
-    and if there were no process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateExtensionsTotalProcessCountEstimate"
-    units="units" expires_after="M77">
-  <obsolete>
-    Logging code has been removed in M77 - the histogram is no longer useful
-    since isolate-extensions has already shipped in M56 (see
-    https://crbug.com/545200).
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted total process count if we isolated only Chrome extensions,
-    subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateHttpsSitesProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The upper bound of the predicted renderer process count if we isolated only
-    HTTPS (not HTTP) sites, subject to the process limit. Recorded once per UMA
-    ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The lower bound of the predicted renderer process count if we isolated only
-    HTTPS (not HTTP) sites, subject to the process limit. Happens to be the
-    number of isolated sites. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted renderer process count if we isolated only HTTPS (not HTTP)
-    sites and if there were no process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted total process count if we isolated only HTTPS (not HTTP)
-    sites, subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateNothingProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The upper bound of the estimated renderer process count if we isolated no
-    sites, subject to the process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateNothingProcessCountLowerBound"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The lower bound of the predicted renderer process count if we isolated no
-    sites, subject to the process limit. Happens to be the number of isolated
-    sites. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateNothingProcessCountNoLimit" units="units"
-    expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted renderer process count if we isolated no sites and if there
-    were no process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateNothingTotalProcessCountEstimate"
-    units="units" expires_after="M82">
-  <obsolete>
-    Logging code has been removed in M77.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <owner>site-isolation-dev@chromium.org</owner>
-  <summary>
-    The predicted total process count if we isolated no sites, subject to the
-    process limit. Recorded once per UMA ping.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.IsolateOrigins.Size" units="origins"
-    expires_after="M82">
-  <obsolete>
-    Deprecated in March 2020.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <summary>
-    The number of currently enabled isolated origins. This includes origins
-    specified via the --isolate-origins command-line flag as well as those
-    configured via enterprise policy. Recorded on browser startup.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.LowMemoryMode.Transition" enum="BooleanEnabled"
-    expires_after="M85">
-  <obsolete>
-    Code deleted in June 2020.
-  </obsolete>
-  <owner>rsesek@chromium.org</owner>
-  <summary>
-    The number of times a render process transitions its main thread isolate
-    into or out of memory savings mode. This is recorded per-renderer-process
-    upon the creation of the first main frame or the destruction of the last
-    main frame.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.PendingSitelessNavigationDisallowsProcessReuse"
-    enum="BooleanProcessReuseDisallowed" expires_after="M82">
-  <obsolete>
-    Deprecated in March 2020.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    Whether or not the RenderProcessHost is disqualified from process reuse
-    because it has a pending navigation to a URL for which SiteInstance does not
-    assign a site URL, such as chrome-native://newtab. This is intended to
-    measure how often this scenario results in spinning up extra processes.
-    Measured once per IsSuitableHost() invocation.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Browser.Allowed.ContentScript"
-    enum="ContentResourceType2" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data have been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The total count of responses that were would be blocked by the cross-site
-    document blocking logic in the browser process, but were only allowed
-    because the request was initiated by a content script of an extension.
-    Recorded with a resource type (0-17) when the response is allowed.
-
-    Note that this histogram is not reimplemented in the NetworkService version
-    of Cross-Origin Read Blocking feature. This should be okay since we hope to
-    gather enough data before NetworkService ships.
-  </summary>
-</histogram>
-
-<histogram
-    name="SiteIsolation.XSD.Browser.AllowedByCorbButNotCors.ContentScript"
-    enum="BooleanRisk" expires_after="M87">
-  <obsolete>
-    Removed in September 2020 / M87. (It was not needed anymore, since
-    CORS-for-content-scripts has successfully shipped in M85.)
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    Logs an upper bound of how many new content script requests might be blocked
-    if we start making them subject to CORS. We haven't yet started passing
-    Origin headers on these requests, so this will report true/risky even if in
-    the future the server might respond with a valid Access-Control-Allow-Origin
-    header when presented with an expected Origin request header.
-
-    Logged when 1) CORB processes a http response (so excluding requests from
-    allowlisted content script and requests from extension background pages
-    where CORB is disabled) and 2) the request was associated with a non-http
-    isolated world origin (so not logging anything when the
-    CorbAllowlistAlsoAppliesToOorCors and OOR-CORS features are enabled since
-    the former feature forces ignoring the isolated world origin when OOR-CORS
-    is enabled) and 3) CORB allows the response (based on non-CORB-content-type
-    header OR sniffing decided that this is not a CORB type).
-
-    Logs &quot;risky&quot; if the request would be blocked by CORS if made from
-    a web page (cross-origin, mode=cors, and no valid ACAO response header).
-    Logs &quot;safe&quot; otherwise.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Browser.Blocked" enum="ContentResourceType2"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data have been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The total count of responses that were blocked by the cross-site document
-    blocking logic in the browser process. Recorded with a resource type (0-17)
-    when the response is blocked; up to 1024 bytes of the response are
-    considered. This is also recorded with a suffix indicating the MIME type
-    category.
-  </summary>
-</histogram>
-
-<histogram
-    name="SiteIsolation.XSD.Browser.Blocked.ContentLength.ValueIfAvailable"
-    units="bytes" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data has been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    For each responses blocked by the cross-site document blocking logic in the
-    browser process, logs network::ResourceResponseInfo::content_length of the
-    response (but only if the content length value was available - if the value
-    was not -1).
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Browser.Blocked.ContentLength.WasAvailable"
-    enum="BooleanAvailable" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data has been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    For each responses blocked by the cross-site document blocking logic in the
-    browser process, logs whether network::ResourceResponseInfo::content_length
-    was available (i.e. value was 0 or greated) or not available (i.e. value was
-    equal to -1) if the value was available (i.e. the value was not -1).
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Browser.BlockedForParserBreaker"
-    enum="ContentResourceType2" expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data have been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The total count of responses that were blocked by the cross-site document
-    blocking logic in the browser process, due to the presence of a Javascript
-    parser-breaker pattern (like &quot;for(;;);&quot;, or &quot;)]}'&quot;, or a
-    non-empty JSON dictionary like &quot;{\&quot;a\&quot;:&quot;. Recorder with
-    a resource type (0-17) when the response is blocked; up to 1024 bytes of the
-    response are considered.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Browser.BytesReadForSniffing" units="bytes"
-    expires_after="M77">
-  <obsolete>
-    Removed in June 2019 / M77. Some old data has been saved in a
-    Google-internal doc at
-    https://docs.google.com/document/d/1hgPpFD5GpxgWsTQvrA0eLunrG0mwb_uJgWWJmG_kVN4
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The number of bytes of the network response buffered for sniffing purposes,
-    when attempting to sniff the response to determine if it should be blocked
-    as a cross-site document. Recorded after sniffing is attempted.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.DataLength" units="byte"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The number of bytes in the first network packet for a response with headers
-    that imply potential illegal cross-site access. Recorded when the first
-    network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having HTML
-    content type header and contents sniffed as HTML. Sampled with value of 1
-    when the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to their HTML contents. Sampled with value
-    1 when the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.HTML.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.) among blocked
-    cross-site document responses due to their HTML contents. Sampled with a
-    resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.) among blocked
-    cross-site document responses due to their HTML contents. Sampled with a
-    resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.NoSniffBlocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to having HTML content type and nosniff
-    headers. Sampled with value 1 when the first network packet of a response of
-    this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.NoSniffBlocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.HTML.NoSniffBlocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having HTML content type and nosniff
-    headers. Sampled with a resource type (0-14) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.NoSniffBlocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having HTML content type and nosniff
-    headers. Sampled with a resource type (0-17) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.NotBlocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of not blocked responses despite having an HTML content type
-    header due to the failure of content sniffing. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.HTML.NotBlocked.MaybeJS" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses that may be parsed as JavaScript among not blocked
-    responses. Sampled with value 1 when the first network packet of a response
-    of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having JSON
-    content type header and contents sniffed as JSON. Sampled with value 1 when
-    the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to their JSON contents. Sampled with value
-    1 when the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.JSON.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their JSON contents. Sampled with a
-    resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their JSON contents. Sampled with a
-    resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.NoSniffBlocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to having JSON content type and nosniff
-    headers. Sampled with value 1 when the first network packet of a response of
-    this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.NoSniffBlocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.JSON.NoSniffBlocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having JSON content type and nosniff
-    headers. Sampled with a resource type (0-14) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.NoSniffBlocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having JSON content type and nosniff
-    headers. Sampled with a resource type (0-17) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.NotBlocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of not blocked responses despite having an JSON content type
-    header due to the failure of content sniffing. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.JSON.NotBlocked.MaybeJS" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses that may be parsed as JavaScript among not blocked
-    responses with a JSON content type header. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.MimeType" enum="SiteIsolationMimeType"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    MIME type codes for content type header values of potentially cross-site
-    document responses, excluding same-site or not http(s) urls. Sampled with a
-    MIME type code (0-4) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.NetworkService.InitiatorLockCompatibility"
-    enum="CorbResultVsInitiatorLockCompatibility" expires_after="2019-06-13">
-  <obsolete>
-    Removed in May 2019.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    Logs whether CORB blocking might have been caused by treating
-    |request_initiator| as opaque when |request_initiator_origin_lock| is
-    incompatible (as may be the case for HTML Imports).
-
-    Logged when CORB allows or blocks a response, only when NetworkService is
-    enabled.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.HTML.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having Plain
-    content type header and contents sniffed as HTML. Sampled with value 1 when
-    the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.HTML.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    responses due to their Plain.HTML contents. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.HTML.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.Plain.HTML.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.HTML contents. Sampled with
-    a resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.HTML.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.HTML contents. Sampled with
-    a resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.JSON.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having Plain
-    content type header and contents sniffed as JSON. Sampled with value 1 when
-    the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.JSON.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to their Plain.JSON contents. Sampled with
-    value 1 when the first network packet of a response of this type is
-    received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.JSON.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.Plain.JSON.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.JSON contents. Sampled with
-    a resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.JSON.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.JSON contents. Sampled with
-    a resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram
-    name="SiteIsolation.XSD.Plain.NoSniffBlocked.NonRenderableStatusCode"
-    units="units" expires_after="M80">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to having Plain content type and nosniff
-    headers. Sampled with value 1 when the first network packet of a response of
-    this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.NoSniffBlocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.Plain.NoSniffBlocked.RenderableStatusCode2
-    in December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having Plain content type and nosniff
-    header. Sampled with a resource type (0-14) when the first network packet of
-    a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.NoSniffBlocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having Plain content type and nosniff
-    header. Sampled with a resource type (0-17) when the first network packet of
-    a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.NotBlocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of not blocked responses despite having an Plain content type
-    header due to the failure of content sniffing. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.NotBlocked.MaybeJS" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses that may be parsed as JavaScript among not blocked
-    responses with a Plain content type header. Sampled with value 1 when the
-    first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.XML.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having Plain
-    content type header and contents sniffed as XML. Sampled with value 1 when
-    the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.XML.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to their Plain.XML contents. Sampled with
-    value 1 when the first network packet of a response of this type is
-    received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.XML.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.Plain.XML.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with renderable HTTP status codes sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.XML contents. Sampled with
-    a resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.Plain.XML.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with renderable HTTP status codes sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their Plain.XML contents. Sampled with
-    a resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.Blocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of blocked cross-site document responses due to having XML content
-    type header and contents sniffed as XML. Sampled with value 1 when the first
-    network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.Blocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with nonrenderable HTTP status codes among blocked
-    cross-site document responses due to their XML contents. Sampled with value
-    1 when the first network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.Blocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.XML.Blocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with renderable HTTP status codes sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their XML contents. Sampled with a
-    resource type (0-14) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.Blocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with renderable HTTP status codes sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to their XML contents. Sampled with a
-    resource type (0-17) when the first network packet of a response of this
-    type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.NoSniffBlocked.NonRenderableStatusCode"
-    units="units" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a nonrenderable HTTP status code among blocked
-    cross-site document responses due to having XML content type and nosniff
-    headers. Sampled with value 1 when the first network packet of a response of
-    this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.NoSniffBlocked.RenderableStatusCode"
-    enum="ContentResourceType" expires_after="2015-12-22">
-  <obsolete>
-    Superseded by SiteIsolation.XSD.XML.NoSniffBlocked.RenderableStatusCode2 in
-    December 2015.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having XML content type and nosniff
-    headers. Sampled with a resource type (0-14) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.NoSniffBlocked.RenderableStatusCode2"
-    enum="ContentResourceType2" expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses with a renderable HTTP status code sub-categorized by
-    their requesting context type (e.g., image, script, etc.), among blocked
-    cross-site document responses due to having XML content type and nosniff
-    headers. Sampled with a resource type (0-17) when the first network packet
-    of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.NotBlocked" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of not blocked responses despite having an XML content type header
-    due to the failure of content sniffing. Sampled with value 1 when the first
-    network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram name="SiteIsolation.XSD.XML.NotBlocked.MaybeJS" units="units"
-    expires_after="2018-03-21">
-  <obsolete>
-    Removed in March 2018; in M67+, browser-process CORB policy is enabled.
-  </obsolete>
-  <owner>creis@chromium.org</owner>
-  <summary>
-    The count of responses that may be parsed as JavaScript among not blocked
-    responses with an XML content type. Sampled with value 1 when the first
-    network packet of a response of this type is received.
-  </summary>
-</histogram>
-
-<histogram
-    name="SmartLock.Performance.AuthenticationToReceiveUnlockableRemoteStatus.Duration.Unlock"
-    units="ms" expires_after="2020-02-01">
-  <obsolete>
-    Removed 2019/08.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when Smart Lock successfully establishes a
-    secure channel connection to the host device, and receives an
-    &quot;authenticated&quot; remote status from it (i.e., the Smart Lock icon
-    becomes green).
-  </summary>
-</histogram>
-
-<histogram
-    name="SmartLock.Performance.StartScanToReceiveUnlockableRemoteStatus.Duration.Unlock"
-    units="ms" expires_after="2020-02-01">
-  <obsolete>
-    Removed 2019/08.
-  </obsolete>
-  <owner>hansberry@chromium.org</owner>
-  <summary>
-    The duration of time between when Smart Lock begins to try to find the host
-    device, and receives an &quot;authenticated&quot; remote status from it,
-    which allows the device to be unlocked (i.e., the Smart Lock icon becomes
-    green).
-
-    See
-    MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background
-    and SmartLock.AuthenticationToReceiveUnlockableRemoteStatus.Unlock.Duration
-    for breakdowns of this metric.
-
-    See SmartLock.GetRemoteStatus.Unlock for the success rate of fetching the
-    remote status from the host.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Cleaner.DownloadHttpResponseCode"
-    enum="HttpResponseCode" expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017. Replaced with
-    SoftwareReporter.Cleaner.DownloadStatusErrorCode.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    The HTTP response code for the Chrome Cleanup Tool download request.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Cleaner.HasCompleted" enum="SRTCompleted"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 because of lack of use.
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The state of software reporter cleaner tool runs. A value of &quot;Not
-    Completed&quot; can mean either the tool crashed, or the tool was still
-    running when Chrome checked.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Cleaner.NumberOfDownloadAttempts"
-    units="counts" expires_after="2018-01-17">
-  <obsolete>
-    Removed on 2018-01-15.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    The number of attempts to download the Chrome Cleanup tool until it either
-    succeeds or fails.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Cleaner.RebootPromptShown"
-    enum="SoftwareReporterRebootPromptType" expires_after="M80">
-  <obsolete>
-    Removed on 2019-05-29.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Indicates how the user was prompted to reboot the machine to complete a run
-    of the Chrome Cleanup Tool.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Cleaner.Version" units="units"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>The build version of the software reporter cleaner tool.</summary>
-</histogram>
-
-<histogram name="SoftwareReporter.ExperimentErrors"
-    enum="SoftwareReporterConfigurationError" expires_after="M82">
-  <obsolete>
-    Deprecate in M82 as the histogram is renamed to
-    SoftwareReporter.ConfigurationErrors.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Whether a configuration error prevented the experimental Software Reporter
-    from running.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.PromptDialog.TimeUntilDone" units="ms"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The time between the Chrome Cleaner dialog being shown and the dialog being
-    closed.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.PromptShown" enum="Boolean"
-    expires_after="2017-08-08">
-  <obsolete>
-    Replaced 2017-08-01 with SoftwareReporter.PromptShownWithType.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Whether the user has been prompted to run the Chrome Cleanup Tool.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.PromptUsage" enum="SRTPromptUsage"
-    expires_after="2017-11-02">
-  <obsolete>
-    Removed as of 2017-11-01. Replaced with
-    SoftwareReporter.PromptDialogResponse.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>Usage of the Software Removal Tool (SRT) Prompt.</summary>
-</histogram>
-
-<histogram name="SoftwareReporter.ReporterSequenceResult"
-    enum="SoftwareReporterSequenceResult" expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>Indicates the result of a reporter sequence once it ends.</summary>
-</histogram>
-
-<histogram name="SoftwareReporter.RunningTime" units="ms" expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The amount of time it took to run the software reporter tool as reported by
-    the tool itself via the registry. Logged just after the software reporter
-    tool has finished.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.RunningTimeRegistryError"
-    enum="SwReporterRunningTimeRegistryError" expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Error encountered when reading the software reporter tool's start and end
-    times from the registry.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.Step" enum="SwReporterStep"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The registration and execution steps for the software reporter.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.UploadFailureCount" units="units"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The total count of SRT log upload failures experienced by this machine for
-    all time. This value is reported at startup by Chrome and is capped at 64.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.UploadLongestFailureRun" units="units"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The longest run of upload failures logged by SRT runs. This value is
-    reported at startup by Chrome and is capped at 64.
-  </summary>
-</histogram>
-
-<histogram name="SoftwareReporter.UploadSuccessCount" units="units"
-    expires_after="M83">
-  <obsolete>
-    Removed 07-2020 due to lack of use
-  </obsolete>
-  <owner>drubery@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    The total count of successful SRT log uploads experienced by this machine
-    for all time. This value is reported at startup by Chrome and is capped at
-    64.
-  </summary>
-</histogram>
-
-<histogram name="Spellcheck.Windows.HunspellUnsupportedLanguageCount"
-    units="locales" expires_after="2020-06-01">
-  <obsolete>
-    Reworked as Spellcheck.Windows.ChromeLocalesSupport.NoSupport and
-    Spellcheck.Windows.ChromeLocalesSupport.NativeOnly in M80.
-  </obsolete>
-  <owner>gujen@google.com</owner>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    Counts how many languages are currently added to Chrome by the user but are
-    not eligible for spellchecking because we have no Hunspell dictionaries for
-    them. This is recorded once during spellcheck initialization, and then once
-    each time the user changes their Chrome languages.
-  </summary>
-</histogram>
-
-<histogram name="Spellcheck.Windows.MissingLanguagePacksCount" units="locales"
-    expires_after="2020-06-01">
-  <obsolete>
-    Reworked as Spellcheck.Windows.SpellcheckLocalesSupport.HunspellOnly and
-    Spellcheck.Windows.SpellcheckLocalesSupport.NoSupport in M80.
-  </obsolete>
-  <owner>gujen@google.com</owner>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    Counts how many Hunspell spellcheck locales are currently enabled by the
-    user but are not supported by the Windows OS spellchecker because there are
-    no language packs installed for them. Locales that are not supported by
-    Hunspell are not counted. This is recorded once during spellcheck
-    initialization, and then once each time the user changes which spellcheck
-    languages are enabled.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.AppCache.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.AppCache in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite for the appcache db.</summary>
-</histogram>
-
-<histogram name="Sqlite.AutoCommitTime" units="ms" expires_after="2019-02-26">
-  <obsolete>
-    Removed in M74.
-  </obsolete>
-  <owner>costan@google.com</owner>
-  <summary>
-    Record times for INSERT/UPDATE/DELETE statements run outside of an explicit
-    transaction.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.CommitTime" units="ms" expires_after="2019-02-26">
-  <obsolete>
-    Removed in M74.
-  </obsolete>
-  <owner>costan@google.com</owner>
-  <summary>Record time spent in explicit COMMIT statements.</summary>
-</histogram>
-
-<histogram name="Sqlite.Cookie.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.Cookie in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite the cookie db.</summary>
-</histogram>
-
-<histogram name="Sqlite.DatabaseTracker.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.DatabaseTracker in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite the websqldb tracker db.</summary>
-</histogram>
-
-<histogram name="Sqlite.DomainBoundCerts.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.DomainBoundCerts in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Error codes returned by sqlite for the domain-bound certs db.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.DomStorageDatabase.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.DomStorageDatabase in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite for the domstorage db.</summary>
-</histogram>
-
-<histogram name="Sqlite.Error.IOERR" enum="SqliteIOERRCode"
-    expires_after="2013-05-15">
-  <obsolete>
-    Replaced 5/14/2013 by expanded Sqlite.Error histogram.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>SQLite extended SQLITE_IOERR codes for all databases.</summary>
-</histogram>
-
-<histogram name="Sqlite.History.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.History in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite for the history db.</summary>
-</histogram>
-
-<histogram name="Sqlite.QueryTime" units="ms" expires_after="2019-02-26">
-  <obsolete>
-    Removed in M74.
-  </obsolete>
-  <owner>costan@google.com</owner>
-  <summary>Record times for all statements run against the database.</summary>
-</histogram>
-
-<histogram name="Sqlite.Quota.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.Quota in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite for the quota db.</summary>
-</histogram>
-
-<histogram name="Sqlite.SizeKB" units="Kb" expires_after="M80">
-  <obsolete>
-    Removed in M75.
-  </obsolete>
-  <owner>peria@chromium.org</owner>
-  <owner>costan@google.com</owner>
-  <summary>Size in kilobytes of pre-existing database at startup.</summary>
-</histogram>
-
-<histogram name="Sqlite.Stats" enum="SqliteStatsEnum"
-    expires_after="2019-03-01">
-  <obsolete>
-    Removed in favor of Sqlite.Stats2 in M74.
-  </obsolete>
-  <owner>costan@google.com</owner>
-  <summary>Stats for different API calls in sql/.</summary>
-</histogram>
-
-<histogram name="Sqlite.Text.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.Text in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite the full text db.</summary>
-</histogram>
-
-<histogram name="Sqlite.Thumbnail.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.Thumbnail in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite for the thumbnail db.</summary>
-</histogram>
-
-<histogram name="Sqlite.UpdateTime" units="ms" expires_after="2019-02-26">
-  <obsolete>
-    Removed in M74.
-  </obsolete>
-  <owner>costan@google.com</owner>
-  <summary>
-    Record times for statements which could update the database file. Includes
-    commit and autocommit time.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.Vfs" units="bytes" expires_after="2018-02-09">
-  <obsolete>
-    Removed 2018/02/06.
-  </obsolete>
-  <owner>shess@chromium.org</owner>
-  <summary>
-    Buffer sizes passed to browser-process SQLite VFS functions.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.Vfs_Events" enum="SqliteVfsEvents"
-    expires_after="2018-02-09">
-  <obsolete>
-    Removed 2018/02/06.
-  </obsolete>
-  <owner>shess@chromium.org</owner>
-  <summary>
-    I/O operations measured by browser-process SQLite VFS wrapper.
-  </summary>
-</histogram>
-
-<histogram name="Sqlite.Web.Error" enum="SqliteErrorCode"
-    expires_after="2013-11-19">
-  <obsolete>
-    Moved to Sqlite.Error.Web in M-27.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Error codes returned by sqlite the web db.</summary>
-</histogram>
-
-<histogram name="sri.resource_integrity_mismatch_event"
-    enum="SRIResourceIntegrityMismatchEvent" expires_after="2017-07-14">
-  <obsolete>
-    Removed 07/2017. Reference: crbug.com/708041
-  </obsolete>
-  <owner>jww@chromium.org</owner>
-  <summary>
-    When resources are checked for mismatching integrity and whether the
-    mismatch forces a refetch.
-  </summary>
-</histogram>
-
-<histogram name="SSL.CertificateErrorHelpCenterVisited"
-    enum="SSLErrorLearnMoreNavigationResult" expires_after="2020-04-19">
-  <obsolete>
-    Removed 03/2020. Reference: crbug.com/1059826
-  </obsolete>
-  <owner>carlosil@chromium.org</owner>
-  <summary>
-    When the &quot;Learn more&quot; link on an SSL interstitial is clicked, this
-    histogram records if the navigation succeded, if it failed with an
-    interstitial, or if it failed with a different error.
-  </summary>
-</histogram>
-
-<histogram name="SSL.ExpectCTReportFailure" enum="NetErrorCodes"
-    expires_after="2016-07-20">
-  <obsolete>
-    Removed as of 07/2016. Replaced with SSL.ExpectCTReportFailure2.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Sites can opt in to Expect CT, a reporting feature that sends a report
-    whenever a TLS connection does not have valid Certificate Transparency
-    information associated with it. This records the error code when Chrome
-    fails to send an Expect CT report.
-  </summary>
-</histogram>
-
-<histogram name="SSL.MarkHttpAsStatus" enum="MarkHttpAsStatus"
-    expires_after="2017-12-27">
-  <obsolete>
-    Removed December 2017 (M65). This information in this histogram can be found
-    in LoginCustomFlags (for users who have set a flag) or by filtering to users
-    with the MarkHttpAs feature enabled (for seeing the field trial breakdown).
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <owner>felt@chromium.org</owner>
-  <summary>
-    Reports whether the user has selected to mark HTTP origins with an
-    experimental UI treatment (such as showing a warning on HTTP pages that
-    collect sensitive information). This histogram is recorded whenever the
-    security level (the overall security state of a page, roughly corresponding
-    to the lock icon) is computed for an HTTP page.
-  </summary>
-</histogram>
-
-<histogram name="SSL.MarkNonSecureAsStatus" enum="MarkNonSecureAsStatus"
-    expires_after="2016-09-20">
-  <obsolete>
-    Removed 09/2016 and replaced with SSL.MarkHttpAsStatus.
-  </obsolete>
-  <owner>palmer@chromium.org</owner>
-  <summary>
-    Reports whether the user has selected to mark non-secure origins as Neutral
-    (the status quo), Dubious, or Non-Secure.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Android.PendingMinidumpsOnStartup" units="minidumps"
-    expires_after="2017-05-16">
-  <obsolete>
-    Removed in M60.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The number of un-uploaded minidumps present in the Android Crash Reports
-    directory. Each minidump file (should) correspond to a crash. This is
-    recorded on startup, just prior to initiating uploading for these minidumps.
-    This is intended as a temporary metric, to be removed around M60:
-    http://crbug.com/699785
-  </summary>
-</histogram>
-
-<histogram name="Stability.Android.PendingMinidumpsOnStartup.SansLogcat"
-    units="minidumps" expires_after="2017-05-16">
-  <obsolete>
-    Removed in M60. Roughly 50% of Chrome startups that had *any* pending
-    minidumps had at least one pending minidump without any logcat output. About
-    5% had multiple minidumps without any logcat output.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    The number of un-uploaded minidumps present in the Android Crash Reports
-    directory that do not yet have logcat output attached. Each minidump file
-    (should) correspond to a crash. This is recorded on startup, just prior to
-    initiating uploading for all pending minidumps. This is intended as a
-    temporary metric, to be removed around M60: http://crbug.com/699785
-  </summary>
-</histogram>
-
-<histogram name="Stability.Android.ProcessedMinidumps"
-    enum="AndroidProcessedMinidumps" expires_after="M76">
-  <obsolete>
-    Removed 04/2019 as we no longer record it in favour of the two variants
-    below.
-  </obsolete>
-  <owner>mheikal@chromium.org</owner>
-  <owner>smaier@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    Records the number of minidumps processed by Crashpad, split by process
-    type. This metric is similar to one that could be computed server-side based
-    on received crash uploads; but the client-side metric also includes any
-    minidumps that were not successfully uploaded.
-  </summary>
-</histogram>
-
-<histogram name="Stability.CrashedProcessAge.Extension" units="ms"
-    expires_after="M83">
-  <obsolete>
-    Removed 04/2020 (data for go/site-isolation-stability has been collected
-    long time ago; nobody on chrome-stability@ spoke in defense of this
-    histogram).
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The age of a crashed extension process. Not logged on iOS. Logged together
-    with CrashExitCodes.Extension.
-  </summary>
-</histogram>
-
-<histogram name="Stability.CrashedProcessAge.Renderer" units="ms"
-    expires_after="M83">
-  <obsolete>
-    Removed 04/2020 (data for go/site-isolation-stability has been collected
-    long time ago; nobody on chrome-stability@ spoke in defense of this
-    histogram).
-  </obsolete>
-  <owner>lukasza@chromium.org</owner>
-  <summary>
-    The age of a crashed extension process. Not logged on iOS. Logged together
-    with CrashExitCodes.Renderer.
-  </summary>
-</histogram>
-
-<histogram name="Stability.iOS.UTE.CreatedSyntheticCrashReportConfig"
-    enum="BooleanSuccess" expires_after="2020-09-30">
-  <obsolete>
-    Removed 09/2019 after having collected enough data.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <owner>olivierrobin@chromium.org</owner>
-  <summary>
-    Recorded when Chrome for iOS attempts to create a config for synthetic crash
-    report. Used to debug the feature, which suppose to upload synthetic crash
-    report using Breakpad.
-  </summary>
-</histogram>
-
-<histogram name="StackSamplingProfiler.DeserializeAllPendingProfilesTime"
-    units="ms" expires_after="2019-05-21">
-  <obsolete>
-    Removed 5/2019 after having collected enough data to analyze jank.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>wittman@chromium.org</owner>
-  <summary>
-    Amount of time taken to deserialize all pending call stack profiles.
-  </summary>
-</histogram>
-
-<histogram name="StackSamplingProfiler.ProfileDeserializationTime" units="ms"
-    expires_after="2019-01-24">
-  <obsolete>
-    Removed 11/2018 as we no longer record this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>wittman@chromium.org</owner>
-  <summary>
-    Amount of time taken to deserialize a call stack profile string.
-  </summary>
-</histogram>
-
-<histogram name="StackSamplingProfiler.ProfileSerializationTime" units="ms"
-    expires_after="2019-01-24">
-  <obsolete>
-    Removed 11/2018 as we no longer record this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <owner>wittman@chromium.org</owner>
-  <summary>Amount of time taken to serialize a call stack profile.</summary>
-</histogram>
-
-<histogram name="Stars.BookmarksBar_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the bookmarks bar view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Clipper_Folio_Selected_Depth_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the depth of a folio when it is selected in the clipper.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Clipper_Folio_Selected_Visible_Folio_Count"
-    units="units" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the number of folios visible when a folio is selected in the clipper.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Clipper_Open_Folio_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of folios when the clipper is opened.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Folio_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the folio view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Goog_Related" units="%" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips with Google related urls (points to internal Google
-    resources). Logs every time user goes to chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Goog_Related_20_Percent" units="%"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips with Google related urls within first 20 (points to
-    internal Google resources). Logs every time user goes to chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Images_Percent" units="%" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips with images. Logs every time user goes to
-    chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Images_Percent_First20" units="%"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips with images within first 20. Logs every time user goes
-    to chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Launch_Bookmark_BookmarksBar_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when a bookmark is launched from the
-    bookmarks bar view.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Launch_Bookmark_Folio_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when a bookmark is launched from the folio
-    view.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Launch_Bookmark_Search_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when a bookmark is launched from the search
-    view.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Launch_Bookmark_SmartGroup_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when a bookmark is launched from the smart
-    group view.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Launch_Bookmark_Timeline_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when a bookmark is launched from the
-    timeline view.
-  </summary>
-</histogram>
-
-<histogram name="Stars.LaunchLocation" enum="StarsLaunchLocation"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>lpromero@chromium.org</owner>
-  <summary>
-    Logs every time a bookmark is launched from an assortment of different UI
-    surfaces with Stars, the new bookmarks UI.
-  </summary>
-</histogram>
-
-<histogram name="Stars.No_Images_Snippets" units="%" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips without images or snippets. Logs every time user goes to
-    chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.No_Img_No_Snippet_20_Percent" units="%"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Percentage of clips without images or snippets within first 20. Logs every
-    time user goes to chrome://bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Number_Of_Nodes" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>yefim@chromium.org</owner>
-  <summary>
-    Logs number of bookmark nodes every time stars extension is loaded.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Profile_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the profile view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.PromoActions" enum="StarsPromoActions"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>jbbegue@chromium.org</owner>
-  <summary>
-    Count the actions performed by the user on the stars promo panel currently
-    only on android and ios.
-  </summary>
-</histogram>
-
-<histogram name="Stars.SalientImageFound" enum="BooleanStarsSalientImageFound"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>lpromero@chromium.org</owner>
-  <summary>
-    A boolean that indicates if a salient image was found for a displayed
-    bookmark. It is recorded every single time a bookmark is displayed. That
-    way, this histogram shows the proportion of bookmarks the user sees with an
-    image. This is used only with Stars, the new bookmarks UI.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Search_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the search view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.SmartGroup_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the smart group view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Timeline_Active_Clip_Count" units="units"
-    expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>
-    Logs the approx number of clips when the timeline view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Stars.Version" units="units" expires_after="2019-01-30">
-  <obsolete>
-    Removed 01/2020 as we no longer record this metric.
-  </obsolete>
-  <owner>accamed@google.com</owner>
-  <summary>Logs the extension version the user is using.</summary>
-</histogram>
-
-<histogram name="Startup.Android.Experimental.Cold.TimeToFirstContentfulPaint"
-    units="ms" expires_after="2018-05-24">
-  <obsolete>
-    This metric was deprecated in M68 in favour of
-    &quot;Startup.Android.Cold.TimeToFirstContentfulPaint.Tabbed&quot;. It has
-    moved out of experimental and records a smaller range of numbers (medium
-    times instead of long times). The &quot;.Tabbed&quot; suffix is added since
-    the histogram is being tracked for WebApkActivity using the
-    &quot;.WebApk&quot; suffix.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Android: The time from the activity creation point to the first contentful
-    paint of the first loaded page. It's not recorded when the first loaded page
-    is non http(s) page like a chrome error page, a new tab page, a blank page.
-    It's also not recorded if the application wasn't in the foreground since the
-    start till the end of event.
-  </summary>
-</histogram>
-
-<histogram name="Startup.Android.Experimental.Cold.TimeToFirstNavigationCommit"
-    units="ms" expires_after="2018-05-24">
-  <obsolete>
-    This metric was deprecated in M68 in favour of
-    &quot;Startup.Android.Cold.TimeToFirstNavigationCommit.Tabbed&quot;. It has
-    moved out of experimental and records a smaller range of numbers (medium
-    times instead of long times). The &quot;.Tabbed&quot; suffix is added since
-    the histogram is being tracked for WebApkActivity using the
-    &quot;.WebApk&quot; suffix.
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <owner>alexilin@chromium.org</owner>
-  <summary>
-    Android: The time from the activity creation point to the moment the first
-    navigation is committed, i.e. when renderer gets the first byte of the
-    document. It's not recorded when the first loaded page is non http(s) page
-    like a chrome error page, a new tab page, a blank page. It's also not
-    recorded if the application wasn't in the foreground since the start till
-    the end of event.
-  </summary>
-</histogram>
-
-<histogram name="Startup.AppListFirstPaintColdStart" units="ms"
-    expires_after="2018-03-20">
-  <obsolete>
-    Removed 03/2018 with Mash AppList refactoring.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    Time for a newly created browser process to perform the first paint of the
-    app launcher, when started with the --show-app-list flag and with no
-    currently running Chrome processes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.AppListFirstPaintWarmStart" units="ms"
-    expires_after="2018-03-20">
-  <obsolete>
-    Removed 03/2018 with Mash AppList refactoring.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    Time for a running browser process to perform the first paint of the app
-    launcher. Measured from the time a second Chrome process started, which sent
-    its --show-app-list command line argument to the already-running process and
-    will soon exit.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserLaunchURLCount" units="urls"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed as of 02/2020.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    Measured when Chrome is invoked, this counts the number of URLs passed via
-    command line. Note that this handles the case of a URL passed to Chrome
-    starting up, or when a running Chrome is given the message to open a new
-    URL.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMainToRendererMain" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 01/2020. Data is not used.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time from the ChromeMain() entry in the browser process to the first
-    RendererMain() entry.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStart.To.MainNavigationStart"
-    units="ms" expires_after="2018-02-20">
-  <obsolete>
-    Removed 2/2018, as MessageLoopStart is after MainNavigationStart with
-    browser-side navigation.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Time between Startup.BrowserMessageLoopStartTime and
-    Startup.FirstWebContents.MainNavigationStart. Recorded explicitly to allow
-    easy breakdown of Startup.FirstWebContents.MainNavigationStart when
-    diagnosing issues.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartHardFaultCount.FirstRun"
-    units="faults" expires_after="2016-01-26">
-  <obsolete>
-    Removed 1/2016.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of hard faults incurred in the browser process from startup to
-    start of the main thread's message loop on first run. This is only reported
-    on Windows 7 and greater.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartHardFaultCount.Success"
-    enum="BooleanSuccess" expires_after="2015-12-10">
-  <obsolete>
-    Removed 12/2015. No longer tracked because values collected on stable show
-    that the function pretty much never fails.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    If OS support was detected (Windows 7 and greater) indicates whether it was
-    possible to determine the number of hard faults that have occurred in the
-    process from startup to start of the main thread's message loop. This can
-    fail because the underlying call is inherently racy.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry" units="ms"
-    expires_after="2016-12-17">
-  <obsolete>
-    Removed 12/2016. crbug.com/634408
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from main entry to the start of the main thread's message loop. This
-    stat is only recorded after 7 minutes of OS uptime to try to mitigate the
-    variance resulting from Chrome being autostarted. Replaced with
-    Startup.BrowserMessageLoopStartTimeFromMainEntry2 which is recorded all the
-    time.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun"
-    units="ms" expires_after="2016-12-17">
-  <obsolete>
-    Removed 12/2016. crbug.com/634408
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from main entry to the start of the main thread's message loop on first
-    run. This stat is only recorded after 7 minutes of OS uptime to try to
-    mitigate the variance resulting from Chrome being autostarted. Replaced with
-    Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun2 which is recorded
-    all the time.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun2"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed 01/2020. Replaced with Startup.BrowserMessageLoopStartTime.FirstRun.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from main entry to the start of the main thread's message loop on first
-    run.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry2" units="ms"
-    expires_after="2018-01-08">
-  <obsolete>
-    Removed 2018-01 in favor of
-    Startup.BrowserMessageLoopStartTimeFromMainEntry3 which does not involve a
-    conversion from Time to TimeTicks.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from main entry to the start of the main thread's message loop.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry3" units="ms"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed 01/2020. Startup.BrowserMessageLoopStartTime has similar data.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from main entry to the start of the main thread's message loop.
-  </summary>
-</histogram>
-
-<histogram name="Startup.BrowserOpenTabs" units="units"
-    expires_after="2020-06-28">
-  <obsolete>
-    Removed 01/2020. Data is not used.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time taken to open the initial tab or to restore tabs from previous session.
-  </summary>
-</histogram>
-
-<histogram name="Startup.ChromeCast.TimeToDisplayVideo" units="ms"
-    expires_after="2015-07-09">
-  <obsolete>
-    Removed 7/2015. To be replaced with Cast events.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The elapsed time from the ChromeCast application launch to the first video
-    frame displayed.
-  </summary>
-</histogram>
-
-<histogram
-    name="Startup.Experimental.FirstWebContents.MainFrameLoad.ManyBuckets"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M-41.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    An experimental metric only collected on the dev and canary channels.
-    Measure the elapsed time from process launch to the first main frame load of
-    the first web contents. Uses significantly more buckets, with reduced
-    ranges.
-  </summary>
-</histogram>
-
-<histogram
-    name="Startup.Experimental.FirstWebContents.MainFrameLoad.StandardBuckets"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Moved to Startup.FirstWebContents.MainFrameLoad in M-41.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    An experimental metric only collected on the dev and canary channels.
-    Measure the elapsed time from process launch to the first main frame load of
-    the first web contents. Uses standard bucket ranges.
-  </summary>
-</histogram>
-
-<histogram
-    name="Startup.Experimental.FirstWebContents.NonEmptyPaint.ManyBuckets"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in M-41.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    An experimental metric only collected on the dev and canary channels.
-    Measure the elapsed time from process launch to the first non-empty paint of
-    the first web contents. Uses significantly more buckets, with reduced
-    ranges.
-  </summary>
-</histogram>
-
-<histogram
-    name="Startup.Experimental.FirstWebContents.NonEmptyPaint.StandardBuckets"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Moved to Startup.FirstWebContents.NonEmptyPaint in M-41.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <summary>
-    An experimental metric only collected on the dev and canary channels.
-    Measure the elapsed time from process launch to the first non-empty paint of
-    the first web contents. Uses standard bucket ranges.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstCommitNavigationTime" units="ms"
-    expires_after="2016-08-08">
-  <obsolete>
-    Replaced by Startup.FirstCommitNavigationTime2
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <summary>
-    [Android only] The time from the earliest entry point in the browser process
-    to the moment the first navigation is committed, i.e. when renderer gets the
-    first byte of the document.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstCommitNavigationTime2" units="ms"
-    expires_after="2017-06-28">
-  <obsolete>
-    Replaced with Startup.FirstCommitNavigationTime3 on 6/2017
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    [Android only] The time from the first foreground entry point in the app to
-    the moment the first navigation is committed, i.e. when renderer gets the
-    first byte of the document.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstCommitNavigationTime3" units="ms"
-    expires_after="2017-12-05">
-  <obsolete>
-    Replaced with Startup.Android.Experimental.Cold.TimeToFirstNavigationCommit
-    on 11/2017
-  </obsolete>
-  <owner>pasko@chromium.org</owner>
-  <owner>wnwen@chromium.org</owner>
-  <summary>
-    [Android only] The time from the first foreground entry point in the app to
-    the moment the first navigation is committed, i.e. when renderer gets the
-    first byte of the document.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.MainFrameLoad" units="ms"
-    expires_after="2016-03-01">
-  <obsolete>
-    Removed with 3/2016 with M48.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    [Desktop] DEPRECATED (but kept as a known basis until M48 is phased out).
-    Measure the elapsed time from process launch to the first main frame load of
-    the first web contents. Deprecated in favor of
-    Startup.FirstWebContents.MainFrameLoad2 which now avoids counting ill-cases
-    (ref. FirstWebContentsProfiler::FinishReason).
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.MainFrameLoad2" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed with M77. Startup.FirstWebContents.NonEmptyPaint3 is a better
-    indicator of startup time as perceived by users.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    [Desktop] Measure the elapsed time from process launch to the first main
-    frame load of the first web contents. Only comprised of cases where the
-    initial foreground tab gets to complete its rendering task unimpeded (an
-    improvement over Startup.FirstWebContents.MainFrameLoad).
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.NonEmptyPaint" units="ms"
-    expires_after="2016-03-01">
-  <obsolete>
-    Removed with 3/2016 with M48.
-  </obsolete>
-  <owner>erikchen@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    [Desktop] DEPRECATED (but kept as a known basis until M48 is phased out).
-    Measure the elapsed time from process launch to the first non- empty paint
-    of the first web contents. Deprecated in favor of
-    Startup.FirstWebContents.NonEmptyPaint2 which now avoids counting ill-cases
-    (ref. FirstWebContentsProfiler::FinishReason).
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.NonEmptyPaint2" units="ms"
-    expires_after="2020-06-10">
-  <obsolete>
-    Replaced with Startup.FirstWebContents.NonEmptyPaint3 on 06/2020, which uses
-    application start time instead of process creation time to reduce noise.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>chrome-analysis-team@google.com</owner>
-  <summary>
-    [Desktop] Measure the elapsed time from process launch to the first non-
-    empty paint of the first web contents. Only comprised of cases where the
-    initial foreground tab gets to complete its rendering task unimpeded (an
-    improvement over Startup.FirstWebContents.NonEmptyPaint).
-
-    This histogram is of special interest to the chrome-analysis-team@. Do not
-    change its semantics or retire it without talking to them first.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UINotResponsive" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the execution time for a single task to execute on UI if
-    it was not possible to execute UI tasks under 1/60s within certain limits,
-    after WebContents was painted at least once. This is recorded at most once
-    per Chrome launch. Used as a measure of responsiveness on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UINotResponsive_10sec" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the elapsed time for a single task to execute on UI if it
-    was not possible to execute it under 1/60s within certain limits, 10 second
-    after first WebContents was painted at least once. This is recorded at most
-    once per Chrome launch. Used as a measure of responsiveness on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UINotResponsive_1sec" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the elapsed time for a single task to execute on UI if it
-    was not possible to execute it under 1/60s within certain limits, 1 second
-    after first WebContents was painted at least once. This is recorded at most
-    once per Chrome launch. Used as a measure of responsiveness on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UIResponsive" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the elapsed time it takes for a task to execute on UI
-    under 1/60s after first WebContents was painted at least once. This is
-    recorded at most once per Chrome launch. Used as a measure of responsiveness
-    on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UIResponsive_10sec" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the elapsed time it takes for a task to execute on UI
-    under 1/60s, 10 second after the first WebContents was painted. This is
-    recorded at most once per Chrome launch. Used as a measure of responsiveness
-    on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.FirstWebContents.UIResponsive_1sec" units="ms"
-    expires_after="2015-10-30">
-  <obsolete>
-    Removed 10/2015.
-  </obsolete>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    [Desktop] Measures the elapsed time it takes for a task to execute on UI
-    under 1/60s, 1 second after the first WebContents was painted. This is
-    recorded at most once per Chrome launch. Used as a measure of responsiveness
-    on startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.Fling.TimeToDisplayVideo" units="ms"
-    expires_after="2015-07-09">
-  <obsolete>
-    Removed 7/2015. To be replaced with Cast events.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    The elapsed time from the Fling application launch to the first video frame
-    displayed.
-  </summary>
-</histogram>
-
-<histogram name="Startup.IsResume" units="units" expires_after="2013-07-08">
-  <obsolete>
-    Removed 12/2011. Merged into MobileSessionStartType.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>Whether a startup is a resume (vs a cold start).</summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ExeMainToDllMain" units="units"
-    expires_after="2016-12-17">
-  <obsolete>
-    Removed 12/2016. crbug.com/634408
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from the main() function in chrome.exe to chrome.dll's main(). This
-    stat is only recorded after 7 minutes of OS uptime to try to mitigate the
-    variance resulting from Chrome being autostarted. Replaced with
-    Startup.LoadTime.ExeMainToDllMain2 which is recorded all the time.
-  </summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ExeMainToDllMain2" units="ms"
-    expires_after="2020-03-12">
-  <obsolete>
-    Removed 03/2020. Replaced with Startup.LoadTime.ApplicationStartToChromeMain
-    which applies to most platforms.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from the main() function in chrome.exe to chrome.dll's main().
-  </summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ProcessCreateToDllMain" units="units"
-    expires_after="2016-12-17">
-  <obsolete>
-    Removed 12/2016. crbug.com/634408
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from the process creation to chrome.dll's main(). This stat is only
-    recorded after 7 minutes of OS uptime to try to mitigate the variance
-    resulting from Chrome being autostarted. Replaced with
-    Startup.LoadTime.ProcessCreateToDllMain2 which is recorded all the time.
-  </summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ProcessCreateToDllMain2" units="ms"
-    expires_after="2020-03-12">
-  <obsolete>
-    Removed 03/2020. Replaced with
-    Startup.LoadTime.ProcessCreateToApplicationStart which applies to most
-    platforms.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>Time from the process creation to chrome.dll's main().</summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ProcessCreateToExeMain" units="units"
-    expires_after="2016-12-17">
-  <obsolete>
-    Removed 12/2016. crbug.com/634408
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from the process creation to executing the main() function in
-    chrome.exe. This stat is only recorded after 7 minutes of OS uptime to try
-    to mitigate the variance resulting from Chrome being autostarted. Replaced
-    with Startup.LoadTime.ProcessCreateToExeMain2 which is recorded all the
-    time.
-  </summary>
-</histogram>
-
-<histogram name="Startup.LoadTime.ProcessCreateToExeMain2" units="ms"
-    expires_after="never">
-  <obsolete>
-    Removed 03/2020. Now covered by
-    Startup.LoadTime.ProcessCreateToApplicationStart and
-    Startup.LoadTime.ApplicationStartToChromeMain.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Time from the process creation to executing the main() function in
-    chrome.exe.
-  </summary>
-</histogram>
-
-<histogram name="Startup.PreMainMessageLoopRunImplStep1Time" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the first untracked section of
-    ChromeBrowserMainParts::PreMainMessageLoopRunImpl.
-  </summary>
-</histogram>
-
-<histogram name="Startup.PreMainMessageLoopRunImplStep2Time" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the second untracked section of
-    ChromeBrowserMainParts::PreMainMessageLoopRunImpl. Not written for Android.
-  </summary>
-</histogram>
-
-<histogram name="Startup.PreMainMessageLoopRunImplStep3Time" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed as of 7/2019.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during the third untracked section of
-    ChromeBrowserMainParts::PreMainMessageLoopRunImpl. Not written for Android.
-  </summary>
-</histogram>
-
-<histogram name="Startup.PreMainMessageLoopRunImplTime" units="ms"
-    expires_after="2015-02-17">
-  <obsolete>
-    Removed as of 2/2015.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during
-    ChromeBrowserMainParts::PreMainMessageLoopRunImpl.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SameVersionStartupCount" units="units"
-    expires_after="2020-03-08">
-  <obsolete>
-    Removed 8/2019. See startup_metric_utils.cc for a summary of old data.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    The number of startups the current version has been through. Reported once
-    per Chrome session, on startup. Any user that reports X for this version
-    will also have previously reported [1,X-1] for this version through the
-    previous X-1 Chrome sessions.
-  </summary>
-</histogram>
-
-<histogram name="Startup.ShowAppListColdStart" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 2018-03.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    Time for a newly created browser process to reach the code that starts
-    showing the app launcher, when started with the --show-app-list flag and
-    with no currently running Chrome processes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.ShowAppListWarmStart" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 2018-03.
-  </obsolete>
-  <owner>tapted@chromium.org</owner>
-  <summary>
-    Time for a running browser process to reach the code that starts showing the
-    app launcher. Measured from the time a second Chrome process started, which
-    sent its --show-app-list command line argument to the already-running
-    process and will soon exit.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupBookmarksLoad" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to load bookmarks from disk. This measurement is only sent for
-    startups that take &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupExtensionServiceInitAfterImport" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to finish initialization of the extension service including
-    loading built-in extensions. This measurement is only sent for startups that
-    take &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupFinalProfileInit" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time the final stages of profile initialization taking including
-    initialization of profile keyed services. This measurement is only sent for
-    startups that take &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupNSSInit" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to load the NSS libraries and initialize it. This measurement
-    is only sent for startups that take &gt;10 seconds after an uptime of 7
-    minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupPreferenceLoading" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to load preferences from disk. This measurement is only sent
-    for startups that take &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupProfileIODataInit" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to initialize the ProfileIOData object - this includes
-    initialization of the cookie store. This measurement is only sent for
-    startups that take &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupSafeBrowsingGetDatabase" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to load the safe browsing database from disk. This measurement
-    is only sent for startups that take &gt;10 seconds after an uptime of 7
-    minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupSafeBrowsingServiceInitialize" units="ms"
-    expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes to initialize the safe browsing service. This measurement is
-    only sent for startups that take &gt;10 seconds after an uptime of 7
-    minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SlowStartupSessionServiceCreateTabsAndWindows"
-    units="ms" expires_after="2015-06-09">
-  <obsolete>
-    Removed 06/2015.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <summary>
-    Time it takes for session restore to finish initiating creation of restored
-    tabs and windows. This measurement is only sent for startups that take
-    &gt;10 seconds after an uptime of 7 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Startup.StartupBrowserCreator_ProcessCmdLineImplTime"
-    units="ms" expires_after="2015-02-24">
-  <obsolete>
-    Removed 02/2015. Startup.StartupBrowserCreator_Start is more useful.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The amount of time that elapsed during
-    StartupBrowserCreator::ProcessCmdLineImpl.
-  </summary>
-</histogram>
-
-<histogram name="Startup.SystemUptime" units="ms" expires_after="2020-07-06">
-  <obsolete>
-    Remove 01/2020. Data is no longer used.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The time elapsed between system boot and Chrome browser process launch. This
-    is recorded just before the main message loop starts.
-  </summary>
-</histogram>
-
-<histogram name="Startup.TimeOfDayGMT" units="HHMM" expires_after="M77">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>feuunk@chromium.org</owner>
-  <summary>
-    The time of day in GMT that the startup was performed. This is logged in
-    HHMM format, with the minutes rounded down to the nearest 10 minute
-    interval.
-
-    This can be used to make traffic estimates for requests made from startup.
-  </summary>
-</histogram>
-
-<histogram name="Startup.TimeSinceLastStartup" units="minutes"
-    expires_after="M77">
-  <obsolete>
-    Removed 08/2019. See startup_metric_utils.cc for a summary of old data.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time elapsed since the last startup that went up to the main message loop
-    start. This is recorded just before the main message loop starts.
-  </summary>
-</histogram>
-
-<histogram name="Startup.WarmStartTimeFromRemoteProcessStart" units="ms"
-    expires_after="M81">
-  <obsolete>
-    Removed 01/2020. The data is no longer used.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time for a running browser process to start processing the command line
-    passed in by a second Chrome process, which just sent its command line
-    arguments to the already-running process and will soon exit. Measured from
-    the time the second Chrome process started.
-  </summary>
-</histogram>
-
-<histogram name="StartupTimeBomb.Alarm" units="ms" expires_after="2014-10-23">
-  <obsolete>
-    Removed as of 10/2014.
-  </obsolete>
-  <owner>dschinazi@chromium.org</owner>
-  <owner>src/net/OWNERS</owner>
-  <summary>
-    Time duration measured from the time the startup timebomb was started and
-    when it went off.
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.CreateDirectoryResult" enum="PlatformFileError"
-    expires_after="2020-03-29">
-  <obsolete>
-    No longer relevant. There are almost never any failures.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Recorded when we create the blob storage directory for the blob storage
-    system. When we need to write blob data to files, we create this directory
-    if it doesn't exist. We write blob data to files when either we have a new
-    blob that's larger than our memory limit, or we're approaching our in-memory
-    limit for blob storage.
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.ExceededMemory" enum="Boolean"
-    expires_after="2016-03-30">
-  <obsolete>
-    Removed as of 3/2016. Use Storage.Blob.Broken to see the fraction of blobs
-    that are broken, and Storage.Blob.BrokenReason for the number of broken
-    blobs that are broken because of memory constraints.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    True if a created blob exceeded the internal in-memory storage memory limit
-    for blobs.
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.ItemCount" units="Blob Items"
-    expires_after="2018-12-13">
-  <obsolete>
-    Removed as of 12/18. Metric wasn't used for anything and wasn't useful.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The number of blob items in a blob, recorded at blob construction. (Blobs
-    are immutable, so this won't change afterwards).
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.MaxDiskSpace" units="MB"
-    expires_after="2018-12-13">
-  <obsolete>
-    Removed as of 12/18.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the calculated max disk space the blob storage system can use.
-    Recorded on storage partition initialization.
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.StorageSizeAfterAppend" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Not an accurate way to measure the normal max blob usage.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the total in-memory storage size of blobs before a blob item is
-    appended. Can be subtracted by Storage.Blob.StorageSizeBeforeAppend to find
-    the true distribution of blob storage sizes.
-  </summary>
-</histogram>
-
-<histogram name="Storage.Blob.StorageSizeBeforeAppend" units="KB"
-    expires_after="M77">
-  <obsolete>
-    Not an accurate way to measure the normal max blob usage.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the total in-memory storage size of blobs before a blob item is
-    appended. Can be subtracted from Storage.Blob.StorageSizeAfterAppend to find
-    the true distribution of blob storage sizes.
-  </summary>
-</histogram>
-
-<histogram name="Storage.BlobItemSize" units="KB" expires_after="2018-12-13">
-  <obsolete>
-    Removed on 12/18. Metric wasn't used for anything and wasn't useful.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The size in KB of items (or parts of items) appended to blobs.
-  </summary>
-</histogram>
-
-<histogram name="Storage.BlobItemSize.BlobSlice" units="KB"
-    expires_after="2018-12-13">
-  <obsolete>
-    Removed on 12/18. Metric wasn't used for anything and wasn't useful.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The size in KB of items (or parts of items) appended to blobs that come from
-    the slicing of other blobs. This happens when using Blob.slice, where we are
-    using a part of an item in the original blob (not the whole item).
-  </summary>
-</histogram>
-
-<histogram name="Storage.BlobItemSize.FileSystem.Unknown" enum="BooleanUnknown"
-    expires_after="2018-12-13">
-  <obsolete>
-    Removed on 12/18. Metric was always false.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    True if the file size of a filesystem object on blob append is unknown
-    (which means the full file), or false if a specific file length was
-    populated. Recorded in BlobStorageContext when we are adding a filesystem
-    item to a blob.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Storage.BytesRead" units="bytes"
-    expires_after="M83">
-  <obsolete>
-    Removed in 2020-04.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>The number of bytes read. Recorded on each read.</summary>
-</histogram>
-
-<histogram base="true" name="Storage.BytesWritten" units="bytes"
-    expires_after="M83">
-  <obsolete>
-    Removed in 2020-04.
-  </obsolete>
-  <owner>mek@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>The number of bytes written. Recorded on each write.</summary>
-</histogram>
-
-<histogram name="Storage.IndexedDB.WriteBlobFileViaCopy" enum="Boolean"
-    expires_after="M75">
-  <obsolete>
-    No longer emitted.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <owner>mek@chromium.org</owner>
-  <summary>
-    Records if a blob attempted to be written to IndexedDB used the
-    base::CopyFile optimization. Recorded for every blob attempted to be written
-    to IndexedDB.
-  </summary>
-</histogram>
-
-<histogram name="Style.AuthorStyleSheet.ParseTime" units="microseconds"
-    expires_after="2019-02-13">
-  <obsolete>
-    Removed 2019-02, no longer used.
-  </obsolete>
-  <owner>futhark@chromium.org</owner>
-  <summary>
-    Microseconds spent in StyleSheetContents::ParseAuthorStyleSheet.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Style.LazyUsage.Percent" enum="LazyCSSParseUsage"
-    expires_after="2018-07-25">
-  <obsolete>
-    Removed 07/2018, no longer used.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Tracks % of lazy rules that ended up needing to be parsed. A sheet logs
-    counts into this histogram as it is parsed (i.e. as properties are parsed
-    lazily). Once a certain percent of rules have been parsed, we log a count
-    immediately. Note that this implies that a stylesheet which uses all of its
-    rules will log counts in every bucket.
-  </summary>
-</histogram>
-
-<histogram name="Style.TotalLazyRules" units="count" expires_after="2018-07-25">
-  <obsolete>
-    Removed 07/2018, no longer used.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Tracks the total number of rules that have parsing lazily deferred in an
-    author style sheet.
-  </summary>
-</histogram>
-
-<histogram name="Style.TotalLazyRules.FullUsage" units="count"
-    expires_after="2018-07-25">
-  <obsolete>
-    Removed 07/2018, no longer used.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Tracks the total number of rules that have parsing lazily deferred in an
-    author style sheet, for sheets that ended up needing all their rules.
-  </summary>
-</histogram>
-
-<histogram name="Style.UpdateTime" units="microseconds"
-    expires_after="2018-08-01">
-  <obsolete>
-    Removed 07/2018, replaced by Style.RecalcTime and
-    Style.RebuildLayoutTreeTime.
-  </obsolete>
-  <owner>futhark@chromium.org</owner>
-  <summary>
-    Microseconds spent in Document::UpdateStyle.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.Actions" enum="SubresourceFilterActions"
-    expires_after="2018-07-13">
-  <obsolete>
-    Removed June 2018 in favor of SubresourceFilter.Actions2
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Counts of various UI and user action events related to the
-    SubresourceFilter. This will be triggered in response to Content Settings
-    changes, as well as when portions of the UI are shown or interacted with.
-    Main frame navigations are also tracked for ease of comparison and analysis.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.AdDelay.Delay" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed April 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Logs the delay the ad delay throttle added to a request. Logged for every
-    subresource request that was delayed.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.AdDelay.Delay.Expected" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed April 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Logs the expected delay the ad delay throttle added to a request. This is
-    the delay imposed assuming no task queuing delay. Logged for every
-    subresource request that was delayed.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.AdDelay.Delay.Queuing" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed April 2019
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Logs the task queuing delay the ad delay throttle added to a request. This
-    is the actual delay minus the expected delay. Logged for every subresource
-    request that was delayed.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.AdDelay.IsolatedInfo" enum="AdIsolatedInfo"
-    expires_after="2018-07-16">
-  <obsolete>
-    Removed July 2018. Replaced with Ads.Features.AdResourceIsIsolated.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For a given ad request, logs information related to whether it is isolated
-    from the top-level context. Logged per ad subresource request.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.AdDelay.SecureInfo" enum="AdSecureInfo"
-    expires_after="2018-07-16">
-  <obsolete>
-    Removed July 2018. Replaced with Ads.Features.ResourceIsSecure.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    For a given request, logs information related to whether it is marked as an
-    ad, and whether it is secure (e.g. https). Logged per subresource request.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.DocumentLoad.ActivationComputingDelay"
-    units="microseconds" expires_after="M77">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Records the total time the activation state navigation throttle within a
-    document is delayed while calculating activation. Recorded at resume time.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame"
-    units="microseconds" expires_after="M78">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Records the total time the activation state navigation throttle within a
-    main frame document is delayed while calculating activation. Recorded at
-    resume time.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Disallowed"
-    units="resource loads" expires_after="M77">
-  <obsolete>
-    Expired in M77, then deprecated in July 2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total number of subresource
-    loads that have been disallowed. This only differs from `MatchedRules` when
-    filtering is performed in dry-run mode.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Evaluated"
-    units="resource loads" expires_after="M77">
-  <obsolete>
-    Expired in M77, then deprecated in July 2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total number of subresource
-    loads that have been evaluated. This only differs from 'Total' when the
-    document is subject to a deactivating rule with DOCUMENT activation type.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules"
-    units="resource loads" expires_after="M78">
-  <obsolete>
-    Expired in M78, then deprecated in July 2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total number of subresource
-    loads that have matched filtering rules. This only differs from `Disallowed`
-    when filtering is performed in dry-run mode.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Total"
-    units="resource loads" expires_after="M77">
-  <obsolete>
-    Expired in M77, then deprecated in July 2019.
-  </obsolete>
-  <owner>engedy@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total number of subresource
-    loads that have gone through the subresource filtering pipeline.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed"
-    units="microseconds" expires_after="M87">
-  <obsolete>
-    Removed in August 2019. Replaced by SubframeFilteringDelay.Disallowed2.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Records the total time a subframe navigation was delayed while calculating
-    whether it should be disallowed or not. Logged for all navigations that were
-    disallowed or would be disallowed.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>pkalinnikov@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total thread CPU time spent on
-    processing subresource requests in allowLoad.
-
-    Note: this histogram is emitted for all clients, both ones which have
-    high-resolution timer available and those which don't.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalWallDuration"
-    units="microseconds" expires_after="M78">
-  <obsolete>
-    Removed in July 2019.
-  </obsolete>
-  <owner>pkalinnikov@chromium.org</owner>
-  <summary>
-    Whenever a document load is finished in a main frame or subframe with
-    subresource filtering activated, records the total real time spent on
-    processing subresource requests in allowLoad, including the time spent on
-    waiting or being descheduled.
-
-    Note: this histogram is emitted for all clients, both ones which have
-    high-resolution timer available and those which don't.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.IndexRuleset.Verify.WallDuration"
-    units="microseconds" expires_after="2017-11-07">
-  <obsolete>
-    Removed in favor of the Verify2 metric
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The total time it took to verify the indexed ruleset in the browser process.
-    Logged every time verification occurs, which usually occurs when the first
-    page with activation is navigated to.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.Activation.RedirectPosition"
-    enum="SafeBrowsingActivationPosition" expires_after="M80">
-  <obsolete>
-    Removed in favor of SubresourceFilter.PageLoad.Activation.RedirectPosition2
-  </obsolete>
-  <owner>ericrobinson@chromium.org</owner>
-  <summary>
-    For pages that trigger Safe Browsing activations (not including dry runs),
-    records the position in the redirect chain for the page the activation was
-    triggered by. If SubresourceFilterConsiderRedirects is disabled, then always
-    returns &quot;Only navigation&quot;.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.BlockedPopups" units="popups"
-    expires_after="2017-10-20">
-  <obsolete>
-    Metric is broken and will be replaced by
-    ContentSettings.Popups.StringBlocked.NumBlocked. This only logged values for
-    sites which are also activated for subresource filtering, when most sites
-    will probably only be marked for popup blocking.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Records the number of popups blocked per page load due to subresource filter
-    logic. Recorded when a new main frame navigation commits. Note that this
-    histogram is recorded for all pages which are activated by the subresource
-    filter, including ones which do not trigger the stronger popup blocker.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.FinalURLMatch"
-    enum="BooleanMatched" expires_after="2017-08-25">
-  <obsolete>
-    Removed in favor of SubresourceFilter.PageLoad.ActivationList.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Records, for each main frame navigation, whether the last URL in the
-    redirect chain matched the Safe Browsing blacklist specified by the
-    histogram suffix.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.ForcedActivation.DisallowedLoad"
-    enum="Boolean" expires_after="2018-05-31">
-  <obsolete>
-    Removed May 2018 in favor of SubresourceFilter.PageLoad.ActivationDecision
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Logged when the first resource is disallowed from a page with forced
-    activation. For example, if the devtools ad blocking option is set.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.RedirectChainLength" units="urls"
-    expires_after="2018-05-24">
-  <obsolete>
-    Removed May 2018
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Total number of server redirects during the navigation. This histogram is
-    recorded in several for every list where subresource fiter is active.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.PageLoad.RedirectChainMatchPattern"
-    enum="SubresourceFilterMatchPattern" expires_after="2017-05-16">
-  <obsolete>
-    Obsolete as of April 2017, since the don't have correct data to record
-    anymore.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    For each main frame navigation, records a pattern that indicates which URLs
-    in the redirect chain matched Safe Browsing blacklists, and which did not.
-    For example, for the redirect chain A-B-C-D metric tracks: 1. If initial URL
-    (A) was on a Safe Browsing blacklist. 2. If any if middle urls (B, C) were
-    on a Safe Browsing blacklist. 3. If committed URL (B) was on a Safe Browsing
-    blacklist. This histogram is recorded in several flavours: with prefix
-    SubresourceFilterOnly in case the redirect chain contains url from the Safe
-    Browsing SubresourceFilter list and without the prefix for all other
-    redirect chains.
-  </summary>
-</histogram>
-
-<histogram
-    name="SubresourceFilter.PageLoad.SafeBrowsingDelay.NoRedirectSpeculation"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed in May 2018 (M69). We have enough data to show that the redirect
-    speculations we do are necessary, especially for Android.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The navigation delay that would have been imposed by the subresource filter
-    on a given navigation due to Safe Browsing checks if redirect speculation
-    was removed. Removing this feature would cause more delay if a navigation
-    has redirects.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.Prompt.NumReloads" enum="BooleanRequested"
-    expires_after="2018-07-13">
-  <obsolete>
-    Removed in favor of the whitelisted bucket in SubresourceFilter.Actions2
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Number of times the user has requested a reload for the page by clicking on
-    the reload button.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.Prompt.NumVisibility" enum="BooleanVisible"
-    expires_after="2017-03-30">
-  <obsolete>
-    Removed in favor of SubresourceFilter.Action
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Number of times Safebrowsing Subresource Filter decided to toggle visibility
-    of the prompt.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.SafeBrowsing.CheckDispatchTime"
-    units="microseconds" expires_after="2018-05-15">
-  <obsolete>
-    Removed in May 2018 in favor of the more general
-    SB2.RemoteCall.CheckDispatchTime.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The microseconds it took to dispatch the Safe Browsing check. This includes
-    IPC descheduling delays to communicate with SafetyNet on Android, and
-    synchronous db checks on desktop.
-
-    Note: this histogram is emitted for all clients, both ones which have
-    high-resolution timer available and those which don't.
-  </summary>
-</histogram>
-
-<histogram name="SubresourceFilter.SafeBrowsing.CheckTime" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed in May 2019 in favor of the TotalCheckTime variant.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The time an individual Safe Browsing URL check took before finishing. Logged
-    when a check is complete or cancelled due to a timeout.
-  </summary>
-</histogram>
-
-<histogram name="SupervisedUserContentProvider.ChromeNotStartedRequestTime"
-    units="ms" expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>aberent@chromium.org</owner>
-  <summary>
-    Time to get the response to requesting whether a URL should be accessible to
-    the supervised user, when Chrome was not previously running.
-  </summary>
-</histogram>
-
-<histogram name="SupervisedUserContentProvider.ChromeStartedRequestTime"
-    units="ms" expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>aberent@chromium.org</owner>
-  <summary>
-    Time to get the response to requesting whether a URL should be accessible to
-    the supervised user, when Chrome was already running.
-  </summary>
-</histogram>
-
-<histogram name="SupervisedUserContentProvider.RequestTimedOut"
-    enum="BooleanTimedOut" expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>aberent@chromium.org</owner>
-  <summary>
-    True if a request to find out whether a URL should be accessible to a
-    supervised user timed out.
-  </summary>
-</histogram>
-
-<histogram name="SupervisedUsers.Extensions" enum="SupervisedUserExtension"
-    expires_after="2020-12-03">
-  <obsolete>
-    Renamed to SupervisedUsers.Extensions2 in M84.
-  </obsolete>
-  <owner>tobyhuang@chromium.org</owner>
-  <owner>agawronska@chromium.org</owner>
-  <owner>danan@chromium.org</owner>
-  <owner>cros-families@google.com</owner>
-  <summary>
-    Records the progress of supervised users as they try to install Chrome
-    extensions. New extension approval granted count increments when the
-    custodian initially grants approval to install the extension. New version
-    approval granted count increments when the supervised user approves a newer
-    version of an existing extension. Removed count increments when the
-    supervised user removes an extension.
-  </summary>
-</histogram>
-
-<histogram name="SupervisedUsers.ExtensionsAllowlist"
-    enum="SupervisedUserExtensionAllowlist" expires_after="M84">
-  <obsolete>
-    Removed in April 2020 (M84).
-  </obsolete>
-  <owner>tobyhuang@chromium.org</owner>
-  <owner>cros-families@google.com</owner>
-  <summary>
-    Records the progress of supervised users as they try to install Chrome
-    extensions during the COVID-19 crisis, before the parent approval dialog is
-    ready. kAllowlistMiss count increments whenever we query for an extension id
-    in the allowlist and it is not found. kAllowlistHit count increments
-    whenever the extension id is found in the allowlist.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AppAssociationTime" units="ms" expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during app association (M18 and earlier were mispelled with this
-    histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AppRunFailures" units="units" expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of apps run failures, used to compare failure rates between data types
-    for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AppSettingsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by AppSettingsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of app settings association failures.</summary>
-</histogram>
-
-<histogram name="Sync.AppsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by AppsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of app association failures.</summary>
-</histogram>
-
-<histogram name="Sync.AppStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of app association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.AssociationTime" units="ms"
-    expires_after="2019-10-01">
-  <obsolete>
-    Removed in M80.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>Time taken during association of this data type.</summary>
-</histogram>
-
-<histogram name="Sync.Attachments.DownloadChecksumResult" enum="BooleanMatched"
-    expires_after="2018-04-20">
-  <obsolete>
-    Removed 2018-04, Sync attachments were never launched.
-  </obsolete>
-  <owner>maxbogue@chromium.org</owner>
-  <summary>Whether attachment checksums match on download or not.</summary>
-</histogram>
-
-<histogram name="Sync.Attachments.DownloadResponseCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2018-04-20">
-  <obsolete>
-    Removed 2018-04, Sync attachments were never launched.
-  </obsolete>
-  <owner>maxbogue@chromium.org</owner>
-  <summary>Response or error codes from downloading sync attachments.</summary>
-</histogram>
-
-<histogram name="Sync.Attachments.DownloadTotalTime" units="ms"
-    expires_after="2018-04-20">
-  <obsolete>
-    Removed 2018-04, Sync attachments were never launched.
-  </obsolete>
-  <owner>maxbogue@chromium.org</owner>
-  <summary>
-    The total time a download takes including request and server overhead.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Attachments.StoreInitResult"
-    enum="SyncAttachmentStoreResult" expires_after="2018-04-20">
-  <obsolete>
-    Removed 2018-04, Sync attachments were never launched.
-  </obsolete>
-  <owner>maxbogue@chromium.org</owner>
-  <summary>The result of initializing the sync attachment store.</summary>
-</histogram>
-
-<histogram name="Sync.Attachments.UploadResponseCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2018-04-20">
-  <obsolete>
-    Removed 2018-04, Sync attachments were never launched.
-  </obsolete>
-  <owner>maxbogue@chromium.org</owner>
-  <summary>Response or error codes from uploading sync attachments.</summary>
-</histogram>
-
-<histogram name="Sync.AttemptNigoriMigration" enum="SyncNigoriMigrationResult"
-    expires_after="2020-05-31">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>mmoskvitin@google.com</owner>
-  <summary>
-    Enumeration of results from attempting to migrate Sync's nigori node and its
-    encryption keys to support keystore.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AuthInvalidationRejectedTokenAgeLong" units="days"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Age of all auth tokens rejected by the invalidation server. Measured from
-    the time they were created.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AuthInvalidationRejectedTokenAgeShort" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Age of auth tokens younger than one hour that were rejected by the
-    invalidation server. Measured from the time they were created.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AuthorizationTimeInNetwork" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time taken during initial authorization.</summary>
-</histogram>
-
-<histogram name="Sync.AuthServerRejectedTokenAgeLong" units="days"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Age of all auth tokens rejected by the sync server. Measured from the time
-    they were created.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AuthServerRejectedTokenAgeShort" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    No longer relevant since transition to OAuth.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Age of auth tokens younger than one hour that were rejected by the sync
-    server. Measured from the time they were created.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfile.AddOrUpdateOrigin"
-    enum="AutofillProfileSyncChangeOrigin" expires_after="M76">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Reported for autofill profile sync once per every locally committed entity
-    creation/update. It breaks down the origin of such a local change.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfile.DeleteOrigin"
-    enum="AutofillProfileSyncChangeOrigin" expires_after="M76">
-  <obsolete>
-    Removed in M77.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Reported for autofill profile sync once per every locally committed entity
-    deletion. It breaks down the origin of such a local deletion.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfileAssociationTime" units="ms"
-    expires_after="2018-09-27">
-  <obsolete>
-    Replaced by Sync.AutofillProfilesAssociationTime.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during autofill profile association (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfileRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of autofill profiles run failures, used to compare failure rates
-    between data types for a particular profile (see other Sync*RunFailures
-    histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfilesStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by AutofillProfilesConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of autofill profile association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfileStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of autofill profile association failures (M18 and
-    earlier were mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of autofill (autocomplete) run failures, used to compare failure rates
-    between data types for a particular profile (see other Sync*RunFailures
-    histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by AutofillConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of autofill association failures.</summary>
-</histogram>
-
-<histogram name="Sync.AutoNigoriOverwrites" units="units" expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>mmoskvitin@google.com</owner>
-  <summary>
-    Number of times this client has overwritten the nigori node to update the
-    encryption keys without a user action (during this instantiation of Chrome).
-  </summary>
-</histogram>
-
-<histogram name="Sync.BackendInitializeRestoreState"
-    enum="SyncBackendInitializeRestoreState" expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Compares sync's has_setup_completed pref against the set of types actually
-    restored from the sync DB. Mismatches should be rare.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BadRequestCountOnSignInNeedsUpdateInfoBar" units="units"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of bad requests since application startup, when the Sync error
-    infobar asking the user to update their account details is displayed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarkAssociationTime" units="ms"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m18
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time taken during bookmark association.</summary>
-</histogram>
-
-<histogram name="Sync.BookmarkGUIDSource" enum="BookmarkGUIDSource"
-    expires_after="M85">
-  <obsolete>
-    Removed as of 12/2019. Replaced by Sync.BookmarkGUIDSource2 which fixes a
-    bug affecting bucket 2 (field left empty) which counted permanent nodes.
-  </obsolete>
-  <owner>psivieroleitao@google.com</owner>
-  <owner>mamir@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records the source of GUIDs for remote bookmark updates, recorded when
-    processing a remote bookmark update.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarkRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of bookmark run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarksDuplicationsAtAssociation" units="units"
-    expires_after="M82">
-  <obsolete>
-    Removed as of M80.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Estimated number of bookmark duplications after bookmark association.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarksModelReadyToSyncTime" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Time used to parse the Bookmarks persisted sync metadata after being read
-    from the Bookmarks JSON file. It includes the time spent in initializing
-    Bookmark Sync data structures as well as the time spent to check the
-    correctness of the data. It's reported on every startup for already syncing
-    users. It's not reported for non-syncing users or users going through the
-    first sync experience.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarksModelSyncStateAtNewDuplication"
-    enum="SyncBookmarkModelSyncState" expires_after="M82">
-  <obsolete>
-    Removed as of M80.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Tracks state of local bookmark model version relative to the sync version
-    when a new bookmark duplication occurs during bookmark association.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarksNewDuplicationsAtAssociation" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed as of M80.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Estimated number of new bookmark duplications after bookmark association.
-  </summary>
-</histogram>
-
-<histogram name="Sync.BookmarksStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by BookmarksConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of bookmark association failures.</summary>
-</histogram>
-
-<histogram name="Sync.BookmarkStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of bookmark association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.CanDecryptNigoriKeybagWithBase64DecodedKeys"
-    enum="Boolean" expires_after="2019-10-01">
-  <obsolete>
-    Removed 10/2019. Was used for investigation of not completed Nigori
-    migration to keystore and recorded 0 suspicious samples.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records whether Nigori keybag can be decrypted with base64 decoded keystore
-    keys, when Nigori is not migrated to keystore and cryptographer is not
-    ready.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ClearServerDataEvents" enum="ClearServerDataEvents"
-    expires_after="2019-02-19">
-  <obsolete>
-    Removed in 2019-02.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>
-    Records events encountered during sync's ClearServerData flow.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.CommitLatency" units="ms"
-    expires_after="2020-10-02">
-  <obsolete>
-    Removed in 2020-10.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Records the time between the local model being changed until the commit
-    response is completed and propagated to the model thread. Note: This is only
-    recorded with a data type suffix. The base version is never recorded.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.ConfigureFailure" enum="SyncConfigureResult"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed in M80.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Enumeration of types of configuration failures of this data type.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime.ABORTED" units="ms"
-    expires_after="2014-02-28">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Long.ABORTED in m21.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration is
-    aborted.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime.OK" units="ms" expires_after="2014-02-28">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Long.OK in m21.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime.PARTIAL_SUCCESS" units="ms"
-    expires_after="2014-02-28">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Long.PARTIAL_SUCCESS in m21.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where only some data types
-    succeed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime.UNRECOVERABLE_ERROR" units="ms"
-    expires_after="2014-02-28">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Long.UNRECOVERABLE_ERROR in m21.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration encounters
-    an unrecoverable error.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime_Long.ABORTED" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Initial.ABORTED and
-    Sync.ConfigureTime_Subsequent.ABORTED in M75.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration is
-    aborted.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime_Long.OK" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Initial.OK and
-    Sync.ConfigureTime_Subsequent.OK in M75.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration succeeds.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime_Long.PARTIAL_SUCCESS" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Removed in M75.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where only some data types
-    succeed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConfigureTime_Long.UNRECOVERABLE_ERROR" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Initial.UNRECOVERABLE_ERROR and
-    Sync.ConfigureTime_Subsequent.UNRECOVERABLE_ERROR in M75.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent configuring data types in the case where configuration encounters
-    an unrecoverable error.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConflictFixCircularity" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 12/2011. No longer tracked. See crbug.com/107816.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of times we fix a circularity sync conflict. This is not expected to
-    be hit anymore.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ConflictFixRemovedDirectoriesWithContent" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 12/2011. No longer tracked. See crbug.com/107816.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of times we fix a removed directory with content sync conflict. This
-    is not expected to be hit anymore
-  </summary>
-</histogram>
-
-<histogram name="Sync.CredentialsLost" enum="BooleanCredentialsLost"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Whether or not we detected missing credentials during startup. This may be
-    related to crbug.com/121755.
-  </summary>
-</histogram>
-
-<histogram name="Sync.CustomPassphrase" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m26.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Boolean histogram for whether a custom passphrase was entered during sync
-    setup. Samples are taken every time sync is (re)configured, and the unique
-    userid count shows how many users entered a custom passphrase.
-  </summary>
-</histogram>
-
-<histogram name="Sync.CustomSync" enum="UserSelectableSyncType"
-    expires_after="2018-10-22">
-  <obsolete>
-    Removed 10/2018, replaced by Sync.CustomSync2.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Samples are taken every time sync is (re)configured, and the unique userid
-    count shows how many users explicitly chose to sync this data type via the
-    &quot;Advanced Sync Preferences&quot; dialog.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DatatypePrefRecovery" units="units"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of clients that have fixed themselves up from a datatype preference
-    loss. Clients are not expected to have this happen more than once. This
-    value can be compared to Sync.BackendInitializeRestoreSuccess to determine
-    what percentage of users are still recovering.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DataTypeRunFailures" enum="SyncModelTypes"
-    expires_after="2018-10-09">
-  <obsolete>
-    Removed 10/2018. Replaced by Sync.DataTypeRunFailures2 which correctly
-    splits run and start failures.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Histogram of the run failures for the different sync datatypes. These are
-    failures that occur after startup while the datatype is syncing. Note: Due
-    to an enumeration reordering, pre-M23 labels are inaccurate (see
-    sync/base/model_type.h).
-  </summary>
-</histogram>
-
-<histogram name="Sync.DataTypeStartFailures" enum="SyncModelTypes"
-    expires_after="2018-10-09">
-  <obsolete>
-    Removed 10/2018. Replaced by Sync.DataTypeStartFailures2 which correctly
-    splits run and start failures.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Histogram of the startup failures for the different sync datatypes. These
-    are failures due to missing top level sync nodes or model association Note:
-    Due to an enumeration reordering, pre-M23 labels are inaccurate (see
-    sync/base/model_type.h).
-  </summary>
-</histogram>
-
-<histogram name="Sync.DeleteRoamingUserDataDirectory"
-    enum="RoamingUserDataDirectoryDeletionResult" expires_after="2020-08-04">
-  <obsolete>
-    Removed in 2020-08 (M86).
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>
-    Reports the result of an attempt to delete a Windows user's roaming User
-    Data directory. This directory was erroneously created for signed-in users
-    who were not using the local sync server. See https://crbug.com/980487 for
-    details.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DeviceCount" units="units" expires_after="2019-02-08">
-  <obsolete>
-    Removed in M74.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    The largest number of active syncing devices known to any profile. May be 0
-    when there are no signed in/syncing profiles open.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DeviceIdMismatchDetails" enum="DeviceIdMismatch"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>
-    When signin_scoped_device_id from pref doesn't match the one in
-    DeviceInfoSpecfics this histogram tells if sync or pref copy was empty. This
-    will indicate how often such mismatch happens and what was the state before.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DictionaryStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by DictionaryConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of dictionary association failures.</summary>
-</histogram>
-
-<histogram name="Sync.DirectoryCatastrophicError" enum="BooleanError"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Whether the Sync Directory encountered a catastrophic error.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DirectoryOpenFailedMac" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 11/2011. No longer tracked.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Number of failures trying to open the sync database on mac.</summary>
-</histogram>
-
-<histogram name="Sync.DirectoryOpenFailedNotWinMac" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 11/2011. No longer tracked.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of failures trying to open the sync database on a non-windows non-mac
-    platform.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DirectoryOpenFailedWin" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 11/2011. No longer tracked.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of failures trying to open the sync database on windows.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DirectoryOpenResult" enum="SyncDirectoryOpenResult"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Tracks success of failure of sync directory initialization.</summary>
-</histogram>
-
-<histogram name="Sync.DirectoryVsPrefsConsistency"
-    enum="SyncDirectoryVsPrefsConsistency" expires_after="2020-06-25">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Whether the sync cache GUID and birthday are stored consistently across the
-    sync directory and prefs.
-  </summary>
-</histogram>
-
-<histogram name="Sync.DownloadedPasswordsCountWhenInitialMergeFails"
-    units="entries" expires_after="2020-04-01">
-  <obsolete>
-    Removed 01/2020. No longer tracked.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Counts the number of password updates downloaded in case of error during the
-    MergeSyncData(). This is introduced to detect if there is corrleation
-    between number of password updates and failure during merge. Recorded only
-    for USS implementation.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.DuplicateClientTagHashInApplyPendingUpdates"
-    enum="BooleanPresent" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-09 - we collected sufficient data, see crbug.com/995534.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Whether ModelTypeWorker received any duplicate client tag hashes within a
-    full GetUpdates cycle (which, in the case of pagination, might consist of
-    multiple individual GetUpdates responses).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.DuplicateClientTagHashInGetUpdatesResponse"
-    enum="BooleanPresent" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-09 - we collected sufficient data, see crbug.com/995531.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Whether ModelTypeWorker received any duplicate client tag hashes within a
-    single GetUpdates response (which, in the case of pagination, might be only
-    part of a full GetUpdates cycle).
-  </summary>
-</histogram>
-
-<histogram base="true"
-    name="Sync.DuplicateClientTagHashWithDifferentServerIdsInApplyPendingUpdates"
-    enum="BooleanPresent" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-09 - we collected sufficient data, see crbug.com/995528.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Whether ModelTypeWorker received any duplicate client tag hashes within a
-    full GetUpdates cycle that happen to have different server ids (which, in
-    the case of pagination, might consist of multiple individual GetUpdates
-    responses).
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.DuplicateServerIdInApplyPendingUpdates"
-    enum="BooleanPresent" expires_after="2019-09-30">
-  <obsolete>
-    Removed 2019-09 - we collected sufficient data, see crbug.com/995529.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Whether ModelTypeWorker received any duplicate server ids within a full
-    GetUpdates cycle (which, in the case of pagination, might consist of
-    multiple individual GetUpdates responses).
-  </summary>
-</histogram>
-
-<histogram name="Sync.EncryptAllData" units="units" expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m26.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Boolean histogram for whether the &quot;Encrypt all synced data&quot; radio
-    button was selected during sync setup. Samples are taken every time sync is
-    (re)configured, and the unique userid count shows how many users chose to
-    encrypt their sync data.
-  </summary>
-</histogram>
-
-<histogram name="Sync.EncryptEverythingWhenCryptographerNotReady"
-    enum="Boolean" expires_after="2020-02-01">
-  <obsolete>
-    Removed 02/2020, Sync.PassphraseType2 can give the same data in a better
-    way.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <owner>mamir@chromium.org</owner>
-  <summary>
-    Records EncryptEverything state when Nigori is not migrated to keystore and
-    cryptographer is not ready.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Entities.PositioningScheme" enum="SyncPositioningScheme"
-    expires_after="M85">
-  <obsolete>
-    Removed as of M85.
-  </obsolete>
-  <owner>mamir@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    The positioning scheme used within sync entities. It is reported for data
-    types migrated to USS only. While it is reported for all data types, the
-    positioning information are expected to be set for bookmarks only.
-    &quot;MISSING&quot; is reported only for non deleted bookmarks.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ExtensionAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during extension association (M18 and earlier were mispelled with
-    this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ExtensionRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of extension run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ExtensionSettingsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by ExtensionSettingsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of extension settings association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ExtensionsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by ExtensionsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of extension association failures.</summary>
-</histogram>
-
-<histogram name="Sync.ExtensionStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of extension association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ExtraSyncDataCount" units="entries"
-    expires_after="2018-07-26">
-  <obsolete>
-    Removed as of 07/2018. No longer tracked (because it is directory-specific
-    and related to now obsolete metrics Sync.ModelTypeCount).
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    Counts the total number of extra copies of sync data in memory. This count
-    is emitted once, after loading Sync Directory. The count will indicate how
-    many Directory entities fail to share client and server specifics.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.FaviconAvailability"
-    enum="FaviconAvailabilityStatus" expires_after="2019-07-10">
-  <obsolete>
-    Replaced by a Sync.SyncedHistoryFaviconAvailability in M77. Note: Last data
-    entries will be inconsistent since we keep recording this histogram while
-    behavior has not been changed for every SyncFaviconRequestOrigin histogram
-    suffix. In particular, Sync.FaviconAvailability.RECENTLY_CLOSED_TABS on
-    Android has always been recorded for remote only entries.
-  </obsolete>
-  <owner>victorvianna@google.com</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Records the availability status (local, sync or non-available) for each
-    favicon displayed by an interface. Recorded when the recent tabs menu is
-    opened or when a request is done to chrome://favicon by page url, which
-    happens for example for the chrome://history and chrome://history/syncedTabs
-    interfaces.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FaviconCacheLookupSucceeded" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Whether a sync favicon cache lookup succeeded or not.</summary>
-</histogram>
-
-<histogram name="Sync.FaviconCount" units="units" expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Number of synced favicons at initialization time.</summary>
-</histogram>
-
-<histogram name="Sync.FaviconImagesStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by FaviconImagesConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of favicon images association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FaviconsAvailableAtMerge" enum="SyncFaviconsAvailable"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of client that have filled their sync favicon cache and must evict
-    old favicons vs those whose cache is not full.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FaviconTrackingStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by FaviconTrackingConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of favicon tracking association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FaviconVisitPeriod" units="hours"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time between updates to a synced favicon's visit time.</summary>
-</histogram>
-
-<histogram name="Sync.FirstBackendInitializeSuccess" enum="BooleanSuccess"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 11/2011. Was counted incorrectly. Replaced by
-    Sync.BackendInitializeFirstTimeSuccess.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Tracks sync backend initialization success rate during initial sync setup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FirstSyncDelayByBackup" units="ms"
-    expires_after="2016-02-24">
-  <obsolete>
-    Backup logic has been removed since 02/2016.
-  </obsolete>
-  <owner>haitaol@chromium.org</owner>
-  <summary>First sync delay casued by backing up user data.</summary>
-</histogram>
-
-<histogram name="Sync.FreqApps" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for apps. Used as estimate of datatype commit frequency.
-    Logged when a sync cycle is performed for apps.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqAutofill" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for autofill entries. Used as estimate of datatype
-    commit frequency. Logged when a sync cycle is performed for autofill
-    entries.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqAutofillProfiles" units="ms"
-    expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for autofill profiles. Used as estimate of datatype
-    commit frequency. Logged when a sync cycle is performed for autofill
-    profiles.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqBookmarks" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for bookmarks. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for boomarks.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqDictionary" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for dictionary. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for dictionary.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqExtensions" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for extensions. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for extensions.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqFaviconImages" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for favicon images. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for favicon images.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqFaviconTracking" units="ms"
-    expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for favicon tracking. Used as estimate of datatype
-    commit frequency. Logged when a sync cycle is performed for favicon
-    tracking.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqNigori" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for nigori. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for nigori.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqPasswords" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for passwords. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for passwords.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqPreferences" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for preferences. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for preferences.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqSearchEngines" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for search engines. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for search engines.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqSessions" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for sessions. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for sessions.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqSyncedNotifications" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for synced notifications. Used as estimate of datatype
-    commit frequency. Logged when a sync cycle is performed for synced
-    notifications.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqThemes" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for themes. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for themes.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqTypedUrls" units="ms" expires_after="2018-03-02">
-  <obsolete>
-    Removed 03/2018 (M67). Replaced by Sync.SyncCycleInterval.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for typed urls. Used as estimate of datatype commit
-    frequency. Logged when a sync cycle is performed for typed urls.
-  </summary>
-</histogram>
-
-<histogram name="Sync.FreqWifiCredentials" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time between nudges for WiFi credentials. Used as estimate of datatype
-    commit frequency. Logged when a sync cycle is performed for WiFi
-    credentials.
-  </summary>
-</histogram>
-
-<histogram name="Sync.GlobalIdConflict" enum="SyncGlobalIdConflict"
-    expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Two navigations with different unique_ids shared a global_id/timestmap. This
-    means that user events will be ambiguously referencing navigations.
-  </summary>
-</histogram>
-
-<histogram name="Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailed"
-    enum="Boolean" expires_after="M81">
-  <obsolete>
-    Removed 02/2020. Instrumented in a wrong way and replaced by
-    Sync.NigoriConfigurationWithInvalidatedCredentials.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Recorded when Nigori-only configuration failed. Indicates whether there was
-    a valid access token when failure happened.
-  </summary>
-</histogram>
-
-<histogram
-    name="Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailedWith5SecBackoff"
-    enum="Boolean" expires_after="M81">
-  <obsolete>
-    Removed 02/2020. Instrumented in a wrong way and replaced by
-    Sync.NigoriConfigurationWithInvalidatedCredentials.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Recorded when Nigori-only configuration failed with 5 seconds backoff.
-    Indicates whether there was a valid access token when failure happened.
-  </summary>
-</histogram>
-
-<histogram name="Sync.InvalidationSessionsAndroid" enum="BooleanHit"
-    expires_after="2016-06-08">
-  <obsolete>
-    Removed as of 5/2016.
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Count of the number of session sync invalidations. The goal of the metric is
-    to track how the number of session sync invalidations changes over time.
-  </summary>
-</histogram>
-
-<histogram name="Sync.IsNigoriMigratedAfterMigration" enum="Boolean"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed as of 04/2020 because directory implementation of Nigori is no
-    longer used and enough data for corresponding investigation was recorded.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Indicates whether Nigori node state is migrated after the migration attempt.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Local.FileSize" units="KB" expires_after="M77">
-  <obsolete>
-    Removed as of 6/2019 in favor of Sync.Local.FileSizeKB.
-  </obsolete>
-  <owner>pastarmovj@chromium.org</owner>
-  <summary>Tracks the size of the local sync backend database file.</summary>
-</histogram>
-
-<histogram name="Sync.LocalDataFailedToLoad" enum="SyncModelTypes"
-    expires_after="2020-03-29">
-  <obsolete>
-    Removed 2019-09. Was only ever recorded for passwords.
-  </obsolete>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Counts cases when a sync type failed to load the local data during startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.LocalModelOutOfSync" enum="SyncModelTypes"
-    expires_after="M78">
-  <obsolete>
-    Removed 2019-09. Was only ever recorded for bookmarks.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Counts instances of out of sync local models detected during startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.LostNavigationCount" units="navigations"
-    expires_after="M72">
-  <obsolete>
-    Removed 2019-11.
-  </obsolete>
-  <owner>pnoland@chromium.org</owner>
-  <summary>
-    Counts instances of navigations that are recorded locally but not synced.
-    Recorded once per active tab for every inferred sync cycle. Sync cycles are
-    inferred by examining the is_synced and is_syncing flags of sync directories
-    when recording local changes to tabs or windows. Sync cycles that occur
-    without changes to tabs or windows won't cause this metric to be logged.
-  </summary>
-</histogram>
-
-<histogram name="Sync.MemoryPressureWarningBeforeCleanShutdown" units="count"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    Counts the number of times a user's sync service received a
-    MEMORY_PRESSURE_LEVEL_CRITICAL warning before the sync service shut down
-    cleanly. The sync service emits this number the next time the user's sync
-    service is started, which will likely happen the next time the user's
-    profile is opened after a Chrome restart. This count is emitted once per
-    user/profile. Things like browser crashes that implicitly bring down all
-    users' sync services will cause unclean shutdown tags to appear on all open
-    profiles, meaning that there will be multiple emissions to this histogram as
-    those profiles are re-opened.
-  </summary>
-</histogram>
-
-<histogram name="Sync.MemoryPressureWarningBeforeUncleanShutdown" units="count"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    Counts the number of times a user's sync service received a
-    MEMORY_PRESSURE_LEVEL_CRITICAL warning before the sync service shut down
-    uncleanly. The sync service emits this number the next time the user's sync
-    service is started, which will likely happen the next time the user's
-    profile is opened after a Chrome restart. This count is emitted once per
-    user/profile. Things like browser crashes that implicitly bring down all
-    users' sync services will cause unclean shutdown tags to appear on all open
-    profiles, meaning that there will be multiple emissions to this histogram as
-    those profiles are re-opened.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ModelTypeCount" units="entries"
-    expires_after="2018-07-26">
-  <obsolete>
-    Removed as of 7/2018. Replaced by Sync.ModelTypeCount2 which does record
-    data consistently for both directory data types and USS data types.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    Counts the number of entries for each model type in sync DB at startup.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.ModelTypeCount2" units="entries"
-    expires_after="2020-02-01">
-  <obsolete>
-    Removed as of 8/2018. Replaced by Sync.ModelTypeCount3 which fixes a bug in
-    recording the counts for USS data types
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    Counts the number of entries for each model type. For directory types, the
-    count is based on the directory contents, for USS types, the count is based
-    on metadata entries for the type. Recorded after sync configuration. This
-    metric is used for monitoring general health of sync client-side code.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.ModelTypeCount3" units="entries"
-    expires_after="2020-03-01">
-  <obsolete>
-    Removed as of 9/2018. Replaced by Sync.ModelTypeCount4 which fixes a
-    off-by-one bug that the root node get also recorded for directory data
-    types.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Counts the number of entries for each model type. For directory types, the
-    count is based on the directory contents, for USS types, the count is based
-    on metadata entries for the type. Recorded after sync configuration. This
-    metric is used for monitoring general health of sync client-side code.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.ModelTypeEntityChange"
-    enum="SyncEntityChange" expires_after="2020-02-01">
-  <obsolete>
-    Removed as of 10/2018. Replaced by Sync.ModelTypeEntityChange3 which splits
-    initial remote updates from incremental remote updates.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Recorded once for every sync entity change (whenever it is commited to the
-    server or updated from the server). This metric is used for monitoring
-    general health of sync client-side code. Note: This is only recorded with a
-    data type suffix. The base version is never recorded.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.ModelTypeEntityChange2"
-    enum="SyncEntityChange" expires_after="2020-04-01">
-  <obsolete>
-    Removed as of 11/2018. Replaced by Sync.ModelTypeEntityChange3 which fixes a
-    bug affecting a subset of datatypes (directory codepath).
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Recorded once for every sync entity change (whenever it is commited to the
-    server or updated from the server). This metric is used for monitoring
-    general health of sync client-side code. Note: This is only recorded with a
-    data type suffix. The base version is never recorded.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ModelTypeRedundantPut" enum="SyncModelTypes"
-    expires_after="2020-11-01">
-  <obsolete>
-    Removed as of 10/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Records the model type when a local change is made and sync optimized it
-    away because nothing actually changed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ModelTypeStoreCommitCount" enum="SyncModelTypes"
-    expires_after="2019-07-19">
-  <obsolete>
-    Removed as of 05/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records the number of write batches committed to leveldb
-    (ModelTypeStoreBackend) per datatype.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ModelTypeStoreInitResult"
-    enum="SyncModelTypeStoreInitResult" expires_after="M77">
-  <obsolete>
-    Removed in M78 after sufficient data was gathered.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records the result of ModelTypeStoreBackend initialization. Used to analyze
-    frequency and causes of backend initialization failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NigoriConfigurationWithInvalidatedCredentials"
-    enum="Boolean" expires_after="M82">
-  <obsolete>
-    Removed in M84 after corresponding investigation was completed.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Recorded when Nigori-only configuration pending while user credentials were
-    invalidated.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NigoriMigrationAttemptedBeforeNotMigrated" enum="Boolean"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed as of 04/2020 because directory implementation of Nigori is no
-    longer used and enough data for corresponding investigation was recorded.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records whether Nigori was attempted to migrate before recording migration
-    failure.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NigoriMigrationReason" enum="SyncNigoriMigrationReason"
-    expires_after="M84">
-  <obsolete>
-    Removed in M84 because directory implementation of Nigori is no longer used
-    and enough data for corresponding investigation was recorded.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records the condition, which triggered Nigori migration to keystore.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NigoriMigrationState" enum="SyncNigoriMigrationState"
-    expires_after="2020-05-31">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>mmoskvitin@google.com</owner>
-  <summary>Breakdown of sync's nigori node keystore migration state.</summary>
-</histogram>
-
-<histogram name="Sync.NigoriMigrationTrigger" enum="SyncNigoriMigrationTrigger"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed as of 04/2020 because directory implementation of Nigori is no
-    longer used and enough data for corresponding investigation was recorded.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Records the method, which triggered Nigori migration to keystore.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.NonGroupedInvalidation" enum="SyncModelTypes"
-    expires_after="M75">
-  <obsolete>
-    Was used during the launch to compare new and old implemetations.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    The number of invalidations received per sync data type for cases when only
-    single invalidation was emited by the invalidation component. In some cases
-    the invalidation component emits many invalidations grouped together, this
-    histogram doesn't track those cases.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Sync.NonGroupedInvalidationKnownVersion"
-    enum="SyncModelTypes" expires_after="M75">
-  <obsolete>
-    Was used during the launch to compare new and old implementations.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    The sync datatype of the recieved invalidation. Recorded only for the
-    invalidations with known version and recieved not in a group.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NonRedundantInvalidationPerModelType"
-    enum="SyncModelTypes" expires_after="M77">
-  <obsolete>
-    Deprecated in 10/2019. Was used during the launch of the new implementation.
-  </obsolete>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    WARNING: The recordings here are incorrect (crbug.com/1158476).
-
-    The sync datatype of the received invalidation with fresh version.
-  </summary>
-</histogram>
-
-<histogram name="Sync.NonReflectionUpdateFreshnessPossiblySkewed" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed as of 05/2019 because it recorded freshness only up to 1hr and most
-    samples were thus out of bounds. Replaced by
-    Sync.NonReflectionUpdateFreshnessPossiblySkewed2 which records freshness up
-    to 7 days.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>melandory@chromium.org</owner>
-  <summary>
-    Freshness of the sync data per received sync entity update, excluding
-    reflections. The time represents the clock difference from the model being
-    modified (usually on another device) until the change is processing by this
-    instance of the browser. Beware of potential clock skew due to two clients
-    being involved.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitBookmarksDuration" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The client side execution time to check for revisits with bookmarks data.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitBookmarksMatchAge" units="minutes"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    Age of bookmark that matches a navigation event, where matching means the
-    urls match. If multiple bookmarks match, the most recently created is used.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitBookmarksMatchTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type to a page that matched a bookmark.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitBookmarksMissTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type to a page that didn't match a bookmark.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitNavigationMatchAge" units="minutes"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    Difference in time between finding the match and the creation of the most
-    recent foreign modification of the parent tab. The parent tab's modification
-    will not always be indicative of when the matching navigation occurred.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitNavigationMatchOffset" units="units"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The number of navigations forward or backwards the matching noncurrent
-    navigation is from the current navigation in its tab. Negative values
-    represent backwards and positive values represent forwards. Zero should not
-    occur since it would cease to be noncurrent.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitNavigationMatchTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that matched a synced navigation.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitNavigationMissTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that didn't match a synced navigation.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitSessionDuration" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The client side execution time to check for revisits with session data.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTabMatchAge" units="minutes"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    Difference in time between finding the match and the creation of the most
-    recent foreign modification of the given tab.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTabMatchTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that matched a synced tab.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTabMissTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that didn't match a synced tab.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTypedUrlDuration" units="ms"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    The client side execution time to check for revisits with typed URL data.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTypedUrlMatchAge" units="minutes"
-    expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    Difference in time between finding the match and the last time this URL was
-    typed on a foreign client.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTypedUrlMatchTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that matched a typed URL.</summary>
-</histogram>
-
-<histogram name="Sync.PageRevisitTypedUrlMissTransition"
-    enum="PageVisitTransitionType" expires_after="2018-02-21">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Transition type that didn't match a typed URL.</summary>
-</histogram>
-
-<histogram name="Sync.PartiallySyncedTypes" units="units" expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of partially synced types (those with a progress marker but no
-    initial sync ended bit) that exist at sync startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PassphraseDecryptionSucceeded" enum="BooleanSuccess"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Whether a passphrase decryption attempt succeeded or not.</summary>
-</histogram>
-
-<histogram name="Sync.PassphraseDialogDismissed" enum="SyncPassphraseDismissal"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of how a user dismissed the passphrase dialog.</summary>
-</histogram>
-
-<histogram name="Sync.PasswordAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during password association (M18 and earlier were mispelled with
-    this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.PasswordRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of passwords run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.PasswordsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by PasswordsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of password association failures.</summary>
-</histogram>
-
-<histogram name="Sync.PasswordStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of password association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.PreferenceAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during preference association (M18 and earlier were mispelled
-    with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.PreferenceRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of preferences run failures, used to compare failure rates between
-    data types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.Preferences.RemotePrefTypeMismatch" enum="BooleanHit"
-    expires_after="M85">
-  <obsolete>
-    Removed 2020-06.
-  </obsolete>
-  <owner>tschumann@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Counts the number of times a client received a remote pref update with a
-    value type different from the registered pref type. The client will ignore
-    those remote updates.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Preferences.SyncingUnknownPrefs" units="prefs"
-    expires_after="M80">
-  <obsolete>
-    Removed in M79 because support for lazy pref registration was removed.
-  </obsolete>
-  <owner>tschumann@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of unknown prefs being synced. This number is computed after the
-    sync model has been associated. Preferences which get handled by sync even
-    before being registered are considered &quot;unknown&quot;. This might be
-    limited to a whitelist of preferences.
-  </summary>
-</histogram>
-
-<histogram name="Sync.PreferencesStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by PreferencesConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of preference association failures.</summary>
-</histogram>
-
-<histogram name="Sync.PreferenceStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of preference association failures (M18 and earlier
-    were mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ReauthorizationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time taken from startup for the user to reauthorize.</summary>
-</histogram>
-
-<histogram base="true" name="Sync.ReceivedDataTypeGetUpdatesResponseWithToken"
-    enum="SyncGetUpdatesToken" expires_after="2019-06-01">
-  <obsolete>
-    Removed 05/2019.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Recorded for each GetUpdates response (and each data type included). Records
-    whether the newly received token is new (as this data type had none before)
-    or whether it is the same as before or whether it has changed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.RefreshTokenAvailable" enum="BooleanSuccess"
-    expires_after="2016-04-05">
-  <obsolete>
-    Removed 04/2016 as not useful since it always logged true.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Whether OAuth2 refresh token was available at the time when SyncServiceImpl
-    was starting backend.
-  </summary>
-</histogram>
-
-<histogram name="Sync.RequestContentLength.Compressed" units="bytes"
-    expires_after="2019-04-10">
-  <obsolete>
-    Deleted in M75, Issue 900075.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    The request content size for a single HTTP/HTTPS call from sync client to
-    server. The content is compressed by gzip.
-  </summary>
-</histogram>
-
-<histogram name="Sync.RequestContentLength.Original" units="bytes"
-    expires_after="2019-04-10">
-  <obsolete>
-    Deleted in M75, Issue 900075.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    The original request content size for a single HTTP/HTTPS call from sync
-    client to server. It is the size before content got compressed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.RequestGroupSizeForSyncedHistoryFavicons" units="units"
-    expires_after="2020-08-17">
-  <obsolete>
-    Deleted in M84.
-  </obsolete>
-  <owner>victorvianna@google.com</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Records the number of active requests simultaneously done to the Google
-    favicon server that were associated with a same icon url and could have thus
-    been grouped. Recorded when one of the following is displayed: entries in
-    chrome://history that are known to be present in remote history data; all
-    entries in chrome://history/syncedTabs; tabs from other devices in the 3
-    dots history menu (desktop); tabs from other devices in the android Recent
-    Tabs UI.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ResolveConflict" enum="SyncConflictResolutions"
-    expires_after="M82">
-  <obsolete>
-    Deleted 2020-02.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Enumeration of types of conflict resolutions. Recorded every time a conflict
-    is resolved for a data type that has been converted to USS.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ResolveSimpleConflict"
-    enum="SyncSimpleConflictResolutions" expires_after="2020-06-24">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>Enumeration of types of simple conflict resolutions.</summary>
-</histogram>
-
-<histogram name="Sync.ResponseContentLength.Compressed" units="bytes"
-    expires_after="2019-04-10">
-  <obsolete>
-    Deleted in M75, Issue 900073.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    The response content size for a single HTTP/HTTPS call from sync server to
-    client. The content is compressed by gzip.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ResponseContentLength.Original" units="bytes"
-    expires_after="2019-04-10">
-  <obsolete>
-    Deleted in M75, Issue 900073.
-  </obsolete>
-  <owner>gangwu@chromium.org</owner>
-  <summary>
-    The original response content size for a single HTTP/HTTPS call from sync
-    server and client. It is the size after content got uncompressed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.RestoreBackendInitializeSucess" enum="BooleanSuccess"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 11/2011. Was counted incorrectly. Replaced by
-    Sync.BackendInitializeRestoreSuccess.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Tracks sync backend initialization success rate in cases where sync was
-    previously initialized.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SearchEngineAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during search engine association (M18 and earlier were mispelled
-    with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.SearchEngineRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of search engine run failures, used to compare failure rates between
-    data types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.SearchEnginesStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by SearchEnginesConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of search engine association failures.</summary>
-</histogram>
-
-<histogram name="Sync.SearchEngineStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of search engine association failures (M18 and earlier
-    were mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ServiceInitialConfigureTime" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Initial.{OK, ABORTED, UNRECOVERABLE_ERROR} in
-    M75 when solving bug 169053.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent on first-time configure. May include time spent on retries.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ServiceSubsequentConfigureTime" units="ms"
-    expires_after="2019-04-09">
-  <obsolete>
-    Replaced by Sync.ConfigureTime_Subsequent.{OK, ABORTED, UNRECOVERABLE_ERROR}
-    in M75 when solving bug 169053.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time spent on non-first-time configure. May include time spent on retries.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during session association (M18 and earlier were mispelled with
-    this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of sessions run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionsBadForeignHashOnMergeCount"
-    units="Sessions Entries" expires_after="M85">
-  <obsolete>
-    Removed as of 2018-11.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Number of foreign sessions entries detected with bad client tag hash value
-    during MergeDataAndStartSyncing. These will be immediately deleted. The
-    overwhelming majority of clients should report a value of 0 upon startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionsRefreshDelay" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Delay from the time chrome://history is loaded until the other devices'
-    sessions data became available.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by SessionsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of session association failures.</summary>
-</histogram>
-
-<histogram name="Sync.SessionStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of session association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.SessionWindows" units="windows" expires_after="M85">
-  <obsolete>
-    Removed as of 2018-11.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The number of windows present within Chrome at the time Sync associates the
-    SESSIONS datatype.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SesssionsDuplicateSyncId" units="count"
-    expires_after="2018-06-19">
-  <obsolete>
-    Removed in M69.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    https://crbug.com/639009, count of duplicate sync ids (tab node id) when any
-    are encountered. Likely caused from a persistence race between native tab
-    storage and sync db on Android. Should be trending to zero.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ShouldTriggerMigrationAfterMigration" enum="Boolean"
-    expires_after="M84">
-  <obsolete>
-    Removed in M84 because directory implementation of Nigori is no longer used
-    and enough data for corresponding investigation was recorded.
-  </obsolete>
-  <owner>mmoskvitin@google.com</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Indicates that Nigori would be migrated again right after migration if
-    AttemptToMigrateNigoriToKeystore called.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Shutdown.BackendDestroyedTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken from the start of sync shutdown (in SyncServiceImpl) until the
-    backend (SyncEngine) is fully destroyed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Shutdown.StopRegistrarTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Amount of time the UI thread waits (at shutdown) to stop the
-    SyncBackendRegistrar.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Shutdown.StopSyncThreadTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Amount of time the UI thread waits (at shutdown) to stop the sync thread.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SizeOfFaviconServerRequestGroup" units="units"
-    expires_after="2019-07-10">
-  <obsolete>
-    Replaced by Sync.RequestGroupSizeForSyncedHistoryFavicons in M77.
-  </obsolete>
-  <owner>victorvianna@google.com</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Records the number of active requests simultaneously done to the Google
-    favicon server that were associated with a same icon url and could have thus
-    been grouped. Recorded when opening the recent tabs menu, chrome://history
-    or chrome://history/syncedTabs with both history sync and the
-    EnableHistoryFaviconsGoogleServerQuery feature enabled.
-  </summary>
-</histogram>
-
-<histogram name="Sync.Startup.TimeDeferred" units="ms"
-    expires_after="2014-03-18">
-  <obsolete>
-    Removed, see TimeDeferred2.
-  </obsolete>
-  <owner>jeremy@chromium.org</owner>
-  <owner>zea@google.com</owner>
-  <summary>
-    Time spent after SyncServiceImpl *creation* but before SyncEngine
-    initialization.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SyncAuthError" enum="SyncAuthError"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Counts the number of times sync clients have encountered an auth error and
-    number of times auth errors are fixed.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SyncCycleInterval" units="ms" expires_after="2019-03-12">
-  <obsolete>
-    Removed 2019-03.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The interval between successive sync cycles. Recorded whenever a sync cycle
-    starts, except for the very first one after Chrome startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SyncedNotificationsStartFailure" enum="SyncStartResult"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53. Replaced by SyncedNotificationsConfigureFailure. See
-    crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of synced notifications association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SyncerConflictStuck" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed 12/2011. No longer tracked. See crbug.com/107816.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Number of times the sync conflict resolver gets stuck. This is not expected
-    to be hit anymore.
-  </summary>
-</histogram>
-
-<histogram name="Sync.SyncEverything" units="units" expires_after="2018-10-22">
-  <obsolete>
-    Removed 10/2018, replaced by Sync.SyncEverything2.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Boolean histogram for whether the &quot;Sync Everything&quot; option was
-    selected during sync setup. Samples are taken every time sync is
-    (re)configured, and the unique userid count shows how many users chose to
-    sync all available data types.
-  </summary>
-</histogram>
-
-<histogram name="Sync.ThemeAssociationTime" units="ms"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during theme association (M18 and earlier were mispelled with
-    this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ThemeRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of theme run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.ThemesStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by ThemesConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of theme association failures.</summary>
-</histogram>
-
-<histogram name="Sync.ThemeStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of theme association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Time taken during typed url association (M18 and earlier were mispelled with
-    this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlChangeProcessorErrors" units="%"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    The percentage of history DB operations initiated by the typed URL change
-    processor that return an error. The cumulative count for the current sync
-    session is logged after every typed URL change.
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlMergeAndStartSyncingErrors" units="%"
-    expires_after="2020-05-08">
-  <obsolete>
-    Removed 2020-05.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    The percentage of history DB operations during merge data that return an
-    error. This is logged at the end of typed URL merge data, which happens once
-    each time sync starts up.
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlModelAssociationErrors" units="%"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    The percentage of history DB operations during model association that return
-    an error. This is logged at the end of typed URL model association, which
-    happens once each time sync starts up.
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlRunFailures" units="units"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Count of typed url run failures, used to compare failure rates between data
-    types for a particular profile (see other Sync*RunFailures histograms).
-  </summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by TypedUrlsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Enumeration of types of typed url association failures.</summary>
-</histogram>
-
-<histogram name="Sync.TypedUrlStartFailures" enum="SyncStartResult"
-    expires_after="2014-02-28">
-  <obsolete>
-    Removed as of m19.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of typed url association failures (M18 and earlier were
-    mispelled with this histogram).
-  </summary>
-</histogram>
-
-<histogram name="Sync.UnrecoverableErrors" enum="SyncUnrecoverableErrorReason"
-    expires_after="M85">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Enumeration of the different reasons for unrecoverable errors and how often
-    they have occurred.
-  </summary>
-</histogram>
-
-<histogram name="Sync.UserPerceivedAuthorizationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time the user spends looking at the authorization dialog.</summary>
-</histogram>
-
-<histogram name="Sync.UserPerceivedBookmarkAssociation" units="units"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time taken during bookmark association.</summary>
-</histogram>
-
-<histogram name="Sync.USSLoadModelsTime" units="ms" expires_after="M81">
-  <obsolete>
-    Removed in M82.
-  </obsolete>
-  <owner>pavely@chromium.org</owner>
-  <summary>Time it took sync to load models for USS datatypes.</summary>
-</histogram>
-
-<histogram base="true" name="Sync.USSMigrationEntityCount" units="entries"
-    expires_after="2020-05-20">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Counts the number of sync entities per model type successfully migrated from
-    directory to USS.
-  </summary>
-</histogram>
-
-<histogram name="Sync.USSMigrationFailure" enum="SyncModelTypes"
-    expires_after="2020-05-20">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>Counts directory to USS migration failures per model type.</summary>
-</histogram>
-
-<histogram name="Sync.USSMigrationSuccess" enum="SyncModelTypes"
-    expires_after="2020-05-20">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>Counts directory to USS migration successes per model type.</summary>
-</histogram>
-
-<histogram name="Sync.Wallet.EntitiesClearedWhenDisabled" units="entities"
-    expires_after="M74">
-  <obsolete>
-    Removed as of 05/2019.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>feuunk@chromium.org</owner>
-  <summary>
-    Counts number of data entities that are removed when sync / Wallet sync gets
-    disabled.
-  </summary>
-</histogram>
-
-<histogram name="Sync.WalletDataModelTypeProcessorErrors"
-    enum="ClientTagBasedModelTypeProcessorErrors" expires_after="2020-06-30">
-  <obsolete>
-    Removed as of 2020-03.
-  </obsolete>
-  <owner>rushans@google.com</owner>
-  <owner>jkrcal@chromium.org</owner>
-  <summary>
-    Records errors with storage keys in ClientTagBasedModelTypeProcessor during
-    updates and loading of metadata for AUTOFILL_WALLET_DATA data type.
-  </summary>
-</histogram>
-
-<histogram name="Sync.WalletMetadata.DeletedOldOrphans" units="entities"
-    expires_after="M76">
-  <obsolete>
-    Removed as of 2019-08.
-  </obsolete>
-  <owner>jkrcal@chromium.org</owner>
-  <owner>mastiz@chromium.org</owner>
-  <summary>
-    Counts number of old orphan metadata entities that are removed on startup.
-  </summary>
-</histogram>
-
-<histogram name="Sync.WifiCredentialsAssociationTime" units="ms"
-    expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>Time taken during WiFi credentials association.</summary>
-</histogram>
-
-<histogram name="Sync.WifiCredentialsConfigureFailure"
-    enum="SyncConfigureResult" expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of WiFi credentials configuration failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.WifiCredentialsStartFailure" enum="SyncStartResult"
-    expires_after="2015-04-20">
-  <obsolete>
-    Replaced by WifiCredentialsConfigureFailure. See crbug.com/478226.
-  </obsolete>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    Enumeration of types of WiFi credentials association failures.
-  </summary>
-</histogram>
-
-<histogram name="Sync.WorkerApplyHasEncryptedUpdates" enum="Boolean"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed in M67. After more than a year, almost all clients are reporting
-    FALSE.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>
-    Whether there are still encrypted updates that the cryptographer cannot
-    decrypt during ApplyUpdates in the ModelTypeWorker (USS Only). Emitting true
-    is an invalid state that hopefully never happens, as it is a potential data
-    loss scenario.
-  </summary>
-</histogram>
-
-<histogram name="Sync.YoungestForeignTabAgeOnNTP" units="seconds"
-    expires_after="2018-02-22">
-  <obsolete>
-    Removed in M66.
-  </obsolete>
-  <owner>skym@chromium.org</owner>
-  <summary>Upon NTP load, the age of the youngest synced foreign tab.</summary>
-</histogram>
-
-<histogram name="SyncedNotifications.Actions"
-    enum="SyncedNotificationActionType" expires_after="2016-06-20">
-  <obsolete>
-    Removed in M53.
-  </obsolete>
-  <owner>petewil@chromium.org</owner>
-  <owner>zea@chromium.org</owner>
-  <summary>
-    The actions taken on synced notifications, recorded every time they happen.
-    This histogram will record every single event that happens separately.
-  </summary>
-</histogram>
-
-<histogram name="SyncPromo.NTPPromo" enum="SyncPromoAction"
-    expires_after="2020-03-01">
-  <obsolete>
-    Removed 06/2019.
-  </obsolete>
-  <owner>dbeam@chromium.org</owner>
-  <summary>
-    Shows actions taken on the &quot;Not signed in? You're misssing out&quot;
-    link on the top right of chrome://apps. Logged once per visit of
-    chrome://apps as well as on each click of the sync promo.
-  </summary>
-</histogram>
-
-<histogram name="Syzyasan.DeferredFreeWasEnabled" enum="BooleanEnabled"
-    expires_after="M85">
-  <obsolete>
-    Removed 03/2018. SyzyAsan has been deprecated.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Record whether the deferred free mechanism was successfully enabled or not.
-    This is only recorded in syzyasan builds with the feature enabled.
-  </summary>
-</histogram>
-
-<histogram name="Tab.BackgroundTabShown" enum="BooleanShown"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Whether a tab which was opened in the background (e.g. via &quot;Open link
-    in new tab&quot;) is foregrounded prior to being closed.
-  </summary>
-</histogram>
-
-<histogram name="Tab.BackgroundTabsOpenedViaContextMenuCount" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Counts the number of background tabs opened via the context menu per page
-    URL. The count is reset on each navigation of the parent tab. Zero counts
-    are not recorded.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Close" units="ms" expires_after="2019-01-15">
-  <obsolete>
-    Removed 01/2019.
-  </obsolete>
-  <summary>
-    Time in milliseconds from trying to close the tab to actually closing it.
-    Includes time that's spent in JS OnUnload handlers.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Close.UnloadTime" units="ms" expires_after="2019-01-15">
-  <obsolete>
-    Removed 01/2019.
-  </obsolete>
-  <summary>
-    Time in milliseconds from when JS OnUnload handlers have finished to
-    actually closing tab. Doesn't include time that's spent in JS OnUnload
-    handlers. If there are no UnLoad handlers, should be identical to Tab.Close.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Deactivation.Bookmarked" enum="Boolean"
-    expires_after="2016-11-11">
-  <obsolete>
-    Removed 11/2016. No longer useful after finding out that it has no effect on
-    tab reactivation rates.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was deactivated. Closing tabs are not included. This histogram also
-    records if the tab's URL was bookmarked.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Deactivation.HadFormInteraction" enum="Boolean"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was deactivated. Closing tabs are not included. This histogram also
-    records if the tab had any form interaction.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Deactivation.Pinned" enum="Boolean"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was deactivated. Closing tabs are not included. This histogram also
-    records if the tab was pinned to the tab strip or not.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Discarding" enum="TabDiscardingEvents"
-    expires_after="2015-10-06">
-  <obsolete>
-    Removed 10/2015, not needed anymore.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Metric to track counts of actions related to tab discarding. Namely, we get
-    an event for every tab switch, split into two groups, whether it was a
-    discarded tab not. We also get an event whenever a tab gets discarded as
-    well as when a tab that's playing audio gets discarded.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Discarding.DiscardCount" units="Discards"
-    expires_after="2015-10-06">
-  <obsolete>
-    Removed 10/2015, and replaced by TabManager.Discarding.DiscardCount.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Metric to track the number of discards tabs have gone through. Each time a
-    tab is discarded, this histogram is recorded. Therefore, this metric is
-    cumulative, ie. as a tab gets discarded over and over, it gets a hit in each
-    bin (1, 2, 3...).
-  </summary>
-</histogram>
-
-<histogram name="Tab.EvictedTabWasActive" enum="Boolean"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    [iOS] When switching to an evicted tab, this histogram records whether or
-    not the tab had ever been active. For example, the tab was opened via
-    &quot;Open in new tab&quot; but evicted before being viewed for the first
-    time.
-  </summary>
-</histogram>
-
-<histogram name="Tab.FormActivityCountEvictedHistogram" units="units"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    A count of form activity (e.g. fields selected, characters typed) in a tab.
-    Recorded only for tabs that are evicted due to memory pressure and then
-    selected again.
-  </summary>
-</histogram>
-
-<histogram name="Tab.LostTabAgeWhenSwitchedToForeground" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    [Android] When a tab that was opened in the background (e.g. via &quot;Open
-    link in new tab&quot;) is evicted prior to the first time that it is shown,
-    we record the tab's age at the time that the tab is shown.
-  </summary>
-</histogram>
-
-<histogram name="Tab.NewTabDOMContentLoaded" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 07/2020, no longer used.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    The time for the new tab page to fire the &quot;DOMContentLoaded&quot;
-    event.
-  </summary>
-</histogram>
-
-<histogram name="Tab.NewTabScriptStart" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 07/2020, no longer used.
-  </obsolete>
-  <owner>kmilka@chromium.org</owner>
-  <owner>ramyan@chromium.org</owner>
-  <summary>
-    The time for the new tab page to start executing JavaScript.
-  </summary>
-</histogram>
-
-<histogram name="Tab.OpenedPopup.PopupToCrossOriginRedirectTime" units="ms"
-    expires_after="2017-10-05">
-  <obsolete>
-    Removed in favor of Tab.TabUnder.PopupToTabUnderTime.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the time from when a tab opens a popup to when it navigates itself
-    cross-origin in the background.
-  </summary>
-</histogram>
-
-<histogram name="Tab.OpenedPopup.VisibleTimeAfterCrossOriginRedirect"
-    units="ms" expires_after="2017-10-05">
-  <obsolete>
-    Removed in favor of Tab.TabUnder.VisibleTime.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the total time a tab is visible after it navigates itself
-    cross-origin in the background. Measured at WebContents destruction. The tab
-    must have opened a popup (as classified by the popup blocker) before the
-    navigation.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Reactivation.Bookmarked" enum="Boolean"
-    expires_after="2016-11-11">
-  <obsolete>
-    Removed 11/2016. No longer useful after finding out that it has no effect on
-    tab reactivation rates.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was reactivated after being hidden. This histogram also records if the
-    tab's URL was bookmarked.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Reactivation.HadFormInteraction" enum="Boolean"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was reactivated after being hidden. This histogram also records if the
-    tab had any form interaction.
-  </summary>
-</histogram>
-
-<histogram name="Tab.Reactivation.Pinned" enum="Boolean"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    A tab was reactivated after being hidden. This histogram also records if the
-    tab was pinned to the tab strip.
-  </summary>
-</histogram>
-
-<histogram name="Tab.StatusWhenDisplayed" enum="TabStatus"
-    expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    The status of a tab collected each time the tab is displayed on Android,
-    including user switching to the tab and displays of newly created tabs, such
-    as NTP or tabs opened to handle intents.
-  </summary>
-</histogram>
-
-<histogram name="Tab.StatusWhenSwitchedBackToForegroundDataProxyEnabled"
-    enum="TabStatus" expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <owner>marq@chromium.org</owner>
-  <summary>
-    [Android and iOS] The status of a tab collected each time the user switches
-    to it on mobile with the data reduction proxy enabled. This is populated
-    identically, and in addition to Tab.StatusWhenSwitchedBackToForeground for
-    any given tab switching event if the proxy is enabled.
-  </summary>
-</histogram>
-
-<histogram name="Tab.SwitchedToForegroundLaunchedWithURL"
-    enum="TabSwitchedToForegroundLaunchedWithURL" expires_after="2014-04-14">
-  <obsolete>
-    Removed as of 04/2014.
-  </obsolete>
-  <summary>
-    Each time a tab is brought to the foreground, this histogram indicates if
-    chrome was launched without an URL (i.e., from the launcher), or with an URL
-    (i.e., from another app).
-  </summary>
-</histogram>
-
-<histogram name="Tab.SwitchedToForegroundMRURank" units="units"
-    expires_after="2014-04-14">
-  <obsolete>
-    Removed as of 04/2014.
-  </obsolete>
-  <summary>
-    Rank in MRU order (0 being first) when the tab was switched to foreground.
-  </summary>
-</histogram>
-
-<histogram name="Tab.SwitchedToForegroundNumTabs" units="units"
-    expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>Count of all tabs when a tab is switched.</summary>
-</histogram>
-
-<histogram name="Tab.SwitchedToForegroundRevisit"
-    enum="TabSwitchedToForegroundRevisit" expires_after="2014-04-14">
-  <obsolete>
-    Removed as of 04/2014.
-  </obsolete>
-  <summary>
-    Each time a tab is brought to the foreground, this histogram indicates if
-    this is the first viewing of the tab since Chrome was put into foreground,
-    or if it was a return to a tab that has already been shown in this session.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TabUnder.EngagementScore" units="engagement score"
-    expires_after="2018-08-07">
-  <obsolete>
-    Removed August 2018
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the engagement score associated with the URL that is detected as
-    the target of a tab-under navigation.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TimeSinceActive" units="ms" expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    [iOS] When an existing tab becomes active, this histogram records the time
-    since it was made inactive.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TimeSinceActiveEvicted" units="ms"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    [iOS] When an evicted tab becomes active, this histogram records the time
-    since it was made inactive.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TimeSinceFormActivityEvictedHistogram" units="ms"
-    expires_after="2016-10-06">
-  <obsolete>
-    Removed as of 10/2016.
-  </obsolete>
-  <summary>
-    Time elapsed since there was form activity (e.g. fields selected, characters
-    typed) in a tab. Recorded only for tabs that are evicted due to memory
-    pressure and then selected again.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TimeToReactivation.Important" units="ms"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The time elapsed from the moment a tab was deactivated until it was
-    reactivated. Only recorded for tabs that are pinned or had form interaction.
-  </summary>
-</histogram>
-
-<histogram name="Tab.TimeToReactivation.Normal" units="ms"
-    expires_after="2019-07-23">
-  <obsolete>
-    No longer recorded.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The time elapsed from the moment a tab was deactivated until it was
-    reactivated. Only recorded for tabs that are not pinned nor had form
-    interaction.
-  </summary>
-</histogram>
-
-<histogram name="Tab.VisibleTimeAfterCrossOriginRedirect" units="ms"
-    expires_after="2017-10-05">
-  <obsolete>
-    This metric was deprecated in favor of just using Tab.TabUnder.VisibleTime
-    directly. Consider bringing it back if we care about visible time after a
-    suspicious redirect without an associated popup.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    Measures the total time a tab is visible after it navigates itself
-    cross-origin in the background. Measured at WebContents destruction.
-  </summary>
-</histogram>
-
-<histogram
-    name="TabManager.BackgroundTabOpening.ForegroundTab.ExpectedTaskQueueingDuration"
-    units="ms" expires_after="M79">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The expected queueing duration of tasks in a foreground tab during a
-    background tab opening session (the duration of time from when the browser
-    starts to open background tabs until the time the browser has finished
-    loading those tabs or otherwise decided to stop loading them). The metric
-    reflects the responsiveness of a tab. A lower value means the tab will
-    respond to inputs faster. This metric is equivalent to
-    RendererScheduler.ExpectedTaskQueueingDuration. It is emitted once for all
-    tasks in each 1000-ms window. The metric is not recorded when the session
-    overlaps with session restore.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.DiscardedEngagementScore" units="units"
-    expires_after="2017-11-21">
-  <obsolete>
-    Removed 11/2017. Analysis showed that MRU was as good as engagement score to
-    choose which tabs to discard. The new plan is to build a machine learning
-    model to choose which tabs to discard.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Site engagement score of a discarded tab. Recorded for each discard if the
-    score is available.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.LocalDatabase.DatabaseInit"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="2018-07-10">
-  <obsolete>
-    Removed 07/2018, and replaced by ResourceCoordinator.LocalDB.DatabaseInit.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.LocalDatabase.DatabaseInitAfterDelete"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="2018-07-10">
-  <obsolete>
-    Removed 07/2018, and replaced by
-    ResourceCoordinator.LocalDB.DatabaseInitAfterDelete.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database after deleting
-    it after a failed repair attempt.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.LocalDatabase.DatabaseInitAfterRepair"
-    enum="LocalSiteCharacteristicsDBInitStatus" expires_after="2018-07-10">
-  <obsolete>
-    Removed 07/2018, and replaced by
-    ResourceCoordinator.LocalDB.DatabaseInitAfterRepair.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of opening the Local Site Characteristics database after a repair
-    attempt.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.LocalDatabase.DatabaseRepair"
-    enum="BooleanSuccess" expires_after="2018-07-10">
-  <obsolete>
-    Removed 07/2018, and replaced by ResourceCoordinator.LocalDB.DatabaseRepair.
-  </obsolete>
-  <owner>sebmarchand@chromium.org</owner>
-  <summary>
-    The result of trying to repair the Local Site Characteristics database after
-    a failed open.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.LogMemoryTime" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019, check Arc.LowMemoryKiller.FirstKillLatency instead.
-  </obsolete>
-  <owner>cywang@chromium.org</owner>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Elapsed time to collect memory usage of each tab triggered by a LogMemory()
-    call().
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Discarding.ReloadedEngagementScore" units="units"
-    expires_after="2017-11-21">
-  <obsolete>
-    Removed 11/2017. Analysis showed that MRU was as good as engagement score to
-    choose which tabs to discard. The new plan is to build a machine learning
-    model to choose which tabs to discard.
-  </obsolete>
-  <owner>georgesak@chromium.org</owner>
-  <summary>
-    Site engagement score of a reloaded tab. Recorded for each reload if the
-    score is available. Note that this will be the same score the tab had when
-    discarded (which could have changed by the time it gets reloaded).
-  </summary>
-</histogram>
-
-<histogram
-    name="TabManager.Experimental.BackgroundTabOpening.TabSwitchLoadTime"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.BackgroundTabOpening.TabSwitchLoadTime.UntilTabIsLoaded.
-  </obsolete>
-  <owner>zhenw@chromium.org</owner>
-  <summary>
-    The tab load time of a tab that is switched to during a background tab
-    opening session (the duration of time from when the browser starts to open
-    background tabs until the time the browser has finished loading those tabs
-    or otherwise decided to stop loading them). Tab load time is defined as the
-    time between when the user switches to a backround tab, and the time when
-    that tab finishes loading in the foreground. If the user switches away
-    before the tab finishes loading, a metric will not be recorded unless the
-    user switches back, in which case the tab load time is measured from that
-    point in time. The metric is only recorded when a tab is switched to from
-    another tab within the same tabstrip. As a result, the initial forground tab
-    is not included in this metric since it was not switched to from another
-    tab. The metric is not recorded when the session overlaps with session
-    restore.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Experimental.SessionRestore.TabSwitchLoadTime"
-    units="ms" expires_after="2017-08-31">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.SessionRestore.TabSwitchLoadTime.UntilTabIsLoaded.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The tab load time of a tab that is switched to during a session restore. Tab
-    load time is defined as the time between when the user switches to a
-    backround tab, and the time when that tab finishes loading in the
-    foreground. If the user switches away before the tab finishes loading, a
-    metric will not be recorded unless the user switches back, in which case the
-    tab load time is measured from that point in time. The metric is only
-    recorded when a tab is switched to from another tab within the same
-    tabstrip. As a result, the initial forground tab is not included in this
-    metric since it was not switched to from another tab. The metric is only
-    recorded when session restore is actively loading tabs, which ends when
-    either all tabs have been loaded and their pages rendered, or tab loading
-    needs to be deferred in cases where the system is under memory pressure. The
-    metric is not recorded when the session overlaps with background tab opening
-    session.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Heuristics.FromBackgroundedToFirstAlertFired"
-    units="ms" expires_after="2019-01-21">
-  <obsolete>
-    Removed on 21/1/2019.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    Measures the time duration from when the tab is backgrounded to when a
-    JavaScript alert is updated. Only recorded when the tab is in the
-    background.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Heuristics.FromBackgroundedToFirstAudioStarts"
-    units="ms" expires_after="2019-01-21">
-  <obsolete>
-    Removed on 21/1/2019.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <owner>lpy@chromium.org</owner>
-  <summary>
-    Measures the time duration from when the tab is backgrounded to when audio
-    starts to play. Only recorded when the tab is in the background.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.SessionRestore.CompressedPagesPerSecond"
-    units="pages/s" expires_after="2017-08-30">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.SessionRestore.CompressedPagesPerSecond.
-  </obsolete>
-  <owner>fmeawad@chromium.org</owner>
-  <summary>
-    The number of pages compressed per second during session restore. Recorded
-    at the end of session restore as an average over the entire period, defined
-    as the period of time when session restore is actively loading tabs, which
-    ends when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. Only recorded on macOS.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.SessionRestore.DecompressedPagesPerSecond"
-    units="pages/s" expires_after="2017-08-30">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.SessionRestore.DecompressedPagesPerSecond.
-  </obsolete>
-  <owner>fmeawad@chromium.org</owner>
-  <summary>
-    The number of pages decompressed per second during session restore. Recorded
-    at the end of session restore as an average over the entire period, defined
-    as the period of time when session restore is actively loading tabs, which
-    ends when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. Only recorded on macOS.
-  </summary>
-</histogram>
-
-<histogram
-    name="TabManager.SessionRestore.ForegroundTab.ExpectedTaskQueueingDuration"
-    units="ms" expires_after="M79">
-  <obsolete>
-    Removed June 2020.
-  </obsolete>
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The expected queueing duration of tasks in a foreground tab during session
-    restore. This metric reflects the responsiveness of a tab. A lower value
-    means the tab will respond to inputs faster. This metric is equal to
-    RendererScheduler.ExpectedTaskQueueingDuration. It is emitted once for all
-    tasks in each 1000-ms window. The metric is not recorded when the session
-    overlaps with background tab opening session.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.SessionRestore.SwapInPerSecond" units="swaps/s"
-    expires_after="2017-08-30">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.SessionRestore.SwapInPerSecond.
-  </obsolete>
-  <owner>fmeawad@chromium.org</owner>
-  <summary>
-    The number of swap-ins per second during session restore. Recorded at the
-    end of session restore as an average over the entire period, defined as the
-    period of time when session restore is actively loading tabs, which ends
-    when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.SessionRestore.SwapOutPerSecond" units="swaps/s"
-    expires_after="2017-08-30">
-  <obsolete>
-    Removed 08/2017, and replaced by
-    TabManager.Experimental.SessionRestore.SwapOutPerSecond.
-  </obsolete>
-  <owner>fmeawad@chromium.org</owner>
-  <summary>
-    The number of swap-outs per second during session restore. Recorded at the
-    end of session restore as an average over the entire period, defined as the
-    period of time when session restore is actively loading tabs, which ends
-    when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.DiscardCount" units="units"
-    expires_after="2015-10-06">
-  <obsolete>
-    Removed 10/2015, and replaced by TabManager.Discarding.DiscardCount.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Cumulative number of tabs discarded due to low memory conditions, recorded
-    once per tab discard event. For example, a user who had 3 tabs discarded
-    records a count in the 1 bin, 2 bin and 3 bin. Thus each bin N is the number
-    of sessions where users experienced N or more tab discard events.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.DiscardInLastMinute" enum="BooleanTabDiscard"
-    expires_after="2017-11-08">
-  <obsolete>
-    Removed 11/2017. Average number of minutes between discard events is
-    available in Tabs.Discard.InitialTime2 and Tabs.Discard.IntervalTime2.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Whether or not a tab was discarded in the last minute of usage. Total count
-    is number of minutes of device usage. 100 / discard percentage gives the
-    average number of minutes between discard events.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.InitialTime" units="seconds"
-    expires_after="2015-06-02">
-  <obsolete>
-    Removed May 4, 2012. Replaced by Tabs.Discard.InitialTime2 because this stat
-    had too low of a range maximum. No longer tracked.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Time in seconds between system startup and when the first tab is discarded
-    due to low memory conditions. Higher is better.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.InitialTime2" units="seconds"
-    expires_after="2017-12-04">
-  <obsolete>
-    Removed 11/2017. Replaced with Discarding.Urgent.TimeSinceStartup which is
-    recorded when Chrome has to discard tabs or apps urgently (instead of before
-    an individual tab is urgently or proactively discarded).
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Time in seconds between system startup and when the first tab is discarded
-    due to low memory conditions. Higher is better. Range maximum is
-    approximately one day.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.IntervalTime" units="seconds"
-    expires_after="2015-06-02">
-  <obsolete>
-    Removed May 4, 2012. Replaced by Tabs.Discard.IntervalTime2 because this
-    stat had too low of a range maximum. No longer tracked.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Time in seconds between tab discard events after the first one, recorded
-    once per discard event. Higher is better.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.IntervalTime2" units="ms"
-    expires_after="2017-12-04">
-  <obsolete>
-    Removed 11/2017. Replaced with Discarding.Urgent.TimeSinceLastUrgent which
-    is recorded before a set of tabs/apps are urgently discarded (instead of
-    before an individual tab is urgently or proactively discarded).
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Time in milliseconds between tab discard events after the first one,
-    recorded once per discard event. Should occur no faster than once every 750
-    ms. Higher is better.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.MemAllocatedMB" units="MB" expires_after="M80">
-  <obsolete>
-    Removed 05/2019
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    System-wide memory allocation at the time a tab was discarded, roughly
-    equivalent to the sum of memory allocated with malloc() in userspace plus
-    graphics driver memory.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.MemAnonymousMB" units="MB"
-    expires_after="2015-06-02">
-  <obsolete>
-    Removed December 7, 2012. Replaced by Tabs.Discard.MemAllocatedMB because
-    this stat has insufficient precision in the 2-4 GB range and does not
-    properly account for graphics memory on ARM.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    System-wide anonymous memory allocation at the time a tab was discarded,
-    roughly equivalent to memory allocated with malloc().
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.MemAvailableMB" units="MB" expires_after="M80">
-  <obsolete>
-    Removed 05/2019
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    System-wide file-backed memory plus free memory, roughly equivalent to what
-    the kernel uses to trigger low-memory notifications for tab discards. If
-    lower than the kernel's threshold then we are not effectively freeing memory
-    in response to the initial notification and are repeatedly being notified.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.MemGraphicsMB" units="MB" expires_after="M77">
-  <obsolete>
-    Removed 05/2019
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Graphics driver (GEM object) memory at the time of a tab discard.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.MemShmemMB" units="MB" expires_after="M77">
-  <obsolete>
-    Removed 05/2019
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    System-wide shared memory at the time of a tab discard. Used primarily for
-    shared buffers in the graphics system. Tracked because it's a historical
-    source of leaks on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.ReloadCount" units="units"
-    expires_after="2015-10-06">
-  <obsolete>
-    Removed 10/2015, and replaced by TabManager.Discarding.ReloadCount.
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    Cumulative number of times a tab was reloaded because it was discarded and
-    the user clicked on it later, recorded once per reload event. For example, a
-    user who clicks on 3 discarded tabs will record a count in the 1 bin, 2 bin,
-    and 3 bin. Thus each bin N is the number of sessions where users experienced
-    N or more reload events. Compare to Tabs.Discard.DiscardCount.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Discard.TabCount" units="tabs" expires_after="2017-12-04">
-  <obsolete>
-    Removed 11/2017. Replaced with Discarding.Urgent.NumAliveTabs which records
-    the number of tabs that are not pending load or discarded when an urgent
-    discard request is received (vs. this that records the total number of tabs
-    every time a tab is discarded, no matter the reason).
-  </obsolete>
-  <owner>jamescook@chromium.org</owner>
-  <summary>
-    The number of tabs open across all browser windows when a tab was discarded
-    due to low memory conditions.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.FineTiming.TimeBetweenTabClosedAndNextTabCreated"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between closing a tab and opening another, to
-    track very frequent tabs.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.FineTiming.TimeBetweenTabCreatedAndNextTabCreated"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between opening a tab and opening another, to
-    track very frequent tabs.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.FineTiming.TimeBetweenTabCreatedAndSameTabClosed"
-    units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>joenotcharles@google.com</owner>
-  <summary>
-    Fine-grained (in msec) time between opening a tab and closing it, to track
-    very short-lived tabs.
-  </summary>
-</histogram>
-
-<histogram base="true" name="Tabs.FrozenTabPercentage" units="%"
-    expires_after="2019-08-31">
-  <obsolete>
-    Removed 2020-06.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="FrozenTabPercentage" -->
-
-  <owner>adityakeerthi@google.com</owner>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The percentage of hidden tabs that are frozen. This metric is recorded every
-    5 minutes, as a tab heartbeat metric. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.iOS_PostRedirectPLT" units="ms" expires_after="M85">
-  <obsolete>
-    Code removed long ago.
-  </obsolete>
-  <owner>pauljensen@chromium.org</owner>
-  <summary>
-    Page load time (PLT) for iOS that does not include time spent following
-    redirects. On other platforms this is calculated from Navigation Timings but
-    on iOS Navigation Timings are not available so we're recreating a
-    calculation similar to PLT.PT_RequestToFinish but not including time spent
-    following redirects. This metric represents the time between when navigation
-    is initiated (prior to DNS, TCP connect, etc but after following redirects)
-    until loading ends (i.e. JS onload event). On non-iOS Chrome this is
-    (performance.timing.loadEventEnd - performance.timing.redirectEnd). On
-    Chrome for iOS we're calculating the time between the creation of the
-    top-level URLRequest and when webDidFinishWithURL is called.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestoreApplicability"
-    enum="SpeculativeRestoreApplicability" expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Applicability of speculative tab restore, recorded every time a tab is
-    switched. This allows to estimate the fraction of tab restores experienced
-    on mobile that can be mitigated using speculative restore. Options higher in
-    the enum take precedence over the lower ones (i.e. low-memory tablet will be
-    accounted as tablet).
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestorePredictionAccuracy.SideSwipe"
-    enum="SpeculativeRestorePredictionAccuracy" expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Accuracy of the tab switch predictions made when the user begins the side
-    swipe gesture.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestorePredictionAccuracy.TabSwitcher"
-    enum="SpeculativeRestorePredictionAccuracy" expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Accuracy of the tab switch predictions made when the user enters the tab
-    switcher.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestoreTargetStatus"
-    enum="SpeculativeRestoreTabStatus" expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Status of a tab recorded when the tab is targeted with speculative restore.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestoreTimeAhead.SideSwipe" units="ms"
-    expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Time between starting the speculative load and actual tab switch for correct
-    speculative load predictions made when the user begins the side swipe
-    gesture.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.SpeculativeRestoreTimeAhead.TabSwitcher" units="ms"
-    expires_after="2019-01-16">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <summary>
-    Time between starting the speculative load and actual tab switch for correct
-    speculative load predictions made when the user enters the tab switcher.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.StateTransfer.Time" units="ms" expires_after="2017-05-08">
-  <obsolete>
-    Removed as of 4/2017.
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <owner>tzik@chromium.org</owner>
-  <summary>
-    Tabs.StateTransfer.TimeA_B measures the time a tab was in state A before it
-    transferred to state B.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.Suggestions.Close.NumSuggestionsChanged" units="count"
-    expires_after="2020-11-01">
-  <obsolete>
-    Removed as of 07/2020. Rename to
-    Tabs.Suggestions.NumSuggestionsChanged.Closing.
-  </obsolete>
-  <owner>yusufo@chromium.org</owner>
-  <owner>davidjm@chromium.org</owner>
-  <summary>
-    The user is presented with recommendations on which Tabs they could close.
-    The user has the option to: 1) Remove a Tab from the recommendation 2) Add a
-    Tab which wasn't in the recommendation to the recommendation
-
-    This metric records the sum of the number of times the user does 1) or 2)
-    and is a measure of how useful the recommendation is. This metric is
-    recorded after the user accepts a recommendation - potentially with edits by
-    performing 1) or 2).
-  </summary>
-</histogram>
-
-<histogram name="Tabs.TabSearch.WindowDisplayedDuration" units="ms"
-    expires_after="M90">
-  <obsolete>
-    Removed as of 09/2020 as the way the metric is emitted has changed. Replaced
-    with Tabs.TabSearch.WindowDisplayedDuration2.
-  </obsolete>
-  <owner>tluk@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Tab Search is a feature that allows users to better search their browsers
-    for their desired tabs. It can be opened and closed. This records the amount
-    of time between when a Tab Search bubble is opened and when it is closed. It
-    does so by recording the difference in time between when the Tab Search's
-    WebView is first set visible and when the WebView's destructor is called.
-
-    The Tab Search UI is a bubble anchored to an element within a browser window
-    and is closed if the user switches to a tab, presses the escape key or
-    performs an action to return focus to the hosting window. The Tab Search UI
-    bubble will also close if the hosting browser window is closed or crashes.
-
-    Users may leave the bubble open for long periods of time without directly
-    interacting with the UI which could result in a long tail of displayed
-    durations.
-  </summary>
-</histogram>
-
-<histogram name="Tabs.TimeSinceLastInteraction" units="ms" expires_after="M80">
-  <obsolete>
-    Removed 2019-07.
-  </obsolete>
-  <owner>alexmos@chromium.org</owner>
-  <owner>dcheng@chromium.org</owner>
-  <summary>
-    Reports the delta between the last user interaction time with a WebContents
-    and the time browser code wants to verify a recent user interaction with
-    that WebContents. Used to tune the threshhold for timing out a user
-    interaction.
-  </summary>
-</histogram>
-
-<histogram name="TabsApi.RequestedWindowState" enum="RequestedWindowState"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019-06.
-  </obsolete>
-  <owner>afakhry@chromium.org</owner>
-  <summary>
-    The requested window creation state from the tabs extensions API when it's
-    used to create a new window or update the state of an existing one.
-  </summary>
-</histogram>
-
-<histogram name="TaskScheduler.BlockShutdownTasksPostedDuringShutdown"
-    units="tasks" expires_after="2018-10-18">
-  <obsolete>
-    Removed 10/2018. Instead of recording a histogram with the number of
-    BLOCK_SHUTDOWN tasks posted during shutdown, we generate a crash when too
-    many BLOCK_SHUTDOWN tasks are posted during shutdown. A crash dump is more
-    actionnable than a histogram.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Number of BLOCK_SHUTDOWN tasks that were posted to a base::TaskScheduler
-    after its Shutdown() method was called but before it returned.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.DetachDuration" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Time elapsed between when the thread managed by a SchedulerWorker is
-    detached and when the main function of a new thread managed by the same
-    SchedulerWorker is entered (following a wake up). Recorded each time that a
-    thread is recreated for a given SchedulerWorker.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.HeartbeatLatencyMicroseconds"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Latency of dummy &quot;heartbeat&quot; tasks posted with specific traits
-    (see suffix). The heartbeat recording avoids dependencies between this
-    report and other work in the system. See
-    TaskScheduler.TaskLatencyMicroseconds.* for a metric that is closer to the
-    real workload.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumActiveWorkers" units="workers"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Number of workers running a task in a given SchedulerWorkerPool. Recorded
-    every 59 minutes (sampling rate is not expected to affect the distribution).
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumCancelledDelayedTasks"
-    units="tasks" expires_after="2019-03-20">
-  <obsolete>
-    Removed as of 03/2019.
-  </obsolete>
-  <owner>adityakeerthi@google.com</owner>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Lower-bound number of cancelled tasks that remain in the DelayedTaskManager.
-    An exact number is not recorded, as it could potentially be expensive to
-    calculate. Instead, a lazy count is maintained by noting cancelled tasks as
-    new delayed tasks are added. Recorded every time the ServiceThread performs
-    a heartbeat latency report.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumTasksBeforeDetach" units="tasks"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Number of tasks executed by a SchedulerWorker before it detached. Recorded
-    when a SchedulerWorker detaches.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumTasksBetweenWaits" units="tasks"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Number of tasks executed by a SchedulerWorker between two waits on its
-    WaitableEvent. This should be maximized without affecting perceived browser
-    performance.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumTasksRunWhileQueuing"
-    units="tasks" expires_after="2019-10-01">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Number of tasks run by TaskScheduler while task was queuing (from time task
-    was posted until time it was run). Recorded for dummy &quot;heartbeat&quot;
-    tasks posted with specific traits (see suffix). The heartbeat recording
-    avoids dependencies between this report and other work in the system.
-    Recorded every time the ServiceThread performs a heartbeat latency report.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.NumWorkers" units="workers"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Number of workers that live in a given SchedulerWorkerPool. Recorded every
-    59 minutes (sampling rate is not expected to affect the distribution).
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.PercentCancelledDelayedTasks"
-    units="tasks" expires_after="2019-03-20">
-  <obsolete>
-    Removed as of 03/2019.
-  </obsolete>
-  <owner>adityakeerthi@google.com</owner>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Lower-bound percentage of tasks in the DelayedTaskManager that have been
-    cancelled. An exact number is not recorded, as it could potentially be
-    expensive to calculate. Instead, a lazy count is maintained by noting
-    cancelled tasks as new delayed tasks are added. Recorded every time the
-    ServiceThread performs a heartbeat latency report.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.TaskLatency" units="ms"
-    expires_after="2017-04-28">
-  <obsolete>
-    Removed 4/2017. Units changed from milliseconds to microseconds.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Time elapsed between when a task is posted and when it starts to run.
-    Recorded for each task that runs inside the TaskScheduler. This metric is
-    useful to determine true latency of the average task in the average runtime
-    scenario. Its total count can also be used as a proxy for the number of
-    tasks posted to a given category. On the other hand, a fallout of this
-    metric is that timing every task means each report is dependent on the many
-    things that can cause an individual task to be delayed (e.g. tasks on a
-    single bogged down sequence will be reported with high latency even if not
-    stalling the scheduler itself). See
-    TaskScheduler.HeartbeatLatencyMicroseconds.* for a metric that is
-    independent of such factors.
-  </summary>
-</histogram>
-
-<histogram base="true" name="TaskScheduler.TaskLatencyMicroseconds"
-    units="microseconds" expires_after="M80">
-  <obsolete>
-    Removed 4/2019. Prefix renamed to ThreadPool.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Time elapsed between when a task is posted and when it starts to run.
-    Recorded for each task that runs inside the TaskScheduler.
-  </summary>
-</histogram>
-
-<histogram name="TerminalSystemAppFrame.WrenchMenu.MenuAction"
-    enum="WrenchMenuAction" expires_after="2020-09-01">
-  <obsolete>
-    Removed 07/2020.
-  </obsolete>
-  <owner>alancutter@chromium.org</owner>
-  <owner>calamity@chromium.org</owner>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    Number of times that each menu item is clicked from the terminal system app
-    menu button.
-  </summary>
-</histogram>
-
-<histogram name="TextToSpeech.Settings.DefaultVoicePicked"
-    enum="TextToSpeechVoiceIdHashes" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dtseng@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    The user picked a default voice of the specified voice ID, which is hashed
-    from a JSON string of the voice name and extension ID.
-  </summary>
-</histogram>
-
-<histogram name="TextToSpeech.Settings.PreviewVoiceClicked"
-    enum="TextToSpeechVoiceIdHashes" expires_after="M85">
-  <obsolete>
-    Removed 06/2020 as it is no longer needed for analysis.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dtseng@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    When the user requests a preview of a text-to-speech voice, records which
-    voice was previewed.
-  </summary>
-</histogram>
-
-<histogram name="TextToSpeechEngine.ParseVoice.HasGender"
-    enum="TextToSpeechHasGender" expires_after="M70">
-  <obsolete>
-    Removed 08/2018.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dtseng@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    True if a voice parsed from a ttsEngine extension manifest has a specific
-    gender. This is recorded each time a TTS extension is parsed, which may
-    occur multiple times per extension, in tts_engine_manifest_handler:
-    TtsVoices::Parse.
-  </summary>
-</histogram>
-
-<histogram name="TextToSpeechEngine.UpdateVoice.HasGender"
-    enum="TextToSpeechHasGender" expires_after="M70">
-  <obsolete>
-    Removed 08/2018.
-  </obsolete>
-  <owner>katie@chromium.org</owner>
-  <owner>dtseng@chromium.org</owner>
-  <owner>dmazzoni@chromium.org</owner>
-  <summary>
-    True if a voice specified in chrome.ttsEngine.updateVoices by a ttsEngine
-    extension has a specific gender.
-  </summary>
-</histogram>
-
-<histogram name="ThirdPartyModules.InstalledPrograms.DataSize" units="KB"
-    expires_after="2018-01-14">
-  <obsolete>
-    Removed 12/2017.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    Records the size of the in-memory representation of the installed
-    third-party programs on the user's machine.
-  </summary>
-</histogram>
-
-<histogram name="ThirdPartyModules.InstalledPrograms.GetDataTime" units="ms"
-    expires_after="2018-07-24">
-  <obsolete>
-    Removed 07/2018.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    Records the time it took to gather the list of installed third-party
-    programs and their install location or components.
-  </summary>
-</histogram>
-
-<histogram name="ThirdPartyModules.ShellExtensionsCount" units="counts"
-    expires_after="2018-08-15">
-  <obsolete>
-    Removed as of 14 Aug 2018 as reporting to this metric was incorrect since
-    its inception. Replaced by ThirdPartyModules.ShellExtensionsCount2.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The number of registered shell extensions found on the user's machine. This
-    is emitted shortly after startup when the shell extensions enumeration takes
-    place.
-  </summary>
-</histogram>
-
-<histogram name="ThirdPartyModules.ShellExtensionsCount2" units="counts"
-    expires_after="2018-09-11">
-  <obsolete>
-    Removed on 30/08/2018 now that the enumeration removes duplicate entries.
-  </obsolete>
-  <owner>pmonette@chromium.org</owner>
-  <summary>
-    The number of registered shell extensions found on the user's machine. This
-    is emitted shortly after startup when the shell extensions enumeration takes
-    place.
-  </summary>
-</histogram>
-
-<histogram base="true" name="ThreadPool.NumActiveWorkers" units="workers"
-    expires_after="M86">
-  <obsolete>
-    Removed 7/2020. Not used in active investigations.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Number of workers running a task in a given SchedulerWorkerPool. Recorded
-    every 59 minutes (sampling rate is not expected to affect the distribution).
-  </summary>
-</histogram>
-
-<histogram base="true" name="ThreadPool.NumTasksBetweenWaits" units="tasks"
-    expires_after="M80">
-  <obsolete>
-    Removed 8/2019. Not used in active investigations.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <owner>robliao@chromium.org</owner>
-  <summary>
-    Number of tasks executed by a SchedulerWorker between two waits on its
-    WaitableEvent. This should be maximized without affecting perceived browser
-    performance.
-  </summary>
-</histogram>
-
-<histogram name="ThreadPool.NumTasksInSequenceOnPush" units="tasks"
-    expires_after="2020-05-17">
-  <obsolete>
-    Stopped recording on 21/4/2020 due to a bug.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <owner>scheduler-dev@chromium.org</owner>
-  <summary>
-    Number of tasks in a ThreadPool sequence, recorded every time a task is
-    pushed to a sequence. This is recorded to determine how often the size of a
-    sequence grows above 10000 tasks, and whether it is reasonable to upload a
-    process dump when that happens.
-  </summary>
-</histogram>
-
-<histogram base="true" name="ThreadPool.NumWorkers" units="workers"
-    expires_after="M86">
-  <obsolete>
-    Removed 7/2020. Not used in active investigations.
-  </obsolete>
-  <owner>etiennep@chromium.org</owner>
-  <owner>fdoray@chromium.org</owner>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Number of workers that live in a given SchedulerWorkerPool. Recorded every
-    59 minutes (sampling rate is not expected to affect the distribution).
-  </summary>
-</histogram>
-
-<histogram name="Thumbnails.AddedToTopSites" enum="ThumbnailTopSitesEvent"
-    expires_after="2019-06-06">
-  <obsolete>
-    Doesn't exist anymore as of 2019-06.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    A page thumbnail (for use on the New Tab page) was added to TopSites.
-  </summary>
-</histogram>
-
-<histogram name="Thumbnails.CaptureOutcome" enum="ThumbnailCaptureOutcome"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019-03.
-  </obsolete>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    The result of trying to capture a thumbnail of the current page.
-  </summary>
-</histogram>
-
-<histogram name="TileManager.TilesGPUMemoryUsage" units="KB"
-    expires_after="M80">
-  <obsolete>
-    Replaced by Compositing.Renderer.GPUMemoryForTilingsInKb which is an
-    existing metric tracking the same value.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The amount of GPU memory, in kilobytes. Recorded on devices with less than
-    or equal to 512MB of memory and when tile manager had sufficient memory to
-    schedule all visible tiles.
-  </summary>
-</histogram>
-
-<histogram name="TileManager.TilesGPUMemoryUsage2" units="KB"
-    expires_after="never">
-  <obsolete>
-    Replaced by Compositing.Renderer.GPUMemoryForTilingsInKb which is an
-    existing metric tracking the same value.
-  </obsolete>
-  <owner>pdr@chromium.org</owner>
-  <owner>ericrk@chromium.org</owner>
-  <summary>
-    The amount of GPU memory used for tiles, in kilobytes. Recorded when the
-    tile manager had sufficient memory to schedule all visible tiles.
-  </summary>
-</histogram>
-
-<histogram name="Toolbar.ActionsModel.ComponentActionsCount" units="units"
-    expires_after="2018-12-27">
-  <obsolete>
-    We no longer have component actions.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The number of component action icons the Browser Actions Container knows
-    about (visible or in the overflow bucket). Does not count icons that have
-    been permanently hidden by the user. Measured once per startup per
-    (non-incognito) profile.
-  </summary>
-</histogram>
-
-<histogram name="Toolbar.ActionsModel.OverallActionsCount" units="units"
-    expires_after="2019-02-28">
-  <obsolete>
-    After the removal of component actions, this histogram is equivalent to
-    ExtensionToolbarModel.BrowserActionsCount. See that histogram instead.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The total number of action icons the Browser Actions Container knows about
-    (visible or in the overflow bucket). Does not count icons that have been
-    permanently hidden by the user. Measured once per startup per
-    (non-incognito) profile.
-  </summary>
-</histogram>
-
-<histogram name="Toolbar.ActionsModel.ToolbarActionsVisible" units="units"
-    expires_after="M80">
-  <obsolete>
-    Obsolete. See ExtensionToolbarModel.BrowserActionsVisible instead. Stopped
-    recording 2019-07.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <owner>extensions-core@chromium.org</owner>
-  <summary>
-    The number of visible toolbar icons in the Browser Actions Container
-    (visible as in number of icons not in the overflow bucket). 0 means all
-    icons are in the overflow bucket. MAX_INT means the toolbar is always
-    showing all icons. Measured once per startup per (non-incognito) profile but
-    only for those profiles that have one or more browser actions showing in the
-    toolbar.
-  </summary>
-</histogram>
-
-<histogram name="Toolbar.AppMenuTimeToAction" units="ms" expires_after="M80">
-  <obsolete>
-    Stopped recording 2019-07.
-  </obsolete>
-  <owner>rdevlin.cronin@chromium.org</owner>
-  <summary>
-    The number of millseconds between when the user opens the app menu and when
-    the app menu is closed. Logged once per app menu run when the menu closes.
-    Not recorded for menu runs that are initiated by a drag-and-drop sequence.
-    Note that the code paths for Views-platforms vs Mac are different, so cross-
-    platform comparison may not always be reasonable.
-  </summary>
-</histogram>
-
-<histogram name="Toolbar.Menu.NewTabPresentationDuration" units="ms"
-    expires_after="2019-02-12">
-  <obsolete>
-    Long removed.
-  </obsolete>
-  <owner>peterlaurens@chromium.org</owner>
-  <summary>
-    The number of millseconds between the user requesting a new tab, e.g. by
-    tapping the New Tab entry in the main tools menu, and it completing its
-    animation on screen.
-  </summary>
-</histogram>
-
-<histogram name="TopSites.NumberOfApplyBlacklist" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in M86.
-  </obsolete>
-  <owner>alemate@chromium.org</owner>
-  <summary>
-    The number of times TopSitesImpl::ApplyBlockedUrls is called.
-  </summary>
-</histogram>
-
-<histogram name="TopSites.NumberOfBlacklistedItems" units="units"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed in M86.
-  </obsolete>
-  <owner>alemate@chromium.org</owner>
-  <summary>
-    The number of urls blocked in TopSites. Logged every time
-    TopSitesImpl::ApplyBlockedUrls is called.
-  </summary>
-</histogram>
-
-<histogram name="TouchAction.EffectiveTouchAction" enum="TouchActions"
-    expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <summary>
-    Tracks how often each touch action is allowed (AKA the frequency of each
-    effective touch action) at the end of each touch sequence.
-  </summary>
-</histogram>
-
-<histogram name="TouchAction.EquivalentEffectiveAndWhiteListed"
-    enum="EquivalentEffectiveAndWhiteListed" expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <summary>
-    Tracks how often the effective touch action computed by blink is or is not
-    equivalent to the whitelisted touch action computed by the compositor at the
-    end of each touch sequence.
-  </summary>
-</histogram>
-
-<histogram name="TouchAction.GestureEventFiltered"
-    enum="TouchGestureEventFiltered" expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <summary>
-    Tracks how often a gesture event is or is not dropped due to the current
-    allowed touch action state not matching the gesture event.
-  </summary>
-</histogram>
-
-<histogram name="TouchAction.GestureEventFilterResults"
-    enum="GestureEventFilterResults" expires_after="M85">
-  <obsolete>
-    Removed in 06/2020.
-  </obsolete>
-  <owner>xidachen@chromium.org</owner>
-  <owner>nzolghadr@chromium.org</owner>
-  <summary>
-    Track whether a gesture event is allowed or filtered or deferred.
-  </summary>
-</histogram>
-
-<histogram name="Touchpad.Metrics" enum="TouchpadProblemType"
-    expires_after="2017-08-10">
-  <obsolete>
-    Removed 8/2017.
-  </obsolete>
-  <owner>jhawkins@chromium.org</owner>
-  <summary>
-    Tracks unusual CrOS touchpad operational states (e.g. running into the noisy
-    ground issue). This is sampled at every touchpad event.
-  </summary>
-</histogram>
-
-<histogram name="Touchpad.Sensitivity.Changed" enum="PointerSensitivity"
-    expires_after="2013-07-02">
-  <obsolete>
-    Removed as of 6/2013, replaced by Touchpad.PointerSensitivity.Changed.
-  </obsolete>
-  <owner>jhawkins@chromium.org</owner>
-  <summary>Tracks touchpad sensitivity setting changes by the user.</summary>
-</histogram>
-
-<histogram name="Touchpad.Sensitivity.Started" enum="PointerSensitivity"
-    expires_after="2013-07-02">
-  <obsolete>
-    Removed as of 6/2013, replaced by Touchpad.PointerSensitivity.Started.
-  </obsolete>
-  <owner>jhawkins@chromium.org</owner>
-  <summary>Tracks touchpad sensitivity setting on startup.</summary>
-</histogram>
-
-<histogram name="Touchpad.ThreeFingerSwipe.Changed" enum="BooleanEnabled"
-    expires_after="2013-07-04">
-  <obsolete>
-    Removed as of 7/2013.
-  </obsolete>
-  <owner>jhawkins@chromium.org</owner>
-</histogram>
-
-<histogram name="Touchpad.ThreeFingerSwipe.Started" enum="BooleanEnabled"
-    expires_after="2013-07-04">
-  <obsolete>
-    Removed as of 7/2013.
-  </obsolete>
-  <owner>jhawkins@chromium.org</owner>
-</histogram>
-
-<histogram name="Touchscreen.TapDisambiguation" enum="TapDisambiguation"
-    expires_after="2018-07-31">
-  <obsolete>
-    Removed as of 7/2018.
-  </obsolete>
-  <owner>aelias@chromium.org</owner>
-  <summary>
-    How the user interacted with the tap disambiguation feature on Android.
-  </summary>
-</histogram>
-
-<histogram name="TrackedObjects.GetRetiredOrCreateThreadData" units="ms"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017. Code measured by this histogram no longer exists.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    Time spent in base::ThreadData::GetRetiredOrCreateThreadData(). This method
-    is called at most once per thread, when its name is set, when it posts a
-    task or when it runs a task (whichever comes first).
-  </summary>
-</histogram>
-
-<histogram name="TrafficStatsAmortizer.AmortizationDelay" units="ms"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The amount of time spent waiting to perform an amortization run. This is
-    logged at the end of each amortization run, before passing any DataUse
-    objects to their respective callbacks.
-  </summary>
-</histogram>
-
-<histogram name="TrafficStatsAmortizer.BufferSizeOnFlush" units="count"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The number of DataUse objects processed in an amortization run.
-  </summary>
-</histogram>
-
-<histogram name="TrafficStatsAmortizer.ConcurrentTabs" units="count"
-    expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The number of unique tabs seen across all DataUse objects buffered for a
-    single amortization run by the TrafficStatsAmortizer. This is recorded even
-    if TrafficStats byte counts are unavailable, but not recorded if no DataUse
-    objects have been buffered.
-  </summary>
-</histogram>
-
-<histogram name="TrafficStatsAmortizer.PostAmortizationRunDataUseBytes"
-    units="bytes" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total bytes after performing amortization across all DataUse objects
-    buffered for a single amortization run by the TrafficStatsAmortizer. This is
-    recorded even if TrafficStats byte counts are unavailable, but not recorded
-    if no DataUse objects have been buffered.
-  </summary>
-</histogram>
-
-<histogram name="TrafficStatsAmortizer.PreAmortizationRunDataUseBytes"
-    units="bytes" expires_after="2018-07-19">
-  <obsolete>
-    Removed 2018/07.
-  </obsolete>
-  <owner>sclittle@chromium.org</owner>
-  <owner>bengr@chromium.org</owner>
-  <summary>
-    The total bytes before performing amortization across all DataUse objects
-    buffered for a single amortization run by the TrafficStatsAmortizer. This is
-    recorded even if TrafficStats byte counts are unavailable, but not recorded
-    if no DataUse objects have been buffered.
-  </summary>
-</histogram>
-
-<histogram name="Translate.CLD2.LanguageAccuracy" units="%"
-    expires_after="2017-11-09">
-  <obsolete>
-    Removed as of 11/2017, since cld2 is deprecated.
-  </obsolete>
-  <owner>rkaplow@google.com</owner>
-  <summary>
-    Accuracy of the language detected by CLD2. Only recorded if the detection
-    returned a &quot;known&quot; result.
-  </summary>
-</histogram>
-
-<histogram name="Translate.CLD2.LanguageDetected" enum="CLD2LanguageCode"
-    expires_after="2017-11-09">
-  <obsolete>
-    Removed as of 11/2017, since cld2 is deprecated.
-  </obsolete>
-  <owner>rkaplow@google.com</owner>
-  <summary>Language of page detected by CLD2.</summary>
-</histogram>
-
-<histogram name="Translate.ForceTriggerBackoffStateReached" enum="Boolean"
-    expires_after="2020-12-01">
-  <obsolete>
-    Removed as of 04/2020. No longer used for analysis.
-  </obsolete>
-  <owner>anthonyvd@chromium.org</owner>
-  <owner>yyushkina@chromium.org</owner>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    Whether or not the backoff threshold for triggering Translate on UI-language
-    content is reached when the translation process is initiated.
-  </summary>
-</histogram>
-
-<histogram name="Translate.InitiationStatus" enum="TranslateInitiationStatus"
-    expires_after="2013-11-05">
-  <obsolete>
-    Removed as of 11/2013, and replaced by Translate.InitiationStatus.v2.
-  </obsolete>
-  <owner>chrome-language@google.com</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>
-    The reason why Chrome decided to perform the next action (e.g., to show
-    infobar, to translate a page without any prompting, and so on) when Chrome
-    Translate is ready to translate a page.
-  </summary>
-</histogram>
-
-<histogram name="Translate.LanguageDetectionConflict"
-    enum="EnCrossCLD3LanguageCode" expires_after="M77">
-  <obsolete>
-    Removed from code as of 04/2020.
-  </obsolete>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    This metric logs CLD3-detected languages for pages that specify a
-    conflicting English language in their markup. In these cases, we must decide
-    on a language source to favor.
-
-    Bucket names are of the form &quot;x,y&quot;, where x is the common English
-    language code specified in the page markup (or &quot;other&quot; if the
-    English language code is uncommon), and y is the CLD3-detected language.
-
-    This histogram only logs detection conflicts. Hence, &quot;matching&quot;
-    buckets (e.g. &quot;en,en&quot;, &quot;en-AU,en&quot;) will never be
-    populated.
-  </summary>
-</histogram>
-
-<histogram name="Translate.PageCaptured" units="ms" expires_after="2018-02-13">
-  <obsolete>
-    Removed 2/2018
-  </obsolete>
-  <owner>chrome-language@google.com</owner>
-  <owner>joelhockey@chromium.org</owner>
-  <summary>
-    The time spent capturing plain text from the DOM. This is reported by
-    ChromeRenderViewObserver when a page is loaded completely.
-  </summary>
-</histogram>
-
-<histogram name="Translate.ServerReportedUnsupportedLanguage" units="units"
-    expires_after="2013-06-14">
-  <obsolete>
-    Removed 5/2013 by Translate.UndisplayableLanguage
-  </obsolete>
-  <owner>kenjibaheux@google.com</owner>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    The number of times the detected language is not supported by Translate
-    Element.
-  </summary>
-</histogram>
-
-<histogram name="Translate.ShowBeforeTranslateInfobar" units="units"
-    expires_after="2013-05-30">
-  <obsolete>
-    Removed 7/2010. No longer tracked.
-  </obsolete>
-  <owner>chrome-language@google.com</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>
-    The number of times an infobar proposing to translate a page has been shown.
-  </summary>
-</histogram>
-
-<histogram name="Translate.ShowErrorInfobar" enum="TranslateError"
-    expires_after="2020-09-18">
-  <obsolete>
-    Removed 06/2020. Duplicate of Translate.ShowErrorUI
-  </obsolete>
-  <owner>chrome-language@google.com</owner>
-  <owner>kenjibaheux@google.com</owner>
-  <summary>
-    Chrome Translate shows an error infobar when an error happens on translation
-    and the infobar message depends on what kind of error happens. This metric
-    counts how often each error message is shown.
-  </summary>
-</histogram>
-
-<histogram name="TrustedWebActivity.TimeInVerifiedOrigin" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Retired in M77 in favour of TrustedWebActivity.TimeInVerifiedOrigin.V2 which
-    uses a more appropriate timescale.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Time spent in a verified origin until navigating to an unverified one or
-    pausing the Trusted Web Activity.
-  </summary>
-</histogram>
-
-<histogram name="TrustedWebActivity.TimeOutOfVerifiedOrigin" units="ms"
-    expires_after="M82">
-  <obsolete>
-    Retired in M77 in favour of TrustedWebActivity.TimeOutOfVerifiedOrigin.V2
-    which uses a more appropriate timescale.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Time spent out of verified origins until navigating back to a verified one
-    or pausing the Trusted Web Activity.
-  </summary>
-</histogram>
-
-<histogram name="TrustedWebActivity.TranslucencyRemovalFailed" enum="Boolean"
-    expires_after="M83">
-  <obsolete>
-    Replaced by Mobile.Splash.TranslucencyRemovalFailed.
-  </obsolete>
-  <owner>peconn@chromium.org</owner>
-  <owner>peter@chromium.org</owner>
-  <summary>
-    Records the cases when removing a Trusted Web Activity's translucency via a
-    reflective call fails. Only &quot;true&quot; is recorded.
-  </summary>
-</histogram>
-
-<histogram name="TryScroll.SlowScroll" enum="ScrollThread"
-    expires_after="2016-02-29">
-  <obsolete>
-    Removed 02/2016 in Issue 1741103002, and replaced by
-    Renderer4.CompositorWheelScrollUpdateThread and
-    Renderer4.CompositorTouchScrollUpdateThread.
-  </obsolete>
-  <owner>tdresser@chromium.org</owner>
-  <summary>Whether a scroll is executed on main thread.</summary>
-</histogram>
-
-<histogram name="UI.CompositorResizeLock.Duration" units="ms"
-    expires_after="2019-02-07">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The amount of time the CompositorResizeLock was held in milliseconds. This
-    is a measure of jank as UI will not generate new frames as long as the lock
-    is held.
-  </summary>
-</histogram>
-
-<histogram name="UI.CompositorResizeLock.TimedOut" enum="Boolean"
-    expires_after="2019-02-07">
-  <obsolete>
-    Removed in M65.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    Tracks whether the CompositorResizeLock is being released due to timing out
-    or not.
-  </summary>
-</histogram>
-
-<histogram name="UI.WindowTreeHost.SurfaceSynchronizationDuration" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85.
-  </obsolete>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    The amount of time it took for UI's CompositorFrame to activate due to a
-    surface synchronization event. This a measure of jank as UI will not
-    generate new frames as long synchronization is in progress. This metric is
-    similar to UI.CompositorResizeLock.Duration but measures the new
-    synchronization code path.
-  </summary>
-</histogram>
-
-<histogram name="UKM.Entries.SerializedCount" units="units"
-    expires_after="2018-02-16">
-  <obsolete>
-    Removed 2/2018 by UKM.Entries.SerializedCount2.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>ukm-team@google.com</owner>
-  <summary>Number of serialized UKM entries when storing a UKM log.</summary>
-</histogram>
-
-<histogram name="UKM.LogUploader.UploadSize" units="bytes"
-    expires_after="2019-01-22">
-  <obsolete>
-    Removed in favor of UKM.LogSize.OnSuccess
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>holte@chromium.org</owner>
-  <summary>
-    Reports total upload length in bytes when the UKM service type is used.
-  </summary>
-</histogram>
-
-<histogram name="UKM.Sources.SerializedCount" units="sources"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed 10/2018 by UKM.Sources.SerializedCount2.
-  </obsolete>
-  <owner>holte@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>Number of serialized UKM sources when storing a UKM log.</summary>
-</histogram>
-
-<histogram name="UKM.SyncDisable.Info" enum="UkmSyncDisableInfo"
-    expires_after="2020-05-10">
-  <obsolete>
-    Removed 11/2018 for UKM.ConsentObserver.AllowedForAllProfiles.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>ukm-team@google.com</owner>
-  <summary>
-    Information about the determination by the UkmConsentStateObserver on why it
-    enabled or disabled UKM.
-  </summary>
-</histogram>
-
-<histogram name="UKM.SyncDisable.Purge" enum="Boolean" expires_after="M79">
-  <obsolete>
-    Removed 11/2018 for UKM.ConsentObserver.Purge.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>ukm-team@google.com</owner>
-  <summary>
-    Logged in the UpdateSyncState call from the UkmConsentStateObserver. This
-    records if the UKM allowed change will trigger a purge of the local UKM
-    data.
-  </summary>
-</histogram>
-
-<histogram name="UKM.Upload.ResponseCode" enum="HttpResponseCode"
-    expires_after="2017-04-04">
-  <obsolete>
-    Replaced by UKM.LogUpload.ResponseOrErrorCode
-  </obsolete>
-  <owner>holte@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    For each upload to the UKM server, log the response received from the
-    server.
-  </summary>
-</histogram>
-
-<histogram name="UMA.ClientIdMigrated" enum="BooleanMigrated"
-    expires_after="2015-06-01">
-  <obsolete>
-    Removed in M45.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Recorded when the one-time UMA client id reset was performed (and the client
-    id of this user was migrated).
-  </summary>
-</histogram>
-
-<histogram name="UMA.CollectExternalEventsTime" units="ms"
-    expires_after="2015-08-07">
-  <obsolete>
-    Removed as of August 2015. The histogram showed no unexpected slowness, and
-    a profiler is a better tool for identifying any future issues.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The time to run the external metrics collection task (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="UMA.ComputeCurrentSigninStatus"
-    enum="ComputeCurrentSigninStatus" expires_after="2016-06-14">
-  <obsolete>
-    Removed as of Jun 2016. The histogram was added for debugging purpose and is
-    not needed anymore.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>yiyaoliu@chromium.org</owner>
-  <summary>
-    Records attempts to compute the current the signin status and error
-    encountered when computing.
-  </summary>
-</histogram>
-
-<histogram name="UMA.CreatePersistentHistogram.Result"
-    enum="CreatePersistentHistogramResult" expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as the information has never shown any problems.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records attempts to create histograms in presistent space and any errors
-    encountered when doing so.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUpAsyncTaskDuration"
-    units="ms" expires_after="M77">
-  <obsolete>
-    No longer useful or monitored, removed 2020-01-06.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Measures how much time it took to complete all async deferred startup tasks
-    on the background thread. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime"
-    units="ms" expires_after="M77">
-  <obsolete>
-    No longer useful or monitored, removed 2020-01-06.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Measures how much time since application was first in foreground till all
-    deferred tasks are done. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUpDuration"
-    units="ms" expires_after="M77">
-  <obsolete>
-    No longer useful or monitored, removed 2020-01-06.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Measures how much time it took to complete deferred startup tasks on the UI
-    thread. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUpDurationAsync"
-    units="ms" expires_after="2017-01-24">
-  <obsolete>
-    Removed 01/2017 for
-    UMA.Debug.EnableCrashUpload.DeferredStartupAsyncTaskDuration.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time it took to complete async deferred startup tasks on
-    the background thread. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration"
-    units="ms" expires_after="2020-02-16">
-  <obsolete>
-    No longer useful or monitored, removed 2020-01-06.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Measures the maximum amount of time a single deferred startup task took.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUptime" units="ms"
-    expires_after="2016-08-08">
-  <obsolete>
-    Replaced by UMA.Debug.EnableCrashUpload.DeferredStartUptime2
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since start up it took for onDeferredStartup() to be
-    called, which schedules enablePotentialCrashUploading() to be executed on an
-    async task. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUptime2" units="ms"
-    expires_after="2017-06-28">
-  <obsolete>
-    Removed 2017. No longer tracked.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since application was first in foreground till
-    deferred tasks are initialized and queued on the idle handler. Only logged
-    on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.PostDeferredStartUptime"
-    units="ms" expires_after="2016-08-08">
-  <obsolete>
-    Replaced by UMA.Debug.EnableCrashUpload.PostDeferredStartUptime2
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since start up it took before ChromeActivity's
-    postDeferredStartupIfNeeded() was called. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.PostDeferredStartUptime2"
-    units="ms" expires_after="2017-06-28">
-  <obsolete>
-    Removed 2017. No longer tracked.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since application was first in foreground till
-    ChromeActivity's postDeferredStartupIfNeeded() was called exactly once. Only
-    logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.Uptime" units="ms"
-    expires_after="2016-05-16">
-  <obsolete>
-    Replaced by UMA.Debug.EnableCrashUpload.Uptime2
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since start up it took before crash reporting was
-    enabled via enablePotentialCrashUploading() as part of deferred start up.
-    Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.Uptime2" units="ms"
-    expires_after="2016-08-08">
-  <obsolete>
-    Replaced by UMA.Debug.EnableCrashUpload.Uptime3
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since start up it took before crash reporting was
-    enabled via enablePotentialCrashUploading() as part of deferred start up.
-    Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Debug.EnableCrashUpload.Uptime3" units="ms"
-    expires_after="2017-06-28">
-  <obsolete>
-    Removed 2017. No longer tracked.
-  </obsolete>
-  <owner>wnwen@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Measures how much time since application was first in foreground till crash
-    reporting was enabled as part of deferred start up. Only logged on Android.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Discarded Log Events" units="units"
-    expires_after="2017-06-05">
-  <obsolete>
-    Replaced by UMA.Truncate* metrics.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <summary>
-    The number of events that would be discarded at log transmission time
-    because the event count was already too large. Note that this doesn't
-    measure actual discards - in case the UMAThrottleEvents feature is disabled,
-    the discards won't occur.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FieldTrialAllocator.Size" units="bytes"
-    expires_after="2016-11-09">
-  <obsolete>
-    Removed 11/2016 for UMA.FieldTrialAllocator.Used
-  </obsolete>
-  <owner>lawrencewu@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Size, before padding, of objects allocated from persistent memory in the
-    browser process for field trials. Updated on each subprocess launch.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FieldTrialsEnabledBenchmarking" enum="BooleanUsage"
-    expires_after="2014-10-15">
-  <obsolete>
-    Removed 2012. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Log whether the --enable-benchmarking flag was set, which causes field
-    trials to only use the default group.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.DeletedFiles" units="units"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as the information it provides is no longer useful.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The number of old metrics files for which a delete was attempted. This is
-    logged once with each upload operation. Values greater than 1 indicate that
-    the files are not deletable by the browser and must be cleaned up by
-    whatever process is creating them.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.DirectoryFiles" units="units"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as no problems were ever indicated.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The number of metrics files in a directory that need to be uploaded. This is
-    logged once with each upload operation.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.EmbeddedProfile.DroppedFileAge"
-    units="minutes" expires_after="2017-07-08">
-  <obsolete>
-    Removed 07/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records the last-modified age of a file that was dropped for lack of an
-    embedded profile.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.EmbeddedProfile.DroppedHistogramCount"
-    units="units" expires_after="M75">
-  <obsolete>
-    Removed 2019/04 with the resolution of https://crbug.com/695880
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records the number of histograms present in a file that was dropped for lack
-    of an embedded profile.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.EmbeddedProfile.RecordTime" units="ms"
-    expires_after="M71">
-  <obsolete>
-    Removed 2019/04 as times are small, consistent, and now on a background
-    thread.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Tracks the time used to record all histograms from a file with an embedded
-    profile.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.EmbeddedProfileResult"
-    enum="FileMetricsProviderEmbeddedProfileResult" expires_after="M75">
-  <obsolete>
-    Removed 2019/04 with the resolution of https://crbug.com/695880
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records attempts to upload metrics from files with embedded system profiles.
-    Counts are not necessarily mutually exclusive.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.Happening"
-    enum="FileMetricsProviderHappening" expires_after="2018-02-09">
-  <obsolete>
-    This metrics was to provide information for crbug/760317 which has been
-    resolved. Removed February, 2018.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records various happenings within the FileMetricsProvider for debugging
-    purposes.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.InitialCheckTime.File" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Access times are consistently on the order of a few ms. Removed 2019/06.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent checking and mapping an initial metrics
-    file on disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.InitialCheckTime.Total" units="ms"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as the information it provides is no longer useful.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent checking and mapping initial metrics
-    from all files on disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.InitialSnapshotTime.File" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Access times are consistently on the order of a few ms. Removed 2019/06.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent collecting initial stability metrics
-    from a file on disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.InitialSnapshotTime.Total" units="ms"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as the information it provides is no longer useful.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent collecting initial stability metrics
-    from all files on disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.SnapshotTime.File" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Access times are consistently on the order of a few ms. Removed 2019/06.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent collecting metrics from a file on disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.FileMetricsProvider.SnapshotTime.Total" units="ms"
-    expires_after="2018-04-12">
-  <obsolete>
-    Removed April, 2018 as the information it provides is no longer useful.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent collecting metrics from all files on
-    disk.
-  </summary>
-</histogram>
-
-<histogram name="UMA.GeneratedLowEntropySource" enum="Boolean"
-    expires_after="2015-08-07">
-  <obsolete>
-    Removed as of August 2015. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    For each attempt to generate the low entropy source, log whether or not the
-    load required generating a new low entropy source.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Histograms.Activity" enum="HistogramActivityReport"
-    expires_after="2017-10-16">
-  <obsolete>
-    Removed as of October 2017. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Type and flags of every histogram created plus other activities. Counts are
-    not mutually-exclusive except for the different types.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.DroppedSampleCount" units="samples"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18. Renamed to
-    UMA.JavaCachingRecorder.DroppedHistogramSampleCount and reports also
-    histogram samples dropped due to a limit of the number of cached histograms.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of histogram samples that were not recorded when flushing due to a
-    per-histogram sample count limit in the Java in-memory cache.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.FullHistogramCount" units="histograms"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18 to reduce the number of histograms emitted by the
-    cache.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of histograms for which not all samples may have been recorded when
-    flushing the Java in-memory cache due to a per-histogram sample count limit.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.HistogramLimitDroppedSampleCount"
-    units="samples" expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18 to reduce the number of histograms emitted by the
-    cache. UMA.JavaCachingRecorder.DroppedHistogramSampleCount includes
-    histogram samples that were reported in this histogram.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of samples that were not recorded when flushing the Java in-memory
-    cache due to a histogram count limit.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.InputSampleCount" units="samples"
-    expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18. Renamed to
-    UMA.JavaCachingRecorder.InputHistogramSampleCount.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of histogram samples seen by the time the Java in-memory cache was
-    flushed. This is a sum of DroppedSampleCount and FlushedHistogramCount.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.RemainingHistogramLimit"
-    units="histograms" expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18 to reduce the number of histograms emitted by the
-    cache.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    The remaining histogram count limit when flushing in the Java in-memory
-    cache.
-  </summary>
-</histogram>
-
-<histogram name="UMA.JavaCachingRecorder.RemainingSampleLimit"
-    units="histograms" expires_after="2020-03-31">
-  <obsolete>
-    Removed on 2020-03-18 to reduce the number of histograms emitted by the
-    cache.
-  </obsolete>
-  <owner>bttk@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    The smallest remaining sample count limit in metrics flushed from the Java
-    in-memory cache.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Large Accumulated Log Not Persisted" units="bytes"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 2020-04
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of bytes in an excessively large log that was discarded at shutdown
-    instead of being saved to disk to retry during next chrome run.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Large Rejected Log was Discarded" units="bytes"
-    expires_after="2018-08-30">
-  <obsolete>
-    Removed 2020-04
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Number of bytes in a log was was rejected by server, and then discarded.
-  </summary>
-</histogram>
-
-<histogram name="UMA.LoadLogsTime" units="ms" expires_after="2015-08-05">
-  <obsolete>
-    Removed as of August 2015. The histograms showed no unexpected slowness, and
-    a profiler is a better tool for identifying any future issues.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The time spent to load (de-serialize) unsent logs from local state, recorded
-    during the MetricsService startup sequence.
-  </summary>
-</histogram>
-
-<histogram name="UMA.LogLoadComplete called" units="units"
-    expires_after="2016-04-09">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Simple counter of the number of times LogLoadComplete was called (bug
-    demonstration, as we're called more often than once per page load :-/ )
-  </summary>
-</histogram>
-
-<histogram name="UMA.LogUpload.ConnetionType" enum="NetworkConnectionType"
-    expires_after="2016-04-11">
-  <obsolete>
-    Used for analyzing UMA log uploads on cellular connection, but necessary
-    after the analysis is finished.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>gayane@chromium.org</owner>
-  <summary>
-    The network connection type for each successful metrics log upload.
-  </summary>
-</histogram>
-
-<histogram name="UMA.LogUploader.UploadSize" units="bytes"
-    expires_after="2019-01-22">
-  <obsolete>
-    Removed in favor of UMA.LogSize.OnSuccess
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>holte@chromium.org</owner>
-  <summary>
-    Reports total upload length in bytes when the UMA service type is used.
-  </summary>
-</histogram>
-
-<histogram name="UMA.MetricsService.DeletedDirectorySize.Failure" units="KB"
-    expires_after="2018-02-09">
-  <obsolete>
-    This metrics was to provide information for crbug/760317 which has been
-    resolved. Removed February, 2018.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records the size of the metrics directory size, after failing to be deleted.
-    This is a temporary metric that will be removed in M63 or M64.
-  </summary>
-</histogram>
-
-<histogram name="UMA.MetricsService.DeletedDirectorySize.Success" units="KB"
-    expires_after="2018-02-09">
-  <obsolete>
-    This metrics was to provide information for crbug/760317 which has been
-    resolved. Removed February, 2018.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records the size of the metrics directory size, after being successfully
-    deleted. This should always be zero unless there is a bug in the return
-    code. This is a temporary metric that will be removed in M63 or M64.
-  </summary>
-</histogram>
-
-<histogram name="UMA.MetricsService.RecordCurrentHistograms.Time" units="ms"
-    expires_after="2018-02-07">
-  <obsolete>
-    Removed February, 2018 because persistent metrics are fully launched with no
-    observable change in operation time.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    Records how much wall time was spent merging, taking snapshots, and
-    recording histograms for reporting to UMA.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Perf.GetData" enum="GetPerfDataOutcome"
-    expires_after="2019-01-14">
-  <obsolete>
-    Removed 01/2019 in b/110205489 being split into ChromeOS.CWP.CollectPerf and
-    ChromeOS.CWP.UploadPerf.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    A count of successes and various failure modes related to collecting and
-    processing performance data obtained through &quot;perf&quot; on Chrome OS.
-  </summary>
-</histogram>
-
-<histogram base="true" name="UMA.PersistentAllocator.Allocs" units="bytes"
-    expires_after="2017-02-16">
-  <obsolete>
-    Removed 2/2017 for Issue 689315 which indicated they weren't being used.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Size, before padding, of objects allocated from persistent memory. This is
-    updated with every allocation.
-  </summary>
-</histogram>
-
-<histogram name="UMA.PersistentHistograms.TmpRemovals" units="units"
-    expires_after="M77">
-  <obsolete>
-    Data showed many files being deleted during rollout and then tapering off to
-    near zero. Removed 2019/07.
-  </obsolete>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Number of old .tmp files of the kind that Windows creates and leaves around
-    when trying to rename a file to another one that already exists. See
-    https://crbug.com/934164
-  </summary>
-</histogram>
-
-<histogram name="UMA.ProfilesCount.AfterErase" units="units"
-    expires_after="2016-06-14">
-  <obsolete>
-    Removed as of Jun 2016. The histogram was added for debugging purpose and is
-    not needed anymore.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>yiyaoliu@chromium.org</owner>
-  <summary>
-    Record the number of loaded profiles when a profile is erased from the
-    profiles map kept by profile manager.
-  </summary>
-</histogram>
-
-<histogram name="UMA.ProtoGzipped" enum="Boolean" expires_after="2013-09-13">
-  <obsolete>
-    Removed as of Sep, 2013. Gzipping protobufs is now the default.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>Was the UMA protobuf uploaded earlier compressed or not.</summary>
-</histogram>
-
-<histogram name="UMA.ProtoGzippedKBSaved" units="KB" expires_after="2015-08-06">
-  <obsolete>
-    Removed as of August 2015. See UMA.ProtoCompressionRatio instead.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Kilobytes saved from gzipping the protobufs before uploading them.
-  </summary>
-</histogram>
-
-<histogram name="UMA.StoreLogsTime" units="ms" expires_after="2015-08-05">
-  <obsolete>
-    Removed as of August 2015. The histograms showed no unexpected slowness, and
-    a profiler is a better tool for identifying any future issues.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The time spent to store unsent logs to local state, which is done
-    periodically and also during start up if there was an initial stability log.
-  </summary>
-</histogram>
-
-<histogram name="UMA.SubprocessMetricsProvider.SubprocessCount"
-    units="subprocesses" expires_after="2020-04-05">
-  <obsolete>
-    Removed 2020/04
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    The number of subprocesses from which persistent metrics were collected,
-    logged once with every reporting cycle.
-  </summary>
-</histogram>
-
-<histogram name="UMA.SubprocessMetricsProvider.UntrackedProcesses"
-    enum="SubprocessType" expires_after="M77">
-  <obsolete>
-    Removed 2019/06 after not reporting anything in years.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The number of subprocesses, by type, from which persistent metrics are NOT
-    collected because there is no information about this (likely new) process
-    type. Process numbers 1000 or greater are &quot;custom&quot; processes used
-    by embedders.
-  </summary>
-</histogram>
-
-<histogram name="UMA.SyntheticTrials.Count" units="units"
-    expires_after="2015-08-06">
-  <obsolete>
-    Removed as of August 2015.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The number of synthetic field trials added to the UMA log when the system
-    profile is recorded. Since this is done prior to capturing the histograms
-    from the current process, this will generally be logged once per UMA log.
-  </summary>
-</histogram>
-
-<histogram name="UMA.Unacceptable_Log_Discarded" units="units"
-    expires_after="2013-07-11">
-  <obsolete>
-    Removed as of May, 2012 (i.e. Chrome 21+). Replaced by the
-    UMA.UploadResponseStatus.XML and UMA.UploadResponseStatus.Protobuf
-    histograms.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The server returned a 400 code, and we discarded a log.
-
-    This tends to indicate that a syntax error is present in a log, such as
-    would appear when a bogus XML tag is included, or the XML is not balanced
-    and well structured.
-  </summary>
-</histogram>
-
-<histogram name="UMA.UploadCreation" enum="BooleanSuccess"
-    expires_after="2015-08-06">
-  <obsolete>
-    Removed as of August 2015. This failure case no longer exists.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    For each attempted UMA upload, log whether the upload was successfully
-    constructed. An upload might fail to be constructed, for example, if we try
-    to upload before the system is fully initialized; or if serialization of the
-    data fails.
-  </summary>
-</histogram>
-
-<histogram name="UMA.UploadResponseStatus.Protobuf"
-    enum="UmaUploadResponseStatus" expires_after="2017-04-04">
-  <obsolete>
-    Replaced by UMA.LogUpload.ResponseOrErrorCode
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    For each upload to the protocol buffer (v2) UMA server, log whether the
-    upload was successful, or whether there was an error.
-  </summary>
-</histogram>
-
-<histogram name="UMA.UploadResponseStatus.XML" enum="UmaUploadResponseStatus"
-    expires_after="2014-10-15">
-  <obsolete>
-    Removed 2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    For each upload to the XML (v1) UMA server, log whether the upload was
-    successful, or whether there was an error.
-  </summary>
-</histogram>
-
-<histogram name="UMA.UsedResetVariationsFlag" enum="BooleanUsage"
-    expires_after="2016-04-09">
-  <obsolete>
-    No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Log whether the --reset-variation-state flag was set before the low entropy
-    source was requested.
-  </summary>
-</histogram>
-
-<histogram name="UMA.XMLNodeDumpTime" units="ms" expires_after="2014-10-15">
-  <obsolete>
-    Removed 2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The time spent in converting the XML tree into a character buffer when
-    closing a metrics log (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="UMA.XMLWriterDestructionTime" units="ms"
-    expires_after="2014-10-15">
-  <obsolete>
-    Removed 2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The time spent in freeing the XML writer and tree when closing a metrics log
-    (Chrome OS).
-  </summary>
-</histogram>
-
-<histogram name="UnifiedConsent.ConsentBump.Action"
-    enum="UnifiedConsentBumpAction" expires_after="2018-11-30">
-  <obsolete>
-    Removed 2018/11, because the consent bump was removed.
-  </obsolete>
-  <owner>tangltom@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    The action the user takes when the unified consent bump is shown.
-  </summary>
-</histogram>
-
-<histogram name="UnifiedConsent.ConsentBump.EligibleAtStartup" enum="Boolean"
-    expires_after="2018-11-30">
-  <obsolete>
-    Removed 2018/11, because the consent bump was removed.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <owner>tangltom@chromium.org</owner>
-  <summary>
-    Boolean indicating whether the user is eligible for seeing the consent bump.
-    This metric is recorded at every startup when Unified Consent is enabled.
-    Note: There can be multiple entries per user.
-  </summary>
-</histogram>
-
-<histogram name="UnifiedConsent.ConsentBump.SuppressReason"
-    enum="UnifiedConsentBumpSuppressReason" expires_after="2018-11-30">
-  <obsolete>
-    Removed 2018/11, because the consent bump was removed.
-  </obsolete>
-  <owner>tangltom@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <summary>
-    The reason the consent bump isn't shown to the user. This is recorded at
-    startup during the migration to Unified Consent.
-  </summary>
-</histogram>
-
-<histogram name="UnifiedConsent.RevokeReason" enum="UnifiedConsentRevokeReason"
-    expires_after="2018-11-27">
-  <obsolete>
-    Removed 2018/11 because it's no longer necessary.
-  </obsolete>
-  <owner>droger@chromium.org</owner>
-  <owner>msarda@chromium.org</owner>
-  <owner>tangltom@chromium.org</owner>
-  <summary>
-    The reason the unified consent was revoked. This is recorded every time the
-    consent state changes from &quot;unified consent given&quot; to
-    &quot;unified consent not given&quot;.
-  </summary>
-</histogram>
-
-<histogram name="UnifiedConsent.SyncAndGoogleServicesSettings"
-    enum="UnifiedConsentSyncAndGoogleServicesSettings"
-    expires_after="2020-01-20">
-  <obsolete>
-    Renamed as UnifiedConsent.MakeSearchesAndBrowsingBetter.OnStartup in 01/2020
-    because today the UnifiedConsent service only manages the Make Searches and
-    Browsing better feature.
-  </obsolete>
-  <owner>msarda@chromium.org</owner>
-  <owner>droger@chromium.org</owner>
-  <summary>
-    State of the user settings for Sync and Google services, recorded at
-    startup. Multiple samples may be recorded at once, except for 'None' which
-    is recorded when no other bucket is used.
-  </summary>
-</histogram>
-
-<histogram name="Uptime.ProcessesTerminatedToXTerminatedAfterLogout" units="ms"
-    expires_after="2018-06-06">
-  <obsolete>
-    Removed 05/2018 in Issue 721891 with removal of X11. Replaced by
-    Uptime.OtherProcessesTerminatedToChromeExecAfterLogout in ChromeOS M69.
-    Equal to 0 since at least ChromeOS M62.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Measures the time elapsed on Chrome OS between when all user-associated
-    processes (including the X server) have been terminated during the logout
-    process. This statistic is not collected if the logout is part of a restart
-    or shutdown.
-  </summary>
-</histogram>
-
-<histogram name="Uptime.XTerminatedToChromeExecAfterLogout" units="ms"
-    expires_after="2018-06-06">
-  <obsolete>
-    Replaced by Uptime.OtherProcessesTerminatedToChromeExecAfterLogout in
-    ChromeOS M69. Equivalent to the new name since at least ChromeOS M62.
-  </obsolete>
-  <owner>hajimehoshi@chromium.org</owner>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    Measures the time elapsed on Chrome OS between when the X server has been
-    terminated from a previous logout and when Chrome is started again to show
-    the login screen.
-  </summary>
-</histogram>
-
-<histogram name="URLBlacklistManager.ConstructorBuildTime" units="ms"
-    expires_after="2018-09-04">
-  <obsolete>
-    Served its purpose; deprecated 9/2018 in M71 (https://crbug.com/827173).
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The time it took to build and set the URL blacklist on the main thread
-    within URLBlacklistManager's constructor.
-  </summary>
-</histogram>
-
-<histogram name="UrlFetcher.StringResponseSize" units="KB"
-    expires_after="2017-10-11">
-  <obsolete>
-    Removed 10/2017.
-  </obsolete>
-  <owner>mmenke@chromium.org</owner>
-  <summary>
-    Size (in kilobytes) of response bodies retrieved as strings from URLFetcher.
-  </summary>
-</histogram>
-
-<histogram name="UserActivation.AvailabilityCheck.FrameResult"
-    enum="UserActivationFrameResultEnum" expires_after="M80">
-  <obsolete>
-    This was added to assess possible impact of UserActivationV2, by comparing
-    pre- and post-launch stats.
-  </obsolete>
-  <owner>mustaq@chromium.org</owner>
-  <summary>
-    Outcomes (success/failure) of transient user activation availability check
-    attempts for each type of caller frame (null, ancestor, descedant, other).
-  </summary>
-</histogram>
-
-<histogram name="UserActivation.Consumption.FrameResult"
-    enum="UserActivationFrameResultEnum" expires_after="M80">
-  <obsolete>
-    This was added to assess possible impact of UserActivationV2, by comparing
-    pre- and post-launch stats.
-  </obsolete>
-  <owner>mustaq@chromium.org</owner>
-  <summary>
-    Outcomes (success/failure) of user activation consumption attempts for each
-    type of caller frame (null, ancestor, descedant, other).
-  </summary>
-</histogram>
-
-<histogram name="UserCert.ContentDisposition" enum="UserCertContentDisposition"
-    expires_after="2016-12-21">
-  <obsolete>
-    Removed in M57.
-  </obsolete>
-  <owner>rsleevi@chromium.org</owner>
-  <owner>svaldez@chromium.org</owner>
-  <summary>
-    Distribution of Content-Disposition headers sent with x-x509-user-cert
-    content types.
-  </summary>
-</histogram>
-
-<histogram name="UserImage.ChangeChoice" enum="ChromeOSUserImageId"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2020-07 (crbug.com/975700).
-  </obsolete>
-  <owner>raleksandrov@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Distribution of the default images that users choose in Change Picture
-    dialog (Chrome OS). One sample is taken each time the user changes picture.
-  </summary>
-</histogram>
-
-<histogram name="UserImage.FirstTimeChoice" enum="ChromeOSUserImageId"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85. The OOBE user image screen is long gone.
-  </obsolete>
-  <owner>achuith@chromium.org</owner>
-  <summary>
-    Distribution of the default images chosen on user image screen during
-    out-of-the-box experience (Chrome OS). One sample is taken each time the
-    user confirms the choice by clicking OK button.
-  </summary>
-</histogram>
-
-<histogram name="UserImage.ProfileDownloadResult"
-    enum="ProfileImageDownloadResult" expires_after="M77">
-  <obsolete>
-    Removed on 2020-07 (crbug.com/1037348).
-  </obsolete>
-  <owner>raleksandrov@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Profile image download result for UserManager (either on behalf of the
-    Change Picture prefs page, OOBE or scheduled refresh after user login).
-  </summary>
-</histogram>
-
-<histogram name="UserImage.ScreenIsShownTime" units="ms" expires_after="M85">
-  <obsolete>
-    Removed in M85. The OOBE user image screen is long gone.
-  </obsolete>
-  <owner>achuith@chromium.org</owner>
-  <summary>
-    Time histogram of the &quot;Choose Picture&quot; OOBE screen display delay.
-  </summary>
-</histogram>
-
-<histogram name="UserInterfaceStyle.ChangedWhileActive"
-    enum="IOSUserInterfaceStyle" expires_after="M81">
-  <obsolete>
-    Removed. Chrome can't listen to changes in the background, these are delayed
-    until the app becomes active again. Use UserInterfaceStyle.CurrentlyUsed
-    instead.
-  </obsolete>
-  <owner>javierrobles@chromium.org</owner>
-  <owner>rkgibson@google.com</owner>
-  <owner>bling-team@google.com</owner>
-  <summary>
-    [iOS] Used on iOS 13+ to report the changes to Light and Dark mode. This is
-    logged when the interface style changes and Chrome is active. Can be caused
-    by the system automatic switch or by the user manually changing the style.
-  </summary>
-</histogram>
-
-<histogram name="UserSessionManager.UserPodsDisplay" enum="UserPodsDisplay"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2020-06 (crbug.com/975711).
-  </obsolete>
-  <owner>raleksandrov@google.com</owner>
-  <owner>cros-oac@google.com</owner>
-  <summary>
-    Whether the user pods were enabled during login, and what could disable
-    them.
-  </summary>
-</histogram>
-
-<histogram name="V8.ArrayBufferBigAllocations" units="MB"
-    expires_after="2017-05-05">
-  <obsolete>
-    Removed 5/2017 in Issue 704922. Replaced by V8.ArrayBufferLargeAllocations.
-  </obsolete>
-  <owner>gdeepti@chromium.org</owner>
-  <owner>titzer@chromium.org</owner>
-  <owner>kschimpf@chromium.org</owner>
-  <summary>Number of bytes requested in an array buffer allocation.</summary>
-</histogram>
-
-<histogram name="V8.AsmModuleSizeBytes" units="bytes" expires_after="M77">
-  <obsolete>
-    Removed on 2019-06 (crbug.com/969997).
-  </obsolete>
-  <owner>mstarzinger@chromium.org</owner>
-  <owner>titzer@chromium.org</owner>
-  <summary>Size of asm.js module (in asm.js format).</summary>
-</histogram>
-
-<histogram name="V8.AsmWasmTranslationMicroSeconds" units="microseconds"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2019-06 (crbug.com/969997).
-  </obsolete>
-  <owner>mstarzinger@chromium.org</owner>
-  <owner>titzer@chromium.org</owner>
-  <summary>
-    Time to convert asm.js code to WebAssembly.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.AsmWasmTranslationThroughput" units="MB/s"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Throughput of translation of asm.js code to WebAssembly in MB/s.
-  </summary>
-</histogram>
-
-<histogram name="V8.ASTOptimization" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="V8.CodeCreation" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="V8.CodeGeneration" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>Time spent generating native code for functions.</summary>
-</histogram>
-
-<histogram name="V8.CodegenFractionCrankshaft" units="%"
-    expires_after="2016-07-19">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <owner>rmcilroy@chromium.org</owner>
-  <summary>
-    Fraction of the total generated code which was generated using the
-    Crankshaft optimizing compiler, after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.Compile" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.CompileMicroSeconds.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <owner>yangguo@chromium.org</owner>
-  <summary>Time spent in V8 compiler (full codegen).</summary>
-</histogram>
-
-<histogram name="V8.CompileDeserialize" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.CompileDeserializeMicroSeconds.
-  </obsolete>
-  <owner>vogelheim@chromium.org</owner>
-  <summary>Time spent deseriailzing code, used by V8 code caching.</summary>
-</histogram>
-
-<histogram name="V8.CompileEval" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.CompileEvalMicroSeconds.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <summary>Time spent in V8 compiler (full codegen) for eval.</summary>
-</histogram>
-
-<histogram name="V8.CompileHeuristicsDecision" enum="CompileHeuristicsDecision"
-    expires_after="2017-11-03">
-  <obsolete>
-    This histogram has been replaced by V8.CompileTime.CacheBehaviour.
-  </obsolete>
-  <owner>kouhei@chromium.org</owner>
-  <summary>
-    V8 script compile function variant which was picked. This contains
-    information such as {if,why} v8 {code,parser} was
-    {produced,consumed,bypassed}.
-  </summary>
-</histogram>
-
-<histogram name="V8.CompileInlineScriptMicroSeconds" units="microseconds"
-    expires_after="2017-11-03">
-  <obsolete>
-    This histogram has been replaced by
-    V8.CompileTimeMicroSeconds.NoCache.InlineScript.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <summary>Time spent compiling an inline script.</summary>
-</histogram>
-
-<histogram name="V8.CompileLazy" units="ms" expires_after="2014-09-16">
-  <obsolete>
-    This histogram has been replaced by V8.CompileLazyMicroSeconds.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>Time spent compiling functions lazily on first run.</summary>
-</histogram>
-
-<histogram name="V8.CompileNoncacheableMicroSeconds" units="microseconds"
-    expires_after="2017-11-03">
-  <obsolete>
-    This histogram has been replaced by the subcategories of
-    V8.CompileTimeMicroSeconds.NoCache
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <summary>
-    Time spent compiling a script that cannot be subject to caching.
-  </summary>
-</histogram>
-
-<histogram name="V8.CompileScript" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.CompileScriptMicroSeconds.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <summary>
-    Total time spent in compiling a script (incl. parsing/caching).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.CompileSerialize" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.CompileSerializeMicroSeconds.
-  </obsolete>
-  <owner>vogelheim@chromium.org</owner>
-  <summary>Time spent serializing code, used by V8 code caching.</summary>
-</histogram>
-
-<histogram name="V8.DeferredCodeGeneration" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>Time spent generating deferred code stubs.</summary>
-</histogram>
-
-<histogram name="V8.DetachedContextAgeInGC" units="units" expires_after="M80">
-  <obsolete>
-    This histogram has been removed.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    Number of garbage collections that a detached global context survives,
-    recorded after each major garbage collection. Values greater than 7 indicate
-    a memory leak.
-  </summary>
-</histogram>
-
-<histogram name="V8.ExecutableMemoryMax" units="bytes"
-    expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>
-    The maximum memory used to store V8 compiled code on a given process.
-  </summary>
-</histogram>
-
-<histogram name="V8.GC.ParallelTaskLatencyMicroSeconds" units="microseconds"
-    expires_after="2019-02-19">
-  <obsolete>
-    Removed in Feb 2019. No longer tracked in V8.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Latency (post-to-schedule) of each parallel task posted during V8 garbage
-    collection.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.GCContext" units="ms" expires_after="2020-06-01">
-  <obsolete>
-    Removed in April 2020. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>Time spent doing a full GC during an IdleNotification.</summary>
-</histogram>
-
-<histogram name="V8.GCIdleNotification" units="ms" expires_after="2020-06-01">
-  <obsolete>
-    Removed in April 2020. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>Time spent in IdleNotifications.</summary>
-</histogram>
-
-<histogram name="V8.GCIdleTimeAllottedInMS" units="ms"
-    expires_after="2017-08-03">
-  <obsolete>
-    Removed in August 2017. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>Idle time passed to V8 via IdleNotifications.</summary>
-</histogram>
-
-<histogram name="V8.GCIdleTimeLimit.Overshot" units="ms"
-    expires_after="2017-08-03">
-  <obsolete>
-    Removed in August 2017. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Milliseconds the idle time limit was overshot by the IdleNotification.
-  </summary>
-</histogram>
-
-<histogram name="V8.GCIdleTimeLimit.Undershot" units="ms"
-    expires_after="2017-08-03">
-  <obsolete>
-    Removed in August 2017. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Milliseconds the idle time limit was undershot by the IdleNotification.
-  </summary>
-</histogram>
-
-<histogram name="V8.GCLowMemoryNotification" units="ms"
-    expires_after="2020-06-01">
-  <obsolete>
-    Removed in April 2020. No longer tracked.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>Time spent in LowMemoryNotifications.</summary>
-</histogram>
-
-<histogram name="V8.GCYoungGenerationHandling" enum="YoungGenerationHandling"
-    expires_after="M85">
-  <obsolete>
-    Removed in April 2020. No longer tracked.
-  </obsolete>
-  <owner>mlippautz@chromium.org</owner>
-  <summary>
-    Type of garbage collection strategy used to collect the young generation.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryExternalFragmentationCellSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    This histogram has been replaced by V8.MemoryExternalFragmentationOldSpace.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    External memory fragmentation in the cell space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryExternalFragmentationOldDataSpace" units="%"
-    expires_after="2015-05-22">
-  <obsolete>
-    This histogram has been replaced by V8.MemoryExternalFragmentationOldSpace.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    External memory fragmentation in the old data space after each GC in
-    percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryExternalFragmentationOldPointerSpace" units="%"
-    expires_after="2015-05-22">
-  <obsolete>
-    This histogram has been replaced by V8.MemoryExternalFragmentationOldSpace.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    External memory fragmentation in the old pointer space after each GC in
-    percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapCommitted" units="KB" expires_after="2018-07-17">
-  <obsolete>
-    This histogram has been replaced by Memory.Experimental.Renderer2.V8.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    The committed memory used by V8 in KB averaged over time, logged before each
-    GC.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionCellSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the cell space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionCodeSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the code space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionLoSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the lo space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionMapSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the map space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionNewSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the new space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionOldDataSpace" units="%"
-    expires_after="2015-05-22">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the old data space after each GC in
-    percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionOldPointerSpace" units="%"
-    expires_after="2015-05-22">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the old pointer space after each GC in
-    percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapFractionOldSpace" units="%"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    Fraction of the total heap used by the old space after each GC in percent.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapSampleCellSpaceCommitted" units="KB"
-    expires_after="2017-09-27">
-  <obsolete>
-    Removed as of 09/2017.
-  </obsolete>
-  <owner>hpayer@chromium.org</owner>
-  <summary>
-    The size of committed memory in the cell space after each GC in KB.
-  </summary>
-</histogram>
-
-<histogram name="V8.MemoryHeapUsed" units="KB" expires_after="2018-07-17">
-  <obsolete>
-    This histogram has been replaced by
-    Memory.Experimental.Renderer2.V8.AllocatedObjects.
-  </obsolete>
-  <owner>ulan@chromium.org</owner>
-  <summary>
-    The live memory used by V8 in KB averaged over time, logged before each GC.
-  </summary>
-</histogram>
-
-<histogram name="V8.Parse" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.ParseMicroSeconds.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>Time spent in V8 parser.</summary>
-</histogram>
-
-<histogram name="V8.ParseLazy" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.ParseLazyMicroSeconds.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>
-    Time spent parsing functions when they are lazily compiled on first run.
-  </summary>
-</histogram>
-
-<histogram name="V8.ParseLazyMicroSeconds" units="microseconds"
-    expires_after="2016-10-26">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>
-    Time spent parsing functions when they are lazily compiled on first run.
-  </summary>
-</histogram>
-
-<histogram name="V8.ParseMicroSeconds" units="microseconds"
-    expires_after="2016-10-26">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>Time spent in V8 parser.</summary>
-</histogram>
-
-<histogram name="V8.PreParse" units="ms" expires_after="2015-01-27">
-  <obsolete>
-    This histogram has been replaced by V8.PreParseMicroSeconds.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>Time spent preparsing source code.</summary>
-</histogram>
-
-<histogram name="V8.PreParseMicroSeconds" units="microseconds"
-    expires_after="2016-10-26">
-  <obsolete>
-    Removed.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>Time spent preparsing source code.</summary>
-</histogram>
-
-<histogram name="V8.Rewriting" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>Time spent on rewriting ASTs before compilation.</summary>
-</histogram>
-
-<histogram name="V8.RSetLO" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="V8.RSetPaged" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="V8.ScriptCache" units="units" expires_after="2015-01-27">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>yangguo@chromium.org</owner>
-  <summary>
-    The generation a compiled script was found in the compilation cache.
-  </summary>
-</histogram>
-
-<histogram name="V8.UsageAnalysis" units="units" expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>Time spent analysing the usage of variables.</summary>
-</histogram>
-
-<histogram name="V8.VariableAllocation" units="units"
-    expires_after="2014-09-16">
-  <obsolete>
-    This histogram is no longer present in V8.
-  </obsolete>
-  <owner>hablich@chromium.org</owner>
-  <summary>TBD</summary>
-</histogram>
-
-<histogram name="V8.WasmCodeGCTime" units="microseconds" expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Time to execute a single WebAssembly code GC, measured from when it is
-    triggered until all isolates reported live code and all dead code was freed.
-    Recorded after each WebAssembly code GC if a high-resolution clock is
-    available.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmDecodeFunctionMicroSeconds" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053286).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Time to decode a WebAssembly function. Recorded on each validation of a
-    WebAssembly function.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmDecodeModuleMicroSeconds" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Time to decode a WebAssembly module. Recorded for each WebAssembly module
-    which is decoded for validation, compilation, or deserialization.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmDecodeModulePeakMemoryBytes" units="bytes"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Peak memory used to decode a WebAssembly module. Recorded for each
-    WebAssembly module which is decoded for validation, compilation, or
-    deserialization.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmDeserializeModuleStreamingMicroSeconds"
-    units="microseconds" expires_after="2019-10-31">
-  <obsolete>
-    Removed 10/2019. No longer tracked.
-  </obsolete>
-  <owner>bbudge@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    Time to deserialize a WebAssembly module during streaming compilation (via
-    the 'WebAssembly.compileStreaming' API). Recorded on each streaming
-    WebAssembly deserialization from the code cache, but only if a
-    high-resolution clock is available. Note that compilation speed is often
-    limited by the network speed, which is also reflected in thie metric.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmExecutionTimeMicroSeconds" units="microseconds"
-    expires_after="2019-03-12">
-  <obsolete>
-    Removed 03/2019. No longer tracked.
-  </obsolete>
-  <owner>titzer@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <summary>
-    Time spent executing WebAssembly.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmLazyCompilationMicroSeconds" units="microseconds"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Time for lazy compilation of WebAssembly functions. This is recorded per
-    function for the functions that are lazily compiled.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmLazyCompilationThroughput" units="KB/s"
-    expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    Throughput of compilation of lazily compiled WebAssembly functions in KB/s
-    (size of function in wasm format divided by time to compile it). This is
-    recorded per function for functions that are lazily compiled.
-  </summary>
-</histogram>
-
-<histogram name="V8.WasmModuleCodeSizeFreed" units="MB" expires_after="M81">
-  <obsolete>
-    Removed in M82 (crbug.com/1053285).
-  </obsolete>
-  <owner>ecmziegler@chromium.org</owner>
-  <owner>adamk@chromium.org</owner>
-  <owner>clemensb@chromium.org</owner>
-  <summary>
-    The amount of WebAssembly code freed by garbage collection, in MiB. Recorded
-    for each live module after each full GC.
-  </summary>
-</histogram>
-
-<histogram name="Variations.DisabledNoEntropyProvider" enum="BooleanHit"
-    expires_after="2013-06-07">
-  <obsolete>
-    Removed 1/2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    A count of the number of times we hit the code where a field trial is
-    disabled because no entropy provider was provided.
-  </summary>
-</histogram>
-
-<histogram name="Variations.DownloadJobFetchTime" units="ms"
-    expires_after="2021-01-31">
-  <obsolete>
-    Removed 02/2020. Replaced by Variations.WebViewDownloadJobFetchTime2, which
-    has a higher maximum bucket.
-  </obsolete>
-  <owner>rmcelrath@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    The duration of the network request to downloads a new WebView variations
-    seed from the variations server to the central on-device service.
-  </summary>
-</histogram>
-
-<histogram name="Variations.FailedRequestErrorCode" enum="NetErrorCodes"
-    expires_after="2016-10-03">
-  <obsolete>
-    Removed 10/2016. Replaced by Variations.SeedFetchResponseOrErrorCode.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The counts of network error codes encountered by VariationsService when an
-    attempt to fetch a variations seed from the server fails.
-  </summary>
-</histogram>
-
-<histogram name="Variations.FetchNotModifiedLatency" units="ms"
-    expires_after="2014-02-26">
-  <obsolete>
-    Removed 2/2014. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The latency of a VariationsService seed fetch that results in a not modified
-    response.
-  </summary>
-</histogram>
-
-<histogram name="Variations.FetchOtherLatency" units="ms"
-    expires_after="2014-02-26">
-  <obsolete>
-    Removed 2/2014. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The latency of a VariationsService seed fetch that results in neither a
-    success nor not modified response.
-  </summary>
-</histogram>
-
-<histogram name="Variations.FetchSuccessLatency" units="ms"
-    expires_after="2014-02-26">
-  <obsolete>
-    Removed 2/2014. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The latency of a VariationsService seed fetch that results in a success
-    response.
-  </summary>
-</histogram>
-
-<histogram name="Variations.GoogleUpdateRegistryLabelsNeedClearing"
-    enum="BooleanNeedsClearing" expires_after="M80">
-  <obsolete>
-    No longer logged
-  </obsolete>
-  <owner>jwd@chromium.org</owner>
-  <summary>
-    If the registry value for Google Update experiment labels contains
-    Variations experiments, and therefore needs to have them cleared. This will
-    be recorderd once per sessions, right before attempting to clear the value.
-  </summary>
-</histogram>
-
-<histogram name="Variations.HeaderConstructionTime" units="microseconds"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    How long it took to create the X-Client-Data header.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="Variations.NetworkAvailability" enum="BooleanSuccess"
-    expires_after="2013-04-19">
-  <obsolete>
-    Removed 9/2012. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Whether or not the network was available when requested by the
-    VariationsService.
-  </summary>
-</histogram>
-
-<histogram name="Variations.RestartsWithStaleSeed" units="restarts"
-    expires_after="2020-11-01">
-  <obsolete>
-    Removed as of M85 / Jun 2020.
-  </obsolete>
-  <owner>rmcelrath@chromium.org</owner>
-  <owner>ntfschr@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Number of consecutive times WebView started up with a stale seed. Only
-    written by WebView, when its loaded seed is fresh after previously being
-    stale. Note that this means it won't be written for WebViews that are never
-    able to get a fresh seed, or ones that consistently have a fresh seed.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SafeMode.FellBackToSafeMode" enum="BooleanSafeMode"
-    expires_after="2018-01-29">
-  <obsolete>
-    Removed as of M66 / Jan 2018. Replaced by
-    Variations.SafeMode.FellBackToSafeMode2.
-  </obsolete>
-  <owner>isherman@chromium.org</owner>
-  <summary>
-    Whether or not the VariationsService /would/ fall back to Safe Mode, due to
-    either too many crashes or too many failures to fetch a new seed, given some
-    initial/unrefined heuristics. Recorded during Chrome startup, when the
-    VariationsService is created.
-
-    This metric was only reported before Safe Mode was actually implemented, as
-    a sanity-check for the forthcoming implementation.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedDateSkew.BuildTimeAheadBy" units="days"
-    expires_after="2015-10-01">
-  <obsolete>
-    Removed as of 9/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logged on startup when creating field trials from the variations seed if the
-    build time is ahead of or within 24 hours of the kVariationsSeedDate. Used
-    as an experiment to see whether the build time could be used to discard very
-    old seeds.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedDateSkew.BuildTimeBehindBy" units="days"
-    expires_after="2015-10-01">
-  <obsolete>
-    Removed as of 9/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logged on startup when creating field trials from the variations seed if the
-    build time is behind the kVariationsSeedDate by a day or more. Used as an
-    experiment to see whether the build time could be used to discard very old
-    seeds.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedDateSkew.SystemClockAheadBy" units="days"
-    expires_after="2015-10-01">
-  <obsolete>
-    Removed as of 9/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logged on startup when creating field trials from the variations seed if the
-    system clock is ahead of or within 24 hours of the kVariationsSeedDate. Used
-    as an experiment to see whether the system clock could be used to discard
-    very old seeds.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedDateSkew.SystemClockBehindBy" units="days"
-    expires_after="2015-10-01">
-  <obsolete>
-    Removed as of 9/2015.
-  </obsolete>
-  <owner>gab@chromium.org</owner>
-  <summary>
-    Logged on startup when creating field trials from the variations seed if the
-    system clock is behind the kVariationsSeedDate by a day or more. Used as an
-    experiment to see whether the system clock could be used to discard very old
-    seeds.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedEmpty" enum="VariationsSeedLoadResult"
-    expires_after="2017-06-14">
-  <obsolete>
-    Removed in M61, and replaced by Variations.SeedLoadResult. This histogram
-    incorrectly conflated failures from loading the seed with failures while
-    attempting to store seeds with delta compression.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records whether the variations seed was successfully read from local state
-    on startup. Records a detailed reason on read failure.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedFetchResponseCode" enum="HttpResponseCode"
-    expires_after="2016-10-03">
-  <obsolete>
-    Removed 10/2016. Replaced by Variations.SeedFetchResponseOrErrorCode.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The counts of HTTP response codes encountered by VariationsService when
-    attempting to fetch a variations seed from the server.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedLoadSuccessTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 2019-06. See results on https://crbug.com/936172#c8.
-  </obsolete>
-  <owner>changwan@chromium.org</owner>
-  <summary>
-    Records the time spent loading the variations seed in WebView, specifically,
-    the time to call VariationsUtils.readSeedFile(). This is logged once per
-    WebView startup, and is only logged if loading was successful.
-  </summary>
-</histogram>
-
-<histogram name="Variations.SeedLoadWouldBlockTime" units="ms"
-    expires_after="M75">
-  <obsolete>
-    Removed 2019-06. See results on https://crbug.com/936172#c8.
-  </obsolete>
-  <owner>changwan@chromium.org</owner>
-  <summary>
-    Records how long we would block WebView startup to wait for the variations
-    seed if there were no timeout. This is measured from when we start blocking
-    until when the FutureTask which loads the seed finishes. The FutureTask may
-    finish before we block at all, in which case this will be 0. This is logged
-    once per WebView startup, whether or not loading was successful.
-  </summary>
-</histogram>
-
-<histogram name="Variations.ServerStudyExpiredUniformity1Percent"
-    enum="BooleanExpired" expires_after="2013-06-07">
-  <obsolete>
-    Removed 11/2012. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Whether or not the 1-Percent uniformity trial from the Variations server was
-    expired when loaded.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.DeltaSize" units="KiB"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    On successful save of a delta-compressed variations seed, records the size
-    of the delta in KiB.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.DeltaSize.ReductionPercent" units="%"
-    expires_after="M77">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    On successful save of a delta-compressed variations seed, records the size
-    of the delta as a percentage of the decoded seed size.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.GzipSize" units="KiB" expires_after="M80">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records the size of the gzip-compressed variations seed in KiB.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.GzipSize.ReductionPercent" units="%"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records the size of the gzip-compressed variations seed as a percentage of
-    the decoded seed size. Note that variations seed could be first
-    delta-compressed and then gzip-compressed. In this case we record
-    gzip-compressed seed size as a percentage of the delta-compressed seed size.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.HasCountry" enum="Boolean"
-    expires_after="M80">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records whether a country code was present when storing the variations seed.
-  </summary>
-</histogram>
-
-<histogram name="Variations.StoreSeed.Size" units="KiB" expires_after="M80">
-  <obsolete>
-    Removed 2019/07
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    On successful save of a non-delta-compressed variations seed, records the
-    size of the received seed in KiB.
-  </summary>
-</histogram>
-
-<histogram name="Variations.UniformityTrialExpired" enum="BooleanHit"
-    expires_after="2013-06-07">
-  <obsolete>
-    Removed 1/2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    A count of the number of times we hit the code where the
-    UMA-Uniformity-Trial-1-Percent field trial is disabled as a result of the
-    expiration check.
-  </summary>
-</histogram>
-
-<histogram name="Variations.UniformityTrialGroupNotActive"
-    enum="UniformityTrialGroupNotActive" expires_after="2013-06-07">
-  <obsolete>
-    Removed 1/2013. No longer tracked.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Tracks whether the UMA-Uniformity-Trial-1-Percent field trial was not active
-    and which factors contributed to it.
-  </summary>
-</histogram>
-
-<histogram name="Viewport.OverviewZoom" units="%" expires_after="M85">
-  <obsolete>
-    Expired in M85.
-  </obsolete>
-  <owner>bokan@chromium.org</owner>
-  <owner>input-dev@chromium.org</owner>
-  <summary>
-    The screen width as a percentage of viewport width (i.e. zoom at which we
-    can see the whole page). Only recorded on Android and for viewport meta tags
-    with constant width.
-  </summary>
-</histogram>
-
-<histogram name="VirtualKeyboard.ControllerStateTransitionIsValid"
-    enum="BooleanValid" expires_after="2019-06-12">
-  <obsolete>
-    Removed 2019/6 because it's equivalent to VirtualKeyboard.
-    ControllerStateTransition.
-  </obsolete>
-  <owner>oka@chromium.org</owner>
-  <summary>
-    Validity of a state transtion. This is equivalent to the positiveness of
-    VirtualKeyboard.ControllerStateTransition.
-  </summary>
-</histogram>
-
-<histogram name="VirtualKeyboard.KeystrokesBetweenBackspace" units="units"
-    expires_after="2016-04-29">
-  <obsolete>
-    Removed 04/2016 as doesn't have data nor owner.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Counts the number of keys typed by the virtual keyboard between each
-    backspace. This metric provides a rough approximation of an error rate for
-    the virtual keyboard.
-  </summary>
-</histogram>
-
-<histogram name="Viz.DisplayCompositor.SurfaceEmbeddingTime" units="ms"
-    expires_after="M85">
-  <obsolete>
-    This previously reported a latency metric for Viz on all platforms. This has
-    been replaced by improved tracing and Graphics.Smoothness metrics. Marked
-    obsolete in M87.
-  </obsolete>
-  <owner>jonross@chromium.org</owner>
-  <summary>
-    Records the delta from when a viz::LocalSurfaceId was allocated, to the time
-    where it is first embedded by the Viz Service.
-  </summary>
-</histogram>
-
-<histogram name="VoiceInteraction.OpenDuration" units="ms" expires_after="M85">
-  <obsolete>
-    Previously recorded for CrOS, but is no longer used. Marked obsolete in M86.
-  </obsolete>
-  <owner>xiaohuic@chromium.org</owner>
-  <summary>
-    Records the time between a voice interaction session start and end.
-  </summary>
-</histogram>
-
-<histogram name="VR.Component.Assets.DurationUntilReady.OnChromeStart"
-    units="ms" expires_after="2018-02-06">
-  <obsolete>
-    Removed 02/2018 in issue 799074.
-    VR.Component.Assets.DurationUntilReady.OnRegisterComponent measures the
-    intended metric more accurately.
-  </obsolete>
-  <owner>tiborg@chromium.org</owner>
-  <summary>
-    Duration from starting Chrome until VR assets component is ready to use.
-  </summary>
-</histogram>
-
-<histogram base="true" name="VR.Component.Assets.DurationUntilReady.OnEnter"
-    units="ms" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Duration from entering a VR mode until the VR assets component is ready to
-    use.
-  </summary>
-</histogram>
-
-<histogram name="VR.Component.Assets.DurationUntilReady.OnRegisterComponent"
-    units="ms" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Duration from registering VR assets component until it is ready to use.
-  </summary>
-</histogram>
-
-<histogram base="true" name="VR.Component.Assets.Status.OnEnter"
-    enum="VRComponentStatus" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>Status of the VR assets component when entering a VR mode.</summary>
-</histogram>
-
-<histogram name="VR.Component.Assets.VersionAndStatus.OnLoad"
-    enum="VRAssetsLoadStatus" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    The component version and status of loading the VR assets. The value is
-    encoded as (XXX)(YYY)(SSS) where XXX is the major component version, YYY the
-    minor component version and SSS the status. See
-    //chrome/browser/vr/assets_load_status.h for possible status values.
-  </summary>
-</histogram>
-
-<histogram name="VR.Component.Assets.VersionAndStatus.OnUpdate"
-    enum="VRAssetsComponentUpdateStatus" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    The version and update status of the VR assets component. The value is
-    encoded as (XXX)(YYY)(SSS) where XXX is the major version, YYY the minor
-    version and SSS the status. See
-    //chrome/browser/vr/assets_component_update_status.h for possible status
-    values.
-  </summary>
-</histogram>
-
-<histogram name="VR.EnterVrBrowserWithoutFeatureModule" enum="BooleanSuccess"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Recorded every time a user tries to enter the VR browser without the VR
-    feature module installed. Is success if the user could enter the VR browser
-    nonetheless. Is failure if entering the VR browser was blocked (on
-    smartphone VR) or started in 2D-in-VR mode (on standalones).
-  </summary>
-</histogram>
-
-<histogram base="true" name="VR.NetworkConnectionType.OnEnter"
-    enum="NetworkConnectionType" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>Network connection type when entering a VR mode.</summary>
-</histogram>
-
-<histogram name="VR.NetworkConnectionType.OnRegisterComponent"
-    enum="NetworkConnectionType" expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Network connection type when registering the VR component(s).
-  </summary>
-</histogram>
-
-<histogram name="VR.Session.VoiceSearch.StartedCount" units="searches"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed 02/2020
-  </obsolete>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Number of times voice search is started in a single VR session. Recorded
-    when a new disjoint session has begun or when the session has ended in a
-    non-continuable way.
-  </summary>
-</histogram>
-
-<histogram name="VR.Shell.EncounteredSuppressedUI" enum="VRSuppressedElement"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    We must suppress monocularly rendered ui elements in VR. This records which
-    ui element suppressions are encountered in practice.
-  </summary>
-</histogram>
-
-<histogram name="VR.Shell.EncounteredUnsupportedMode" enum="VRUnsupportedMode"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>vollick@chromium.org</owner>
-  <summary>
-    We must exit VR mode when browsing in certain situations. This records which
-    situations are encountered in practice.
-  </summary>
-</histogram>
-
-<histogram name="VR.VoiceSearch.EndState" enum="VRVoiceSearchEndState"
-    expires_after="M85">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>The end state of a voice search request in VR.</summary>
-</histogram>
-
-<histogram name="VR.VoiceSearch.RecordAudioOsPermissionPromptChoice"
-    enum="BooleanContinueChoice" expires_after="M85">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Chrome shows a prompt when the OS's record audio permission is needed for
-    voice search. The prompt gives user two choices: CANCEL or CONTINUE. This
-    records the user's selection.
-  </summary>
-</histogram>
-
-<histogram name="VRAutopresentedWebVR" enum="Boolean"
-    expires_after="2019-02-20">
-  <obsolete>
-    Removed as of 02/2019, VR DLAs are no longer supported.
-  </obsolete>
-  <owner>ymalik@chromium.org</owner>
-  <summary>
-    Whether we're auto-presenting the first time we enter WebVR mode.
-  </summary>
-</histogram>
-
-<histogram name="VRDisplayPresentResult" enum="VRPresentationResult"
-    expires_after="2020-07-01">
-  <obsolete>
-    As of 5/18/2020 this appears to no longer be logged.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    The result of calls to VRDisplay::requestPresent(). Reported twice per
-    requestPresent() call, once to record the call, and once to record the
-    result.
-  </summary>
-</histogram>
-
-<histogram name="VRRuntimeVersion" units="normalized version"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>The version of the runtime being used for VR.</summary>
-</histogram>
-
-<histogram name="VRSessionNavigationCount" units="units"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 02/2020
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Count of navigations while in a VR session. Logged when a new disjoint
-    session has begun, or when the session has ended in a non-continuable way.
-  </summary>
-</histogram>
-
-<histogram name="VRSessionTimeFromDLA" units="ms" expires_after="2019-02-20">
-  <obsolete>
-    Removed as of 02/2019, VR DLAs are no longer supported.
-  </obsolete>
-  <owner>ymalik@chromium.org</owner>
-  <summary>
-    The duration of a single VR session initiated via a deep-linked WebVR app.
-    Logged when a new disjoint session has begun, or when the session has ended
-    in a non-continuable way.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.AcceptLegalDocuments" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's accept legal
-    document API call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.AuthenticateInstrument" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's authenticate
-    instrument API call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.GetFullWallet" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's get full wallet API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.GetWalletItems" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's get wallet items
-    API call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.SaveAddress" units="ms"
-    expires_after="2013-07-20">
-  <obsolete>
-    Removed as of 7/2013, replaced by Wallet.ApiCallDuration.SaveToWallet.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's save address API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.SaveInstrument" units="ms"
-    expires_after="2013-07-20">
-  <obsolete>
-    Removed as of 7/2013, replaced by Wallet.ApiCallDuration.SaveToWallet.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's save instrument API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.SaveInstrumentAndAddress" units="ms"
-    expires_after="2013-07-20">
-  <obsolete>
-    Removed as of 7/2013, replaced by Wallet.ApiCallDuration.SaveToWallet.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's save instument and
-    address API call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.SaveToWallet" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's save to wallet API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.SendStatus" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's send status API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.UnknownApiCall" units="ms"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's unknown API calls.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.UpdateAddress" units="ms"
-    expires_after="2013-07-20">
-  <obsolete>
-    Removed as of 7/2013, replaced by Wallet.ApiCallDuration.SaveToWallet.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's update address API
-    call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ApiCallDuration.UpdateInstrument" units="ms"
-    expires_after="2013-07-20">
-  <obsolete>
-    Removed as of 7/2013, replaced by Wallet.ApiCallDuration.SaveToWallet.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Measures the time taken by Google Online Wallet server's update instument
-    API call.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.MalformedResponse" enum="WalletApiCall"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>
-    Counts the number of times each Wallet API failed due to being unable to
-    parse the response.
-  </summary>
-</histogram>
-
-<histogram name="Wallet.ResponseCode" enum="HttpResponseCode"
-    expires_after="M85">
-  <obsolete>
-    requestAutocomplete was removed in M52.
-  </obsolete>
-  <owner>estade@chromium.org</owner>
-  <summary>HTTP response codes seen by Wallet client.</summary>
-</histogram>
-
-<histogram name="Web.CertVerifyAgreement" enum="WebCertVerifyAgreement"
-    expires_after="2016-08-15">
-  <obsolete>
-    Removed 08/2016 because CertVerifier is not used for web view cert
-    verification.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    [iOS] Reports certificate verification mismatch between SecTrust API and
-    CertVerifier. SecTrust API is used for making load/no-load decision and
-    CertVerifier is used for getting the reason of verification failure. It is
-    expected that mismatches will happen for those 2 approaches (e.g. SecTrust
-    API considers cert as good, but CertVerifier considers same cert as bad).
-    This metric helps to understand how common mismatches are.
-  </summary>
-</histogram>
-
-<histogram name="Web.CurrentURLEqualsLastCommittedURL" enum="BooleanEqual"
-    expires_after="2017-09-13">
-  <obsolete>
-    Removed as of 9/2013, replaced by
-    Web.CurrentOriginEqualsLastCommittedOrigin.
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <summary>
-    [iOS] Reports URL matches between the return value from the WebState's
-    GetLastCommittedURL and GetCurrentURL methods. It is expected the values
-    will be equal to confirm that GetCurrentURL can now be replaced with
-    GetLastCommittedURL. This will be called each time WebStateImpl::
-    GetCurrentURL(URLVerificationTrustLevel* trust_level) is called, which is an
-    old method of obtaining the url and trust level. The trust level was only
-    relevant with UIWebView, so this method is only called from code which has
-    not yet been updated since UIWebView was removed.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.AvailableSpace.Success" units="MB"
-    expires_after="2017-10-27">
-  <obsolete>
-    Removed 2017-09. As of M64, this is no longer recorded.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>ranj@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the available space that can be used when installing a WebAPK from
-    Google Play succeeds. The space recorded is the available space beyond the
-    system's minimum free space threshold, with a range between -1000 and 1000
-    MB. Negative values mean that there is less free space available than the
-    system's minimum, by the given amount.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.AvailableSpaceAfterFreeUpAll.Fail" units="MB"
-    expires_after="2018-07-11">
-  <obsolete>
-    Removed in Chrome M69.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the available space that can be used when installing a WebAPK from
-    Google Play fails after freeing up cache and unimportant storage. The space
-    recorded is the available space beyond the system's minimum free space
-    threshold, with a range between -1000 and 1000 MB. Negative values mean that
-    there is less free space available than the system's minimum, by the given
-    amount.
-  </summary>
-</histogram>
-
-<histogram
-    name="WebApk.Install.AvailableSpaceAfterFreeUpUnimportantStorage.Fail"
-    units="MB" expires_after="2020-02-01">
-  <obsolete>
-    Removed in Chrome M69.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>ranj@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the available space that can be used when installing a WebAPK from
-    Google Play fails after freeing up unimportant storage. The space recorded
-    is the available space beyond the system's minimum free space threshold,
-    with a range between -1000 and 1000 MB. Negative values mean that there is
-    less free space available than the system's minimum, by the given amount.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.ChromeCacheSize.Fail" units="MB"
-    expires_after="M82">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the Chrome cache size when installing a WebAPK from Google Play
-    fails, with a range between 0 and 1000, rounded to the nearest 10MB.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.ChromeUnimportantStorage.Fail" units="MB"
-    expires_after="2018-07-11">
-  <obsolete>
-    Removed in Chrome M69.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>ranj@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the Chrome unimportant storage size when installing a WebAPK from
-    Google Play fails, with a range between 0 and 1000, rounded to the nearest
-    10MB.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.GooglePlayBindDuration" units="ms"
-    expires_after="2018-07-11">
-  <obsolete>
-    Removed in Chrome M69.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the amount of time that it takes to bind to the play install service
-    for WebAPK installs.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.GooglePlayInstallState"
-    enum="WebApkGooglePlayInstallState" expires_after="2017-07-11">
-  <obsolete>
-    Deleted in M61.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    On web app and WebAPK installation, records whether a WebAPK could be
-    installed via the Google Play flow. If not, records why the WebAPK could not
-    be installed via the Google Play flow (and a web app was added to the
-    homescreen instead). Warning: This metric is recorded whenever a site is
-    added to the homescreeen as a web app, not just for sites with a WebAPK
-    compatible Web Manifest.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.InfoBarShown" enum="WebApkInstallInfoBarShown"
-    expires_after="2017-08-21">
-  <obsolete>
-    Removed 2017-08. As of M62, this is no longer recorded.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    WebAPKs are PWAs wrapped in an Android apk, installed from an app banner or
-    the add to homescreen menu item. This stat tracks whether the installation
-    is triggered by an app banner or by the add to homescreen menu.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.InstallSource" enum="WebApkInstallSource"
-    expires_after="2018-03-20">
-  <obsolete>
-    No longer recorded as of M65.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    WebAPKs are PWAs wrapped in an Android apk, installed from an app banner or
-    the add to homescreen menu item. If the installation is via an app banner,
-    user could either accept to install or dismiss the infobar; while via the
-    add to homescreen menu, the installation will start automatically. This stat
-    tracks the ways that user accepts to install a WebAPK.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.SpaceStatus" enum="WebApkInstallSpaceStatus"
-    expires_after="M81">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Whether there is enough space to install a WebAPK. Recorded on each attempt
-    to install a WebAPK.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Install.UserAction" enum="WebApkUserAction"
-    expires_after="2017-08-21">
-  <obsolete>
-    Removed 2017-08. As of M62, this is no longer recorded.
-  </obsolete>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>
-    src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
-  </owner>
-  <summary>
-    WebAPKs are PWAs wrapped in an Android apk, installed from an app banner or
-    the add to homescreen menu item. If the user clicks the add to homescreen
-    menu, and a WebAPK has been installed before, an infobar with an open button
-    will show. The open button will also show on the infobar after a successful
-    installation. This stat tracks whether user clicks the open button on the
-    infobar or dismiss it.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.LaunchInterval" units="ms" expires_after="2018-01-24">
-  <obsolete>
-    Removed 2018-01. Replaced by WebApk.LaunchInterval2
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the amount of time since the user last launched the WebAPK from the
-    homescreen. Not recorded on first launch.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.LaunchInterval2" units="minutes" expires_after="M81">
-  <obsolete>
-    Removed 2020-01.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the amount of time since the user last launched the WebAPK from the
-    homescreen. Not recorded on first launch.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Navigation.ChildTab.InScope" enum="BooleanInScope"
-    expires_after="2020-10-04">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>peconn@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <summary>
-    Recorded each time that a child tab - e.g. a tab opened via window.open() -
-    is navigated. Records whether the navigation is within the scope of the
-    WebAPK's Web Manifest.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.OpenFromMenu" enum="WebApkOpenResult"
-    expires_after="2018-07-11">
-  <obsolete>
-    Removed in Chrome M69.
-  </obsolete>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>
-    src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
-  </owner>
-  <summary>
-    When a user visits a PWA for which they have a WebAPK installed, the menu
-    item changes from 'Add to homescreen' to 'Open WebAPK'. This stat tracks
-    whether the opening of the WebAPK is successful when this menu item is
-    clicked.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Permission.ChromePermissionDenied"
-    enum="WebApkPermissionType" expires_after="2017-12-05">
-  <obsolete>
-    Removed 2017-11. This UMA logs extra requests. Replaced by
-    ChromePermissionDenied2.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>ranj@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The number of Android runtime permission requests that are denied for the
-    WebAPK because Chrome does not have access to that permission.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Permission.ChromePermissionDenied2"
-    enum="WebApkPermissionType" expires_after="M85">
-  <obsolete>
-    Removed 2020-03.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The number of Android runtime permission requests that are denied for the
-    WebAPK because Chrome does not have access to that permission.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Permission.ChromeWithoutPermission"
-    enum="WebApkPermissionType" expires_after="M81">
-  <obsolete>
-    Removed 2020-03.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the amount of requests of Android runtime permissions which haven't
-    been granted to Chrome when Chrome is running in WebAPK runtime.
-  </summary>
-</histogram>
-
-<histogram name="WebApk.Session.TotalDuration" units="ms"
-    expires_after="2018-08-29">
-  <obsolete>
-    Removed 2018-08 in favour of WebApk.Session.TotalDuration2.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The length of a WebAPK session (launch/foregrounding to backgrounding) in
-    milliseconds.
-  </summary>
-</histogram>
-
-<histogram base="true" name="WebApk.ShellApkVersion" units="units"
-    expires_after="2018-08-29">
-  <obsolete>
-    Removed 2018-08 in favour of WebApk.ShellApkVersion2.
-  </obsolete>
-  <owner>hanxi@chromium.org</owner>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records WebAPK &quot;Shell APK version&quot; when the WebAPK is launched.
-    The &quot;Shell APK version&quot; is documented in shell_apk_version.gni
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Engagement.EngagementType"
-    enum="SiteEngagementServiceEngagementType" expires_after="2019-03-07">
-  <obsolete>
-    Removed 3/2019 because only counts PWAs. Superseded by the WebApp.Engagement
-    histogram with suffixes.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>mgiuca@chromium.org</owner>
-  <summary>
-    The type of engagement (navigation, user input, etc.) which led to an
-    accumulation in site engagement within a PWA app window. Should be collected
-    for a subset of SiteEngagementService.EngagementType, which is triggered for
-    all browsing contexts. Recorded at the time of engagement accumulation
-    (e.g., when mouse is clicked).
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Install.DisplayMode" enum="WebAppDisplayMode"
-    expires_after="M87">
-  <obsolete>
-    Removed 2019-11 and replaced by Webapp.Install.DisplayMode2, which correctly
-    records manifest display modes on desktop.
-  </obsolete>
-  <owner>peter@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Records the display mode (as defined in the Web App Manifest spec) at the
-    install time of a WebApp (including WebApks).
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Install.InstallSource" enum="WebAppInstallSource"
-    expires_after="2018-01-18">
-  <obsolete>
-    Removed 2018-01 in favour of Webapp.Install.InstallEvent.
-  </obsolete>
-  <owner>mcgreevy@chromium.org</owner>
-  <summary>
-    Records the mechanism by which a web app installation was triggered,
-    regardless of whether the installation was successful.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.InstallabilityCheckStatus.AddToHomescreenTimeout"
-    enum="AddToHomescreenTimeoutStatus" expires_after="M77">
-  <obsolete>
-    Expired in M77.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    Records whether or not the check that a site is or isn't a Progressive Web
-    App (PWA) completes before the add to homescreen dialog on Android forcibly
-    times out and falls back to generating an icon.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.InstallabilityCheckStatus.MenuItemAddToHomescreen"
-    enum="InstallabilityCheckStatus" expires_after="M80">
-  <obsolete>
-    Expired in M77.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    Records whether or not the check that a site is or isn't a Progressive Web
-    App (PWA) has completed when the user taps the add to homescreen menu item
-    on Android.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.InstallabilityCheckStatus.MenuOpen"
-    enum="InstallabilityCheckStatus" expires_after="M80">
-  <obsolete>
-    Expired in M77.
-  </obsolete>
-  <owner>dominickn@chromium.org</owner>
-  <summary>
-    Records whether or not the check that a site is or isn't a Progressive Web
-    App (PWA) has completed when the user opens the menu on Android.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.InstallDuration.System" units="ms"
-    expires_after="2021-03-07">
-  <obsolete>
-    Replaced by Webapp.SystemApps.FreshInstallDuration in 09/2020, issue
-    https://crbug.com/1129275.
-  </obsolete>
-  <owner>calamity@chromium.org</owner>
-  <owner>ortuno@chromium.org</owner>
-  <summary>
-    Records the number of seconds taken to install system web apps, from when we
-    dispatch a call to install them, until we get all the installation results.
-    Recorded in milliseconds, from 1 millisecond to 3 minutes.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.BackgroundColor" enum="SplashColorStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in Issue http://crbug.com/1716136. Information no longer
-    needed or recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Records the status of the splashscreen's background color (default or
-    custom).
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.Duration" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in Issue http://crbug.com/1716136. Information no longer
-    needed or recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>Records the time during which the splashscreen was visible.</summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.Hides" enum="SplashHidesReason"
-    expires_after="M80">
-  <obsolete>
-    Removed 2020-04.
-  </obsolete>
-  <owner>pkotwicz@chromium.org</owner>
-  <owner>hartmanng@chromium.org</owner>
-  <summary>Records the signal that was used to hide the splashscreen.</summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.Icon.Size" units="dp" expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in Issue http://crbug.com/1716136. Information no longer
-    needed or recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Records the size of the icon used to construct the splashscreen in device
-    pixels (ie. real size divided by device pixel density). This is only
-    recording one dimension, the icon being square.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.Icon.Type" enum="SplashIconType"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in Issue http://crbug.com/1716136. Information no longer
-    needed or recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Records the origin of the icon used to construct the splashscreen.
-  </summary>
-</histogram>
-
-<histogram name="Webapp.Splashscreen.ThemeColor" enum="SplashColorStatus"
-    expires_after="M77">
-  <obsolete>
-    Removed 07/2019 in Issue http://crbug.com/1716136. Information no longer
-    needed or recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Records the status of the splashscreen's theme color (default or custom).
-  </summary>
-</histogram>
-
-<histogram name="Webapp.SyncInitiatedFallbackInstallResult"
-    enum="WebAppInstallResultCode" expires_after="2022-01-01">
-  <obsolete>
-    Removed 08/2020. Information no longer recorded.
-  </obsolete>
-  <owner>alancutter@chromium.org</owner>
-  <summary>
-    Records installation result code for sync initiated fallback installs in the
-    new USS-based web applications system.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.AudioBuffer.SampleRate" units="Hz"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SampleRate384kHz in Issue 644683 on 2016/10 due to higher
-    supported sample rates.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The sample rate (in Hz) requested by createBuffer(). Recorded for every call
-    to createBuffer(). Probably many (tens or hundreds) per page.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.AudioBuffer.SampleRateRatio" units="units"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SampleRateRatio384kHz in Issue 644683 on 2016/10 due to higher
-    supported sample rates.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The ratio of the buffer sample rate from createBuffer() to the context
-    sample rate. This indicates if the buffer needs to be resampled. Recorded
-    for every call to createBuffer(). Probably many (tens or hundreds) per page.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.AudioParam.ValueSetterConflictCount" units="units"
-    expires_after="2018-02-08">
-  <obsolete>
-    Removed 02/2018 in Issue 764396. Information no longer needed or recorded.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The number of times the AudioParam value setter was called that also
-    conflicts with an ongoing AudioParam automation. Updated when the realtime
-    AudioContext is closed.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.AudioParam.ValueSetterConflictPercentage"
-    units="units" expires_after="2018-02-08">
-  <obsolete>
-    Removed 02/2018 in Issue 764396. Information no longer needed or recorded.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The percentage of number of calls to an AudioParam value setter that
-    conflicts with an ongoing AudioParam automation to the total number of calls
-    to the value setter. Updated once when an AudioContext is closed.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.AudioParam.ValueSetterCount" units="units"
-    expires_after="2018-02-08">
-  <obsolete>
-    Removed 02/2018 in Issue 764396. Information no longer needed or recorded.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The number of times the AudioParam value setter was called per tab. Updated
-    when the realtime AudioContext is closed.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.BiquadFilter.Q.Highpass" units="units"
-    expires_after="2017-10-16">
-  <obsolete>
-    Removed in Issue 774526 on 2017/10; statistics aren't needed anymore.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The Q value (in 0.25 dB steps) used for a highpass BiquadFilter. Recorded
-    each time the value is set for a highpass filter via the .value setter or
-    the automation methods linearRampToValueAtTime, exponentialValueAtTime, and
-    setValueAtTime.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.BiquadFilter.Q.Lowpass" units="units"
-    expires_after="2017-10-16">
-  <obsolete>
-    Removed in Issue 774526 on 2017/10; statistics aren't needed anymore.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The Q value (in 0.25 dB steps) used for a lowpass BiquadFilter. Recorded
-    each time the value is set for a lowpass filter via the .value setter or the
-    automation methods linearRampToValueAtTime, exponentialValueAtTime, and
-    setValueAtTime.
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.OfflineAudioContext.SampleRate" units="Hz"
-    expires_after="2016-10-12">
-  <obsolete>
-    Replaced by SampleRate384kHz in Issue 644683 on 2016/10 due to higher
-    supported sample rates.
-  </obsolete>
-  <owner>rtoy@chromium.org</owner>
-  <owner>hongchan@chromium.org</owner>
-  <summary>
-    The sample rate (in Hz) specified for the offline audio context. Recorded
-    for every offline context created. Probably only a few per page, but could
-    be potentially much more (thousands).
-  </summary>
-</histogram>
-
-<histogram name="WebAudio.UserGesture" enum="UserGestureRequirement"
-    expires_after="2016-09-30">
-  <obsolete>
-    Removed 2016-09. As of M55, this is no longer recorded.
-  </obsolete>
-  <owner>mlamouri@chromium.org</owner>
-  <summary>
-    Records whether WebAudio had a user gesture requirement and whether it was
-    fulfilled.
-  </summary>
-</histogram>
-
-<histogram name="WebAuthentication.CableV1Event"
-    enum="WebAuthenticationCableV1Event" expires_after="2020-12-31">
-  <obsolete>
-    Superseded 02/2020 by WebAuthentication.CableV1DiscoveryEvent
-  </obsolete>
-  <owner>agl@chromium.org</owner>
-  <summary>
-    Records events that occur during the lifetime of a caBLE v1 getAssertion
-    operation so that any causes of drop-off can be identified.
-  </summary>
-</histogram>
-
-<histogram name="WebController.EmptyNavigationManagerCausedByStopLoading"
-    enum="Boolean" expires_after="2019-07-15">
-  <obsolete>
-    Removed on 07/2019.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    [iOS] Chrome for iOS crashes because NavigationManager does not have any
-    navigation items and visible navigation item is dereferenced
-    (crbug.com/565457). The assumption is that crash occurs if pending load was
-    stopped for a child window. This metric will prove or disprove that
-    assumption.
-  </summary>
-</histogram>
-
-<histogram
-    name="WebController.StartProvisionalNavigationExitedWithEmptyNavigationManager"
-    enum="BooleanHit" expires_after="M80">
-  <obsolete>
-    Removed 2017-02. This metric disproved the assumption mentioned in the
-    summary and it is no longer needed.
-  </obsolete>
-  <owner>eugenebut@chromium.org</owner>
-  <summary>
-    Chrome for iOS crashes in |didCommitNavigation:| if Navigation Manager is
-    empty. It's unclear how the app can get into this state and one assumption
-    is that didStartProvisionalNavigation: does not add a pending navigation.
-    This metric is logged when didStartProvisionalNavigation: fails to add a
-    pending item.
-  </summary>
-</histogram>
-
-<histogram name="WebController.WKWebViewHasCertForSecureConnection"
-    enum="BooleanHasCert" expires_after="2020-03-01">
-  <obsolete>
-    It is common for WKWebView to have certificateChain, which does not allow
-    constructing net::X509Certificate. Logging was removed on 2020-01-23.
-  </obsolete>
-  <owner>eugenebut@google.com</owner>
-  <summary>
-    Whether or not WKWebView has provided a valid -certificateChain when loaded
-    a page over a secure connection.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.Animation.CSSProperties" enum="MappedCSSProperties"
-    expires_after="2018-09-19">
-  <obsolete>
-    This has been superseded by Blink.UseCounter.CSSProperties which does not
-    count multiple times per page load. See https://crbug.com/458925.
-  </obsolete>
-  <owner>ajuma@chromium.org</owner>
-  <summary>
-    Counts the number of times each CSS property is animated. There is no limit
-    on the number of times each property is counted per page view -- a property
-    that is animated multiple times during a single page view is counted each
-    time it animates.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.CanvasContextUsage" enum="CanvasContextUsage"
-    expires_after="2018-10-23">
-  <obsolete>
-    Removed 10/2018 with Blink.Canvas.IsComposited,
-    Blink.Canvas.ResourceProviderIsAccelerated,
-    Blink.Canvas.ResourceProviderType and Blink.Canvas.2DLayerBridgeIsDeferred
-  </obsolete>
-  <owner>zmin@chromium.org</owner>
-  <owner>fserb@chromium.org</owner>
-  <summary>
-    The usage of Canvas 2D Context API. Logged when the particular API is used.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.FeatureObserver" enum="FeatureObserver"
-    expires_after="2017-11-01">
-  <obsolete>
-    As of M57 this has been superseded by Blink.UseCounter.Features which fixes
-    a number of issues. See https://crbug.com/676837.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-  <summary>
-    Count of how many page loads use various features. The PageVisits bucket is
-    incremented for each page load, and the other buckets incremented at most
-    once per PageVisit via the WebCore::UseCounter class.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.FeatureObserver.CSSProperties"
-    enum="MappedCSSProperties" expires_after="2017-11-01">
-  <obsolete>
-    As of M57 this has been superseded by Blink.UseCounter.CSSProperties which
-    fixes a number of issues. See https://crbug.com/676837.
-  </obsolete>
-  <owner>mikelawther@chromium.org</owner>
-  <summary>
-    Records usage of CSS properties used on a page, either statically or
-    dynamically, from the time the page is initialised to when it is closed or
-    navigated away from. Each property is counted at most once per page per
-    view.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.FindInPage.ScopingTime" units="units"
-    expires_after="M77">
-  <obsolete>
-    Removed in M77 because we're not tracking this anymore.
-  </obsolete>
-  <owner>rakina@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Records how much time it takes for find-in-page scoping over the idle task
-    deadline.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.Framebust" enum="FramebustPermissions"
-    expires_after="2018-09-26">
-  <obsolete>
-    Removed in September 2018 for a version that also tracks if the frame is an
-    ad frame.
-  </obsolete>
-  <owner>japhet@chromium.org</owner>
-  <summary>
-    Records instances of child frames navigating the top frame. Includes whether
-    or not the navigation would have been permitted if not for our special case
-    for 'framebusting', the practice of ensuring a given document is never
-    displayed in a frame.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.Framebust2" enum="FramebustPermissionsPlusAds"
-    expires_after="2019-03-27">
-  <obsolete>
-    Removed in March 2019.
-  </obsolete>
-  <owner>japhet@chromium.org</owner>
-  <owner>jkarlin@chromium.org</owner>
-  <summary>
-    Records instances of child frames navigating the top frame. Includes whether
-    or not the navigation would have been permitted if not for our special case
-    for 'framebusting', the practice of ensuring a given document is never
-    displayed in a frame. It also includes whether the frame that initiated the
-    navigation was an ad frame or not.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.BackingStore.InternalError"
-    enum="IDBLevelDBBackingStoreInternalErrorType" expires_after="2013-04-11">
-  <obsolete>
-    As of chrome 26, use {Consistency, Read, Write}Error instead.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Count of internal IndexedDB errors (data corruption, I/O errors, etc)
-    encountered.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.FrontEndAPICalls"
-    enum="IndexedDatabaseMethods" expires_after="2018-07-23">
-  <obsolete>
-    Removed as of July 2018.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Count total number of front end API calls of IndexedDB methods.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDB.FreeDiskSpaceFailure"
-    enum="LevelDBErrorCount" expires_after="2019-01-08">
-  <obsolete>
-    Removed 1/19. Metric never actually worked, as -1 / 1024 yields 0.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Count of how many times LevelDBDatabase got an error trying to check free
-    disk space.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDB.OpenFailureFreeDiskSpace" units="Kb"
-    expires_after="2019-01-08">
-  <obsolete>
-    Removed 1/19. Use Quota.AvailableDiskSpace instead.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Amount of free disk space on the partition/volume/etc where LevelDB failed
-    to open.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDB.OpenSuccessFreeDiskSpace" units="Kb"
-    expires_after="2019-01-08">
-  <obsolete>
-    Removed 1/19. Use Quota.AvailableDiskSpace instead.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Amount of free disk space on the partition/volume/etc where LevelDB was
-    successfully opened.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDB.PutTime" units="ms"
-    expires_after="M83">
-  <obsolete>
-    Removed in M84.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <owner>chrome-owp-storage@google.com</owner>
-  <summary>
-    The time that it takes to write the data IndexedDB to the LevelDB backing
-    store for a put operation.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDB.Transaction.CommitTime" units="ms"
-    expires_after="2018-11-28">
-  <obsolete>
-    Removed in M72.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The time that it takes to commit an IndexedDB transaction to its LevelDB
-    backing store.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBOpenErrors.Errno"
-    enum="PopularOSErrno" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBOpenErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Errno errors encountered by a single LevelDBEnv method when opening an
-    IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBOpenErrors.PFE"
-    enum="PlatformFileError" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBOpenErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    PlatformFileErrors encountered by a single LevelDBEnv method when opening an
-    IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBReadErrors.Errno"
-    enum="PopularOSErrno" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBReadErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Errno errors encountered by a single LevelDBEnv method when reading an
-    IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBReadErrors.PFE"
-    enum="PlatformFileError" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBReadErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    PlatformFileErrors encountered by a single LevelDBEnv method when opening an
-    IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBWriteErrors.Errno"
-    enum="PopularOSErrno" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBWriteErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    Errno errors encountered by a single LevelDBEnv method when writing to an
-    IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.LevelDBWriteErrors.PFE"
-    enum="PlatformFileError" expires_after="2015-03-24">
-  <obsolete>
-    Removed 2015-05. As of M43 use WebCore.IndexedDB.LevelDBWriteErrors.BFE.
-  </obsolete>
-  <owner>dgrogan@chromium.org</owner>
-  <summary>
-    PlatformFileErrors encountered by a single LevelDBEnv method when writing to
-    an IndexedDB instance.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.ObjectStore.IndexEntry.KeyType"
-    enum="IDBKeyType" expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    The type of key (number, string, etc.) used for an index entry for a record
-    being newly stored or updated in an Indexed DB object store. For array keys,
-    the types of sub-keys are not recorded.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.ObjectStore.Record.KeyType"
-    enum="IDBKeyType" expires_after="M87">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    The type of key (number, string, etc.) used for a record being newly stored
-    or updated in an Indexed DB object store. For array keys, the types of
-    sub-keys are not recorded.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.OpenTime.Blocked" units="ms"
-    expires_after="2018-11-16">
-  <obsolete>
-    Removed 2018-11. No longer needed.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The delay between the receipt of the request to open an IndexedDB database
-    and the firing of the blocked event.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.OpenTime.Error" units="ms"
-    expires_after="2018-11-16">
-  <obsolete>
-    Removed 2018-11. No longer needed.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The delay between the receipt of the request to open an IndexedDB database
-    and the firing of the error event.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.OpenTime.Success" units="ms"
-    expires_after="2018-11-16">
-  <obsolete>
-    Removed 2018-11. No longer needed.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The delay between the receipt of the request to open an IndexedDB database
-    and the firing of the success event.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.OpenTime.UpgradeNeeded" units="ms"
-    expires_after="2018-11-16">
-  <obsolete>
-    Removed 2018-11. No longer needed.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The delay between the receipt of the request to open an IndexedDB database
-    and the firing of the upgradeneeded event.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.PutValueSize" units="KB"
-    expires_after="2017-06-09">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.PutValueSize2 on 6/2017
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The size of the IndexedDB value used in an IndexedDB object store 'put'
-    operation. Recorded for every 'put' operation.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Schema.Index.KeyPathType"
-    enum="IDBKeyPathType" expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    Records the 'keyPath' type (none, string, or array) during IDBObjectStore's
-    createIndex operation. See http://www.w3.org/TR/IndexedDB/
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Schema.Index.MultiEntry" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    Records the 'multiEntry' flag value during IDBObjectStore's createIndex
-    operation. See http://www.w3.org/TR/IndexedDB/
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Schema.Index.Unique" enum="Boolean"
-    expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    Records the 'unique' flag value during IDBObjectStore's createIndex
-    operation. See http://www.w3.org/TR/IndexedDB/
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement"
-    enum="Boolean" expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    Records the 'autoIncrement' flag value during IDBDatabase's
-    createObjectStore operation. See http://www.w3.org/TR/IndexedDB/
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Schema.ObjectStore.KeyPathType"
-    enum="IDBKeyPathType" expires_after="M77">
-  <obsolete>
-    Removed August 2019. Was added to measure use of features which not all
-    actively developed browser engines supported. No longer relevant.
-  </obsolete>
-  <owner>jsbell@chromium.org</owner>
-  <summary>
-    Records the 'keyPath' type (none, string, or array) during IDBDatabase's
-    createObjectStore operation. See http://www.w3.org/TR/IndexedDB/
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.TombstoneSweeper.NumTombstones"
-    units="Index Tombstones" expires_after="2019-07-02">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.TombstoneSweeper.NumDeletedTombstones in
-    07/2017.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the number of tombstones encountered by the IndexedDB Tombstone
-    Sweeper. Recorded on the browser side (back end) when the sweeper has
-    completed scanning and it is in 'statistics' mode. See
-    https://goo.gl/coKwA7.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.TombstoneSweeper.StatsTotalTime.Complete"
-    units="ms" expires_after="2017-07-02">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.TombstoneSweeper.DeletionTotalTime.Complete
-    in 07/2017.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the time it takes for the IndexedDB Tombstone Sweeper to fully scan
-    the indexes. Recorded on the browser side (back end) when the sweeper has
-    completed scanning all indexes (so partial scans are not recorded) and it is
-    in 'statistics' mode. See https://goo.gl/coKwA7.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.TombstoneSweeper.TombstonesSize"
-    units="bytes" expires_after="2017-07-02">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.TombstoneSweeper.DeletedTombstonesSize in
-    07/2017.
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    Records the total size of tombstones encountered by the IndexedDB Tombstone
-    Sweeper. Recorded on the browser side (back end) when the sweeper has
-    completed scanning and it is in the 'statistics' mode. See
-    https://goo.gl/coKwA7.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit"
-    units="KB" expires_after="2017-06-09">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit2 on 6/2017
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The total temporary size of an IndexedDB ReadOnly Transaction. Since this is
-    a readonly transaction, the size should only be &gt;0 when the transaction
-    is removing tombstone index keys. Recorded on transaction commit.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit"
-    units="KB" expires_after="2017-06-09">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit2 on
-    6/2017
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The total temporary size of an IndexedDB ReadWrite Transaction. This is the
-    memory that is temporarily stored before writing to disk. Recorded on
-    transaction commit.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit"
-    units="KB" expires_after="2017-06-09">
-  <obsolete>
-    Replaced with WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit2 on
-    6/2017
-  </obsolete>
-  <owner>dmurph@chromium.org</owner>
-  <summary>
-    The total temporary size of an IndexedDB VersionChange Transaction. This is
-    the memory that is temporarily stored before writing to disk. Version change
-    transactions happen when creating a database or updating a current database
-    schema. Recorded on transaction commit.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.PreloadDelayMs" units="ms" expires_after="2017-10-05">
-  <obsolete>
-    Removed, preloads are issued on the main thread now, so this is less useful.
-  </obsolete>
-  <owner>csharrison@chromium.org</owner>
-  <summary>
-    The delay between when the preload scanner discovers a resource on the
-    parser thread and when the preload request is issued on the main thread.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ResourceFetcher.HitCount" units="units"
-    expires_after="2017-04-24">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Number of dead resources found in the memory cache over the lifetime of the
-    ResourceFetcher.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ResourceFetcher.LoadCount" units="units"
-    expires_after="2017-04-24">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Number of resources that needed to be loaded by the ResourceFetcher over its
-    lifetime.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ResourceFetcher.ResourceTypeUponCacheHit"
-    enum="ResourceType" expires_after="2016-07-17">
-  <obsolete>
-    This metric has been not recorded at least since 2016/01. The displayed enum
-    labels might be unreliable because C++ enum values of blink::Resource::Type
-    have been changed over time.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    The type of the resource (e.g. image, script...) upon a cache hit.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ResourceFetcher.RevalidateCount" units="units"
-    expires_after="2017-04-24">
-  <obsolete>
-    Removed April 2017.
-  </obsolete>
-  <owner>clamy@chromium.org</owner>
-  <summary>
-    Number of dead resources that needed to be revalidated by the
-    ResourceFetcher over its lifetime.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleCallbackDeadline"
-    units="ms" expires_after="2017-12-07">
-  <obsolete>
-    Removed November 2017.
-  </obsolete>
-  <owner>rmcilroy@chromium.org</owner>
-  <summary>
-    The amount of time allotted to a requestIdleCallback callback, i.e., the
-    difference between the time when it is called and when its deadline expires.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleCallbackOverrun"
-    units="ms" expires_after="M85">
-  <obsolete>
-    Removed December 2017.
-  </obsolete>
-  <owner>rmcilroy@chromium.org</owner>
-  <summary>
-    The amount of time by which a requestIdleCallback callback overran its
-    deadline. Callbacks which don't overrun their deadline will report an
-    overrun of 0.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleTaskCallbackType"
-    enum="IdleDeadlineCallbackType" expires_after="2020-10-11">
-  <obsolete>
-    Removed April 2020.
-  </obsolete>
-  <owner>shaseley@chromium.org</owner>
-  <summary>The callback type for every idle task that was run.</summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleTaskQueueingTime"
-    units="ms" expires_after="2020-10-11">
-  <obsolete>
-    Removed April 2020.
-  </obsolete>
-  <owner>shaseley@chromium.org</owner>
-  <summary>
-    The amount of time an idle task was queued before running. This metric is
-    only recorded for idle tasks that run during idle periods, not for those
-    that run as a result of an expired timeout.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleTaskTimeout" units="ms"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed April 2020.
-  </obsolete>
-  <owner>shaseley@chromium.org</owner>
-  <summary>
-    The timeout value specified for each idle task that was run, regardless of
-    whether or not it was run due to its timeout expiring. A value of 0
-    indicates that no timeout was specified.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.ScriptedIdleTaskController.IdleTaskTimeoutExceeded"
-    units="ms" expires_after="2020-04-01">
-  <obsolete>
-    Removed April 2020.
-  </obsolete>
-  <owner>shaseley@chromium.org</owner>
-  <summary>
-    The timeout value for idle tasks that were run because their timeout
-    expired.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.Scripts.ParsingBlocking.AlreadyLoaded"
-    enum="BooleanLoaded" expires_after="2015-03-24">
-  <obsolete>
-    Removed as this data was needed for streaming investigations, no longer
-    needed.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>
-    Whether a parsing blocking script was already preloaded from the net or the
-    cache by the time it was needed.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.Scripts.ParsingBlocking.TimeBetweenLoadedAndCompiled"
-    units="ms" expires_after="2015-03-24">
-  <obsolete>
-    Removed as this data was needed for streaming investigations, no longer
-    needed.
-  </obsolete>
-  <owner>marja@chromium.org</owner>
-  <summary>
-    Time between the events &quot;script is loaded&quot; and &quot;script is
-    compiled&quot; for parsing blocking scripts.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.SpellChecker.RequestInterval" units="ms"
-    expires_after="M85">
-  <obsolete>
-    Removed in M85 as we haven't observed any related performance alerts, and no
-    team is actively monitoring it.
-  </obsolete>
-  <owner>xiaochengh@chromium.org</owner>
-  <summary>
-    The amount of time between consecutive spellcheck requests made by Blink,
-    with the exception that requests made simultaneously checking different
-    parts of the same editing host count as only one request.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.UseCounter_TEST.CSSProperties"
-    enum="MappedCSSProperties" expires_after="2017-01-06">
-  <obsolete>
-    Temporary histogram replaced by Blink.UseCounter.CSSProperties.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-</histogram>
-
-<histogram name="WebCore.UseCounter_TEST.Features" enum="FeatureObserver"
-    expires_after="2017-01-06">
-  <obsolete>
-    Temporary histogram replaced by Blink.UseCounter.Features.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-</histogram>
-
-<histogram name="WebCore.UseCounter_TEST.SVGImage.CSSProperties"
-    enum="MappedCSSProperties" expires_after="2017-01-06">
-  <obsolete>
-    Temporary histogram replaced by Blink.UseCounter.SVGImage.CSSProperties.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-</histogram>
-
-<histogram name="WebCore.UseCounter_TEST.SVGImage.Features"
-    enum="FeatureObserver" expires_after="2017-01-06">
-  <obsolete>
-    Temporary histogram replaced by Blink.UseCounter.SVGImage.Features.
-  </obsolete>
-  <owner>rbyers@chromium.org</owner>
-</histogram>
-
-<histogram name="WebCore.V8DOMWindowShell.createContext.IsolatedWorld"
-    units="ms" expires_after="2014-08-12">
-  <obsolete>
-    Removed 05/2013, we no longer have the code that uses this metric.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Duration of time taken to create a V8 Context for an isolated world.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.V8DOMWindowShell.createContext.MainWorld" units="ms"
-    expires_after="2014-08-12">
-  <obsolete>
-    Removed 05/2013, we no longer have the code that uses this metric.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Duration of time taken to create a V8 Context for the main world.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.BinaryTypeChangesAfterOpen" units="units"
-    expires_after="2017-06-12">
-  <obsolete>
-    Deprecate 2017-06, as we've collected enough data to discuss. (see issue
-    584616).
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count the number of changes to WebSocket.binaryType after the connection
-    opened, per connection. Assignments that match the existing binaryType are
-    not counted. This is recorded after WebSocket close, whether explicit or due
-    to error or navigation. It is not recorded if the render process is
-    destroyed before the WebSocket is closed.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.HandshakeResult"
-    enum="WebSocketHandshakeResult" expires_after="2017-06-02">
-  <obsolete>
-    Removed 2014-06 when we replaced the WebSocket implementation (see issue
-    226931).
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count the number of WebSocket handshake for each result. Use this histogram
-    as a baseline for investigating feature usage counters.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.MessageSize.Receive" units="bytes"
-    expires_after="2020-09-06">
-  <obsolete>
-    Removed as of 2020-09
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    The sizes of binary WebSocket messages received, broken down by type. One
-    entry per message. Clamped to 100 MB.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.MessageSize.Send" units="bytes"
-    expires_after="2021-02-28">
-  <obsolete>
-    Removed as of 2020-09
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    The sizes of binary WebSocket messages sent, broken down by type. One entry
-    per message. Clamped to 100 MB.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.PerMessageDeflateContextTakeOverMode"
-    enum="WebSocketPerMessageDeflateContextTakeOverMode"
-    expires_after="2017-06-02">
-  <obsolete>
-    Removed 2014-06 when we replaced the WebSocket implementation (see issue
-    226931).
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count the number of WebSockets that accepted permessage-deflate extension
-    for each context take over mode. Used by the old Blink-based WebSocket
-    implementation.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.WebSocket.ReceiveType" enum="WebSocketReceiveType"
-    expires_after="M82">
-  <obsolete>
-    Removed as of 2020-02.
-  </obsolete>
-  <owner>yhirano@chromium.org</owner>
-  <owner>ricea@chromium.org</owner>
-  <summary>
-    Count the number of messages for each message type and set binary type.
-  </summary>
-</histogram>
-
-<histogram name="WebCore.XHR.send.ArrayBufferOrView"
-    enum="XMLHttpRequestSendArrayBufferOrView" expires_after="2014-07-09">
-  <obsolete>
-    Removed as of 7/2014. This histogram was used to determine when it would be
-    ok to remove the deprecated XMLHttpRequest.send(ArrayBuffer) overload. The
-    support for ArrayBuffer was un-deprecated in the WHATWG spec for XHR, and
-    subsequently un-deprecated in Blink.
-  </obsolete>
-  <owner>costan@gmail.com</owner>
-  <summary>
-    Count the number of XHR.send() calls for each argument type to see when we
-    can deprecate the ArrayBuffer type support.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.CORSSuccess" enum="BooleanSuccess" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>bashi@chromium.org</owner>
-  <owner>kenjibaheux@chromium.org</owner>
-  <summary>The success or failure of web fonts CORS-enabled fetching.</summary>
-</histogram>
-
-<histogram name="WebFont.DecodeSpeed" units="KB/s" expires_after="M81">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Uncompressed font image size divided by the duration of time OTS takes to
-    decode the font image, in kilobytes per second.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.DiskCache.EntryAge.Evict" units="hours"
-    expires_after="M81">
-  <obsolete>
-    Removed 08/2019.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Recorded upon an eviction of a cache entry for a font in Google Fonts.
-    Records the age of the cache entry.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.DiskCache.EntryAge.Hit" units="hours"
-    expires_after="M81">
-  <obsolete>
-    Removed 08/2019.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Recorded upon a cache hit for a font in Google Fonts. Records the age of the
-    cache entry.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.DiskCache.ReuseCount.Evict" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed 08/2019.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    When a cache entry for a font in Google Fonts is evicted, records the reuse
-    count of the cache entry.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.DiskCache.ReuseCount.Hit" units="units"
-    expires_after="M81">
-  <obsolete>
-    Removed 08/2019.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Recorded upon a cache hit for a font in Google Fonts. Records the reuse
-    count of the cache entry.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.DiskCacheHit" enum="WebFontDiskCacheHit"
-    expires_after="M81">
-  <obsolete>
-    Removed 08/2019 in favor of WebFont.HttpCacheStatus.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    Whether the font was in the cache or not. &quot;Previously in the
-    cache&quot; means there was an evicted entry for the font in the cache.
-    Recorded upon a disk cache query for a font in Google Fonts.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.InterventionResult" enum="WebFontInterventionResult"
-    expires_after="2017-10-19">
-  <obsolete>
-    Removed 10/2017. Related field trial has finished rolling out.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>kenjibaheux@chromium.org</owner>
-  <summary>
-    For each WebFont load attempt, records whether User Agent Intervention was
-    triggered, and whether the request (would have) timed out or not. The
-    intervention takes adaptive behaviors to handle loading timeouts to improve
-    user experiences on slow networks.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.InterventionResult.MissedCache"
-    enum="WebFontInterventionResult" expires_after="2017-11-02">
-  <obsolete>
-    Removed 10/2017. Related field trial has finished rolling out.
-  </obsolete>
-  <owner>toyoshim@chromium.org</owner>
-  <owner>kenjibaheux@chromium.org</owner>
-  <summary>
-    Like InterventionResult, this records whether User Agent Intervention was
-    triggered, and whether the request (would have) timed out or not. But this
-    version records only when data actually comes from network, not from disk or
-    memory cache, and is not provided in a data URL format.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LayoutLatency" units="ms" expires_after="2013-08-22">
-  <obsolete>
-    Renamed to WebFont.StyleRecalcToDownloadLatency for clarity.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time from when the webfont was referenced by a calculated style for the
-    first time to the start of the font download.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.0.Under10KB" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.0.Under10KB.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time it takes for a webfont download to finish, for webfonts of under
-    10KB.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.1.10KBTo50KB" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.1.10KBTo50KB.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time it takes for a webfont download to finish, for webfonts of
-    10KB-50KB.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.2.50KBTo100KB" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.2.50KBTo100KB.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time it takes for a webfont download to finish, for webfonts of
-    50KB-100KB.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.3.100KBTo1MB" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.3.100KBTo1MB.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time it takes for a webfont download to finish, for webfonts of
-    100KB-1MB.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.4.Over1MB" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.4.Over1MB.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time it takes for a webfont download to finish, for webfonts of over
-    1MB.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.LoadTime.LoadError" units="ms"
-    expires_after="2013-08-08">
-  <obsolete>
-    Removed as of 8/2013, replaced by WebFont.DownloadTime.LoadError.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time taken for a webfont download that failed. Includes aborted
-    requests.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.PackageFormat" enum="WebFontPackageFormat"
-    expires_after="2020-08-10">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The packaging format of the font file (e.g. SFNT, WOFF ...) upon a webfont
-    load.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.Resource.StyleRecalcToDownloadLatency" units="ms"
-    expires_after="2014-07-18">
-  <obsolete>
-    Removed 11/2013. No longer tracked.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time from when the webfont was referenced by a calculated style for the
-    first time to the start of the font download. Recorded at most once for each
-    FontResource object (not recorded if the font is retrieved from the memory
-    cache).
-  </summary>
-</histogram>
-
-<histogram name="WebFont.Resource.UsageType" enum="WebFontUsageType"
-    expires_after="2014-07-18">
-  <obsolete>
-    Removed 11/2013. No longer tracked.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    For each webfont, this records (a) if the font was 'styled', i.e. referenced
-    by a calculated style for a RenderText before the font data was used, and
-    (b) if the font was actually used or not, i.e. the renderer requested the
-    font data or not. (A Font can be used without being styled, for example when
-    drawn by a Canvas 2D Context.) This is recorded upon a download request of a
-    webfont, or destruction of a FontResource object. Recorded at most once for
-    each FontResource object in the renderer's memory cahce.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.StyleRecalcToDownloadLatency" units="ms"
-    expires_after="2013-09-05">
-  <obsolete>
-    Removed as of 9/2013, replaced by
-    WebFont.Resource.StyleRecalcToDownloadLatency.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The time from when the webfont was referenced by a calculated style for the
-    first time to the start of the font download.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.UsageType" enum="WebFontUsageType"
-    expires_after="2013-09-05">
-  <obsolete>
-    Removed as of 9/2013, replaced by WebFont.Resource.UsageType.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    For each webfont, this records (a) if the font was 'styled', i.e. referenced
-    by a calculated style for a RenderText before the font data was used, and
-    (b) if the font was actually used or not, i.e. the renderer requested the
-    font data or not. (A Font can be used without being styled, for example when
-    drawn by a Canvas 2D Context.) This is recorded upon a download request of a
-    webfont, or destruction of a CSSFontFaceSource object. Recorded at most once
-    for each url() source of @font-face CSS rule.
-  </summary>
-</histogram>
-
-<histogram name="WebFont.WebFontsInPage" units="units" expires_after="M77">
-  <obsolete>
-    Removed June 2019.
-  </obsolete>
-  <owner>kenjibaheux@chromium.org</owner>
-  <owner>ksakamoto@chromium.org</owner>
-  <summary>
-    The number of webfonts used in a page. This is recorded when the first
-    layout is done, and so will not count webfonts dynamically loaded by
-    scripts.
-  </summary>
-</histogram>
-
-<histogram name="WebHistory.QueryWebAndAppActivity.State"
-    enum="QueryWebAndAppActivityState" expires_after="M83">
-  <obsolete>
-    Removed March 2020.
-  </obsolete>
-  <owner>msalama@chromium.org</owner>
-  <owner>chrome-signin-team@google.com</owner>
-  <summary>
-    Records the state of web and app activity everytime a request to query sWAA
-    is completed. The request is triggered when the user opens the history page,
-    sync setup settings page or clear browsing data dialog. Desktop only.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.AecDelayBasedQuality" enum="DelayBasedEchoQuality"
-    expires_after="M80">
-  <obsolete>
-    Removed 5/2019 in issue bugs.webrtc.org/10563 due to the reporting component
-    (AEC2) being deprecated.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    Captures if the estimated delay between rendered and captured audio is out
-    of bounds which can cause the Echo Cancellation to fail. This is logged
-    roughly once every 5 seconds. The values are logged in four buckets
-    reflecting how well the Echo Cancellation likely performs based on the
-    estimated delay.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.ApplicationMaxConsecutiveBytesDiscard" units="units"
-    expires_after="2014-12-28">
-  <obsolete>
-    Removed as of 12/2014, replaced by
-    WebRTC.ApplicationMaxConsecutiveBytesDiscard.v2.
-  </obsolete>
-  <owner>guoweis@chromium.org</owner>
-  <summary>
-    The maximum consecutive discarded bytes caused by not enough buffer
-    available in WebRTC's socket implementation. This happens when WebRTC
-    IpcPacketSocket's throttling mechanism kicks in.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.AecDelayAdjustmentMsAgnosticValue" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019 in issue bugs.webrtc.org/10563 due to the reporting component
-    (AEC2) being deprecated.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    The AEC in WebRTC will sometimes realign the far- and near-end signal
-    buffers to keep in sync with delay changes in the echo path. This metric
-    logs each such realignment, storing the delay change in ms, when the change
-    is triggered by a shift in the signal based delay estimation (a.k.a
-    delay-agnostic).
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.AecDelayAdjustmentMsSystemValue" units="ms"
-    expires_after="M80">
-  <obsolete>
-    Removed 4/2019 in issue bugs.webrtc.org/10563 due to the reporting component
-    (AEC2) being deprecated.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    The AEC in WebRTC will sometimes realign the far- and near-end signal
-    buffers to keep in sync with delay changes in the echo path. This metric
-    logs each such realignment, storing the delay change in ms, when the change
-    is triggered by a shift in system reported delay.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.AecSystemDelayJump" units="ms"
-    expires_after="2019-11-30">
-  <obsolete>
-    Removed 11/2019 due to old AEC system (AEC2) being removed.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    The AEC in WebRTC keeps a buffer to mimic the audio buffers in the lower
-    layers. This histogram logs a sudden positive jump in buffer size. Since we
-    detect jumps in the capture thread, only positive values are feasible. Note
-    that the difference in milliseconds is logged and not the actual AEC system
-    delay value. Sampled every time the AEC system delay changes more than 50
-    milliseconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.EchoCanceller.ComfortNoiseBand0"
-    units="dBFS (negated)" expires_after="M81">
-  <obsolete>
-    Removed in M81 as the metric is no longer used for analysis.
-  </obsolete>
-  <owner>peah@chromium.org</owner>
-  <summary>
-    This histogram logs the level of the comfort noise in the WebRTC echo
-    canceller in the lower 4 kHz. A new value is logged every 10 seconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.EchoCanceller.ComfortNoiseBand1"
-    units="dBFS (negated)" expires_after="M81">
-  <obsolete>
-    Removed in M81 as the metric is no longer used for analysis.
-  </obsolete>
-  <owner>peah@chromium.org</owner>
-  <summary>
-    This histogram logs the level of the comfort noise in the WebRTC echo
-    canceller between 4 and 8 kHz. A new value is logged every 10 seconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.EchoCanceller.SuppressorGainBand0"
-    units="dB (negated)" expires_after="2020-12-01">
-  <obsolete>
-    Removed in M81 as the metric is no longer used for analysis.
-  </obsolete>
-  <owner>peah@chromium.org</owner>
-  <summary>
-    This histogram logs the echo suppressor gain in the WebRTC echo canceller in
-    the lower 4 kHz. A new value is logged every 10 seconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.EchoCanceller.SuppressorGainBand1"
-    units="dB (negated)" expires_after="2020-12-01">
-  <obsolete>
-    Removed in M81 as the metric is no longer used for analysis.
-  </obsolete>
-  <owner>peah@chromium.org</owner>
-  <summary>
-    This histogram logs the echo suppressor gain in the WebRTC echo canceller
-    between 4 and 8 kHz. A new value is logged every 10 seconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.NumOfAecSystemDelayJumps" units="jumps"
-    expires_after="2019-11-30">
-  <obsolete>
-    Removed 11/2019 due to old AEC system (AEC2) being removed.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    Number of triggered WebRTC.Audio.AecSystemDelayJump during a call. This is
-    recorded when a WebRTC based call has ended. AecSystemDelayJump can be
-    triggered when, for example, the capture thread is stalled, which can harm
-    the AEC. NumOfAecSystemDelayJumps shows how often this occurs in general as
-    well as during a call.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.NumOfPlatformReportedStreamDelayJumps"
-    units="jumps" expires_after="2019-11-30">
-  <obsolete>
-    Removed 11/2019 due to old AEC system (AEC2) being removed.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    Number of triggered WebRTC.Audio.PlatformReportedStreamDelayJump during a
-    call. This is recorded when a WebRTC based call has ended.
-    PlatformReportedStreamDelayJump can be triggered when, for example, the
-    capture thread is stalled, which can harm the AEC.
-    NumOfPlatformReportedStreamDelayJumps shows how often this occurs in general
-    as well as during a call.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Audio.PlatformReportedStreamDelayJump" units="ms"
-    expires_after="2019-11-30">
-  <obsolete>
-    Removed 11/2019 due to old AEC system (AEC2) being removed.
-  </obsolete>
-  <owner>hlundin@chromium.org</owner>
-  <summary>
-    The difference in stream delay reported to WebRTC by Chrome. Since we detect
-    jumps in the capture thread, only positive values are feasible. Note that
-    the difference in milliseconds is logged and not the actual stream delay
-    value. Sampled every time the stream delay changes more than 50
-    milliseconds.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.AudioCaptureTime" units="ms" expires_after="2014-02-26">
-  <obsolete>
-    Removed from code 2014/2/25.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Duration in milliseconds of WebRTC audio capture session.</summary>
-</histogram>
-
-<histogram name="WebRTC.AudioInputFramesPerBuffer" enum="AudioFramesPerBuffer"
-    expires_after="2014-02-26">
-  <obsolete>
-    No longer exists in the code as of 2014/2/25.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Size of WebRTC audio input buffers (in audio frames).</summary>
-</histogram>
-
-<histogram name="WebRTC.AudioInputFramesPerBufferUnexpected"
-    units="audio frames" expires_after="2014-02-26">
-  <obsolete>
-    No longer exists in the code as of 2014/2/25.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Size of WebRTC audio input buffers (atypical values, in audio frames).
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.AudioOutputChannelLayout" enum="ChannelLayout"
-    expires_after="2014-02-26">
-  <obsolete>
-    Removed from code on 2014/2/25.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Audio output channel layout in WebRTC.</summary>
-</histogram>
-
-<histogram name="WebRTC.AudioOutputFramesPerBuffer" enum="AudioFramesPerBuffer"
-    expires_after="2016-11-24">
-  <obsolete>
-    Removed from code Sep 2014.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>Size of WebRTC audio output buffers (in audio frames).</summary>
-</histogram>
-
-<histogram name="WebRTC.AudioOutputFramesPerBufferUnexpected"
-    units="audio frames" expires_after="2016-11-24">
-  <obsolete>
-    Removed from code Sep 2014.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Size of WebRTC audio output buffers (atypical values, in audio frames).
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.AudioRenderTime" units="ms" expires_after="2014-02-26">
-  <obsolete>
-    Removed from code 2014/2/25.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>Duration in milliseconds of WebRTC audio render session.</summary>
-</histogram>
-
-<histogram name="WebRTC.AudioRenderTimes" units="ms" expires_after="2016-08-25">
-  <obsolete>
-    Removed as of Aug 2016, replaced by
-    Media.Audio.Render.GetSourceDataTime.WebRTC.
-  </obsolete>
-  <owner>henrika@chromium.org</owner>
-  <summary>
-    Measures the time spent in WebRtcAudioRenderer::SourceCallback. Sampled 10
-    times per second.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Call.TimeSendingAudioRtpPacketsInSeconds" units="s"
-    expires_after="2018-11-26">
-  <obsolete>
-    Removed 11/2018 due to little use and high implementation complexity.
-  </obsolete>
-  <owner>saza@chromium.org</owner>
-  <summary>
-    The amount of time between sending the first and the last audio RTP packets
-    through the audiostreams of a Call object. This is logged when the Call
-    object is destroyed. This is only logged if audio RTP packets are at some
-    point in time received, and is a way to omit temporary objects that do not
-    send any actual media.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupState.AnswererState"
-    enum="PeerConnectionAnswererState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes which
-    &quot;answerer step&quot; the peer connection reached in its most successful
-    attempt. See blink::AnswererState for more information.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupState.CallSetupState"
-    enum="PeerConnectionCallSetupState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes the status
-    of the most successful attempt. See blink::CallSetupState for more
-    information.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupState.OffererState"
-    enum="PeerConnectionOffererState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes which
-    &quot;answerer step&quot; the peer connection reached in its most successful
-    attempt. See blink::OffererState for more information.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupStateWithGum.AnswererState"
-    enum="PeerConnectionAnswererState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes which
-    &quot;answerer step&quot; the peer connection reached in its most successful
-    attempt. See blink::AnswererState for more information. This is the same as
-    &quot;WebRTC.PeerConnection.CallSetupState.AnswererState&quot; except it is
-    only reported for peer connections on pages where getUserMedia() has been
-    called.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupStateWithGum.CallSetupState"
-    enum="PeerConnectionCallSetupState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes the status
-    of the most successful attempt. See blink::CallSetupState for more
-    information. This is the same as
-    &quot;WebRTC.PeerConnection.CallSetupState.CallSetupState&quot; except it is
-    only reported for peer connections on pages where getUserMedia() has been
-    called.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.CallSetupStateWithGum.OffererState"
-    enum="PeerConnectionOffererState" expires_after="M80">
-  <obsolete>
-    These metrics were useful when Unified Plan was made the default SDP
-    semantics. They will again become useful when Plan B is becoming deprecated.
-    Until then, these are of little value and are temporarily disabled.
-  </obsolete>
-  <owner>hbos@chromium.org</owner>
-  <owner>hta@chromium.org</owner>
-  <summary>
-    Setting up a call involves a number of steps; this enum describes which
-    &quot;answerer step&quot; the peer connection reached in its most successful
-    attempt. See blink::OffererState for more information. This is the same as
-    &quot;WebRTC.PeerConnection.CallSetupState.OffererState&quot; except it is
-    only reported for peer connections on pages where getUserMedia() has been
-    called.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.PeerConnection.SelectedRtcpMuxPolicy"
-    enum="PeerConnectionRtcpMuxPolicy" expires_after="2016-12-20">
-  <obsolete>
-    Removed on Dec 2016. This histogram is used to gauge the risk of making the
-    change for issue 6030. The decision has been made and this is not needed any
-    more.
-  </obsolete>
-  <owner>zhihuang@chromium.org</owner>
-  <summary>
-    Whether the application specified a value for RTCP-mux policy, and if so,
-    which value, &quot;Require&quot; or &quot;Negotiate&quot;. Recorded after
-    parsing the configuration when creating the RTCPeerConnection.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.UserMediaRequest.Result"
-    enum="MediaStreamRequestResult" expires_after="2018-02-13">
-  <obsolete>
-    Replaced by WebRTC.UserMediaRequest.Result2 in Feb 2018.
-  </obsolete>
-  <owner>andresp@chromium.org</owner>
-  <summary>
-    Counters for UserMediaRequests results such as failure reasons.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.BadCall.Any" units="%" expires_after="2020-08-27">
-  <obsolete>
-    Removed 08/27/2020.
-  </obsolete>
-  <owner>sprang@chromium.org</owner>
-  <summary>
-    Fraction of time the call was classified as bad because of any reason.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.BadCall.FrameRate" units="%"
-    expires_after="2020-08-27">
-  <obsolete>
-    Removed 08/27/2020.
-  </obsolete>
-  <owner>sprang@chromium.org</owner>
-  <summary>
-    Fraction of time the call was classified as bad because of low framerate.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.BadCall.FrameRateVariance" units="%"
-    expires_after="2020-08-27">
-  <obsolete>
-    Removed 08/27/2020.
-  </obsolete>
-  <owner>sprang@chromium.org</owner>
-  <summary>
-    Fraction of time the call was classified as bad because of high framerate
-    variance.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.BadCall.Qp" units="%" expires_after="2020-08-27">
-  <obsolete>
-    Removed 08/27/2020.
-  </obsolete>
-  <owner>sprang@chromium.org</owner>
-  <summary>
-    Fraction of time the call was classified as bad because of high qp.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.CompleteFramesReceivedPerSecond" units="fps"
-    expires_after="M85">
-  <obsolete>
-    Removed 03/28/2019.
-  </obsolete>
-  <owner>asapersson@chromium.org</owner>
-  <summary>
-    The number of complete frames received per second for a received video
-    stream. Recorded when a stream is removed. The total number of frames is
-    divided by the time the video stream exists.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.DiscardedPacketsInPercent" units="%"
-    expires_after="M85">
-  <obsolete>
-    Removed 03/28/2019.
-  </obsolete>
-  <owner>asapersson@chromium.org</owner>
-  <summary>
-    Percentage of discarded packets by the jitter buffer due to arriving too
-    late for a received video stream. Recorded when a stream is removed.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.Video.DuplicatedPacketsInPercent" units="%"
-    expires_after="M85">
-  <obsolete>
-    Removed 03/28/2019.
-  </obsolete>
-  <owner>asapersson@chromium.org</owner>
-  <summary>
-    Percentage of duplicated packets in the jitter buffer for a received video
-    stream. Recorded when a stream is removed.
-  </summary>
-</histogram>
-
-<histogram name="WebRTC.webkitApiCountUniqueByOrigin" enum="RTCAPIName"
-    expires_after="2014-03-28">
-  <obsolete>
-    Removed as of r253828 (27 Feb 2014).
-  </obsolete>
-  <owner>tommi@chromium.org</owner>
-  <summary>
-    Counts number of calls to WebRTC APIs from JavaScript, once per origin per
-    renderer process.
-  </summary>
-</histogram>
-
-<histogram name="WebShare.Unverified" enum="SBClientDownloadExtensions"
-    expires_after="M82">
-  <obsolete>
-    Removed March 2020.
-  </obsolete>
-  <owner>ericwilligers@chromium.org</owner>
-  <owner>hartmanng@chromium.org</owner>
-  <owner>hzjian@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    File types included in navigator.share() requests, where file content and
-    source URLs were not verified with Safe Browsing.
-  </summary>
-</histogram>
-
-<histogram name="WebsiteSettings.Action.HttpsUrl" enum="WebsiteSettingsAction"
-    expires_after="2016-10-23">
-  <obsolete>
-    Removed October 2016 in favor of Security.PageInfo.Action.HttpsUrl.Valid,
-    Security.PageInfo.Action.HttpsUrl.Dangerous, and
-    Security.PageInfo.Action.HttpsUrl.Downgraded.
-  </obsolete>
-  <owner>estark@chromium.org</owner>
-  <summary>
-    Tracks WebsiteSettings actions that take place on an HTTPS URL. This
-    completely disregards security status.
-  </summary>
-</histogram>
-
-<histogram name="WebsiteSettings.PermissionChanged" enum="ContentType"
-    expires_after="2014-12-17">
-  <obsolete>
-    Removed 12/2014 in Issue 433776, and replaced by
-    WebsiteSettings.OriginInfo.PermissionChanged.
-  </obsolete>
-  <owner>sashab@chromium.org</owner>
-  <summary>
-    Count of how often a specific content type (permission) is changed using the
-    Page Info UI.
-
-    Note: The values of this metric collected for Chrome 49 (early 2016) are
-    innacurate and should not be trusted. crbug.com/589255.
-  </summary>
-</histogram>
-
-<histogram name="websql.Async.OpenTime.Error" units="ms"
-    expires_after="2018-11-22">
-  <obsolete>
-    Removed 12/2018. We're no longer monitoring WebSQL performance.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>
-    The time required to try (and fail) to open a Web SQL database.
-  </summary>
-</histogram>
-
-<histogram name="websql.Async.OpenTime.Success" units="ms"
-    expires_after="2018-11-22">
-  <obsolete>
-    Removed 12/2018. We're no longer monitoring WebSQL performance.
-  </obsolete>
-  <owner>cmumford@chromium.org</owner>
-  <summary>The time required to successfully open a Web SQL database.</summary>
-</histogram>
-
-<histogram name="WebstoreWidgetApp.Close" enum="SuggestAppsDialogCloseReason"
-    expires_after="2019-02-15">
-  <obsolete>
-    There is no remaining code that is emmiting this metric. It was removed at
-    an unknown time.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Webstore Widget app: the reason why the suggest apps dialog was closed.
-  </summary>
-</histogram>
-
-<histogram name="WebstoreWidgetApp.Install" enum="SuggestAppsDialogInstall"
-    expires_after="2019-02-15">
-  <obsolete>
-    There is no remaining code that is emmiting this metric. It was removed at
-    an unknown time.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Webstore Widget app: whether the Webstore item user selected was
-    successfully installed or not.
-  </summary>
-</histogram>
-
-<histogram name="WebstoreWidgetApp.Load" enum="SuggestAppsDialogLoad"
-    expires_after="2019-02-15">
-  <obsolete>
-    There is no remaining code that is emmiting this metric. It was removed at
-    an unknown time.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Webstore Widget app: whether the initialization of the dialog succeeded or
-    not.
-  </summary>
-</histogram>
-
-<histogram name="WebstoreWidgetApp.LoadTime" units="ms"
-    expires_after="2019-02-15">
-  <obsolete>
-    There is no remaining code that is emmiting this metric. It was removed at
-    an unknown time.
-  </obsolete>
-  <owner>joshwoodward@google.com</owner>
-  <summary>
-    Webstore Widget app: time to load the widget contained in the app. Measured
-    between the moment window appears and the moment all the contents in the app
-    including the Chrome Webstore widget are ready.
-  </summary>
-</histogram>
-
-<histogram name="WebURLLoader.SyncResourceRequestDuration" units="ms"
-    expires_after="M75">
-  <obsolete>
-    Removed 2019-12 after expiration, while adding the similar
-    XHR.Sync.BlockingTime.MainThread and XHR.Sync.BlockingTime.WorkerThread.
-  </obsolete>
-  <owner>qinmin@chromium.org</owner>
-  <owner>cduvall@chromium.org</owner>
-  <summary>
-    Records the total duration the renderer spent on each sync XHR resource
-    request, including requests that time out.
-  </summary>
-</histogram>
-
-<histogram name="WebUsb.DetectorInitialization" units="ms" expires_after="M81">
-  <obsolete>
-    Obsolete in M72 as initialization of WebUsbDetector no longer blocks the
-    main thread.
-  </obsolete>
-  <owner>reillyg@chromium.org</owner>
-  <summary>
-    Records the time spent initializing the WebUSB detector module.
-  </summary>
-</histogram>
-
-<histogram name="WebView.LoadDataWithBaseUrl.HistoryUrl" enum="HistoryUrlType"
-    expires_after="2018-04-06">
-  <obsolete>
-    Obsolete 04/04/2018 as it has been replaced by
-    Android.WebView.LoadDataWithBaseUrl.HistoryUrl.
-  </obsolete>
-  <owner>jamwalla@chromium.org</owner>
-  <summary>
-    Records whether the historyUrl parameter to loadDataWithBaseUrl is empty/
-    null, the same as the baseUrl parameter, or different from baseUrl.
-  </summary>
-</histogram>
-
-<histogram name="WindowManager.PanelWindowCountPerLoad" units="units"
-    expires_after="2015-04-13">
-  <obsolete>
-    Removed 4/2013. No longer tracked.
-  </obsolete>
-  <owner>kuscher@chromium.org</owner>
-  <summary>
-    The number of panel windows open when a load completes. Panels are windows
-    docked to the bottom of the OS desktop, which are visible to the user even
-    while the user is interacting with other applications.
-  </summary>
-</histogram>
-
-<histogram name="Windows.CreateThreadTime" units="ms" expires_after="M77">
-  <obsolete>
-    Removed 01/2020 as it was causing dead lock issues. crbug.com/1043353.
-  </obsolete>
-  <owner>stanisc@chromium.org</owner>
-  <summary>
-    Time spent inside CreateThread() Windows API call creating a single thread.
-  </summary>
-</histogram>
-
-<histogram name="Windows.HasOpenXpsSupport" enum="Boolean"
-    expires_after="2020-04-01">
-  <obsolete>
-    Removed 03/2020 after insight about OpenXPS has lead to more general
-    question of XPS availability (either type).
-  </obsolete>
-  <owner>awscreen@chromium.org</owner>
-  <owner>thestig@chromium.org</owner>
-  <summary>
-    If the version of Xpsprint.dll is sufficiently modern to support OpenXPS.
-    Reported once per browser session, on startup.
-  </summary>
-</histogram>
-
-<histogram name="Windows.InCompatibilityMode" enum="BooleanCompatibilityMode"
-    expires_after="M77">
-  <obsolete>
-    Removed 06/2019
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <owner>brucedawson@chromium.org</owner>
-  <summary>
-    A boolean used to indicate when the Windows version reported by
-    GetVersionEx() and the Windows version reported by VerQueryValue() on
-    kernel32 do not match. This is queried shortly after startup.
-  </summary>
-</histogram>
-
-<histogram name="Windows.UCRTVersion" enum="WindowsVersion"
-    expires_after="2020-04-30">
-  <obsolete>
-    Removed 04/2020. Necessary data was collected and a decision was made. See
-    https://crbug.com/920704 for details.
-  </obsolete>
-  <owner>brucedawson@chromium.org</owner>
-  <owner>jmadill@chromium.org</owner>
-  <summary>
-    The ucrtbase.dll version, converted to a base::win::Version enum. This is
-    queried shortly after startup.
-  </summary>
-</histogram>
-
-<histogram name="Windows.Win32kRendererLockdown" enum="BooleanEnabled"
-    expires_after="2016-10-11">
-  <obsolete>
-    Removed 10/2016 as this is enabled by default so provides no useful data.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <summary>
-    Count of browser launches where Win32k renderer lockdown is enabled.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.CreateIconFilesCount" units="units"
-    expires_after="2017-07-07">
-  <obsolete>
-    Obsolete 07/06/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    The number of jumplist icons requested to create per jumplist update. It is
-    recorded whenever UpdateJumpList() is called.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.CreateIconFilesDuration" units="ms"
-    expires_after="2017-07-07">
-  <obsolete>
-    Obsolete 07/06/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    Time spent in CreateIconFiles(). This method is called whenever there is a
-    jumplist update and the JumpListIcons folder is empty.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DeleteDirectoryContentDuration" units="ms"
-    expires_after="2017-07-10">
-  <obsolete>
-    Obsolete 07/06/2016 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in DeleteDirectoryContentAndLogRuntime().</summary>
-</histogram>
-
-<histogram name="WinJumplist.DeleteDirectoryDuration" units="ms"
-    expires_after="2017-05-01">
-  <obsolete>
-    Obsolete 04/25/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in DeleteDirectoryAndLogResults().</summary>
-</histogram>
-
-<histogram name="WinJumplist.DeleteStatusJumpListIcons"
-    enum="JumplisticonsDeleteCategory" expires_after="2017-05-01">
-  <obsolete>
-    Obsolete 04/25/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric records the detailed delete result of JumpListIcons directory.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DeleteStatusJumpListIconsOld"
-    enum="JumplisticonsDeleteCategory" expires_after="2017-05-01">
-  <obsolete>
-    Obsolete 04/25/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric records the detailed delete result of JumpListIconsOld
-    directory.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DetailedFolderMoveResults"
-    enum="JumplistIconsDetailedFolderMoveCategory" expires_after="2016-12-14">
-  <obsolete>
-    Obsolete 12/13/2016 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric is recorded when folder JumpListIcons is moved (can be rename or
-    copy and delete) to JumpListIconsOld. This happens when tabs are closed,
-    mostly visited URLs get updated, etc. There are several key steps in this
-    folder move operation. Before the move operation, there is another step that
-    JumpListIconsOld folder is deleted. The status of these steps are put
-    together and recorded in this metric. The failure of any of these steps is
-    suspected to be related to a known issue.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DetailedFolderResults"
-    enum="JumplistIconsDetailedFolderOperationCategory"
-    expires_after="2017-03-13">
-  <obsolete>
-    Obsolete 03/10/2017 as it is replaced by DetailedFolderResultsDeleteUpdated.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric is recorded when folders JumpListIcons and JumpListIconsOld get
-    updated. These two folders are updated when tabs are closed, mostly visited
-    URLs get updated, etc. These two folders are updated as follows 1)
-    JumpListIconsOld with its content get deleted; 2) if step 1 succeeds,
-    JumpListIcons is moved, 3) if any of the previous steps fails, JumpListIcons
-    is deleted, 4) A new JumpListIcons folder is created. The status of these 4
-    file operations are put together and recorded in this metric. The failure of
-    any of these file operations is suspected to be related to a known issue.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DetailedFolderResultsDeleteUpdated"
-    enum="JumplistIconsDetailedFolderOperationDeleteUpdatedCategory"
-    expires_after="2017-03-23">
-  <obsolete>
-    Obsolete 03/20/2017. New metrics named WinJumplist.DeleteStatusJumpListIcons
-    and WinJumplist.DeleteStatusJumpListIconsOld are used instead.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric is recorded when folders JumpListIcons and JumpListIconsOld get
-    updated. These two folders are updated when tabs are closed, mostly visited
-    URLs get updated, etc. These two folders are updated as follows 1)
-    JumpListIconsOld with its content get deleted; 2) if step 1 succeeds,
-    JumpListIcons is renamed to JumpListIconsOld, 3) if any of the previous
-    steps fails, JumpListIcons is deleted, 4) A new JumpListIcons folder is
-    created if deletion of JumpListIcons' content succeeds (only fail to delete
-    the directory is okay). The status of these 4 file operations are put
-    together and recorded in this metric. The failure of any of these file
-    operations is suspected to be related to a known issue.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DirectoryStatusJumpListIcons"
-    enum="JumpListIconsFolderExistOrEmptyCategory" expires_after="2017-05-01">
-  <obsolete>
-    Obsolete 04/25/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric records whether the folder JumpListIcons exists; and if it does,
-    whether it is empty or non-empty.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.DirectoryStatusJumpListIconsOld"
-    enum="JumpListIconsFolderExistOrEmptyCategory" expires_after="2017-05-01">
-  <obsolete>
-    Obsolete 04/25/2017 as we are no long recording this metric.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric records whether the folder JumpListIconsOld exists; and if it
-    does, whether it is empty or non-empty.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.FolderMoveResults"
-    enum="JumplistIconsFolderMoveCategory" expires_after="2016-12-09">
-  <obsolete>
-    Obsolete 12/08/2016. DetailedFolderMoveResults is used for more detailed
-    analysis.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric is recorded when folder JumpListIcons is moved (can be rename or
-    copy and delete) to JumpListIconsOld. This happens when tabs are closed,
-    mostly visited URLs get updated, etc. There are 3 possible steps in this
-    folder move operation. Before the move operation, there is another step that
-    JumpListIconsOld folder is deleted. The status of these steps are put
-    together and recorded in this metric. The failure of any of these steps is
-    suspected to be related to a known issue listed below.
-    https://bugs.chromium.org/p/chromium/issues/detail?id=179576
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.FolderResults" enum="JumplisticonsfolderCategory"
-    expires_after="2016-12-14">
-  <obsolete>
-    Obsolete 12/13/2016, as we are now recording DetailedFolderResults.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    This metric is recorded when folders JumpListIcons and JumpListIconsOld get
-    updated. These two folders are updated when tabs are closed, mostly visited
-    URLs get updated, etc. These two folders are updated as follows 1)
-    JumpListIconsOld with its content get deleted; 2) JumpListIcons is moved, 3)
-    A new JumpListIcons folder is created. The status of these three file
-    operations are put together and recorded in this metric. The failure of any
-    of these file operations is suspected to be related to a known issue.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.NotificationTimeInterval" units="ms"
-    expires_after="2017-07-11">
-  <obsolete>
-    Obsolete 07/10/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    The time interval between two adjacent update notifications if it's less
-    than 3500 ms.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.NotificationTimeInterval2" units="ms"
-    expires_after="2017-07-24">
-  <obsolete>
-    Obsolete 07/23/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    The time interval between two adjacent update notifications. A zero value
-    indicates the interval is greater than 3500 ms.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.OnFaviconDataAvailableDuration" units="ms"
-    expires_after="2017-06-29">
-  <obsolete>
-    Obsolete 06/22/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in OnFaviconDataAvailable().</summary>
-</histogram>
-
-<histogram name="WinJumplist.RatioAddCategoryTime" units="scaled ratio"
-    expires_after="2017-07-24">
-  <obsolete>
-    Obsolete 07/23/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    The ratio of the duration spent adding the most-visited category compared to
-    the duration spent adding the recently-closed category, multiplied by 10.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplist.StartLoadingFaviconDuration" units="ms"
-    expires_after="2017-06-29">
-  <obsolete>
-    Obsolete 06/22/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in StartLoadingFavicon().</summary>
-</histogram>
-
-<histogram name="WinJumplist.UpdateJumpListDuration" units="ms"
-    expires_after="2017-04-25">
-  <obsolete>
-    Obsolete 04/20/2017 as it's no longer accurate due to the code change.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>
-    Time spent in UpdateJumpList(). This method is called whenever there is a
-    jumplist update.
-  </summary>
-</histogram>
-
-<histogram name="WinJumplistUpdater.AddCustomCategoryDuration" units="ms"
-    expires_after="2017-07-28">
-  <obsolete>
-    Obsolete 07/26/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in JumpListUpdater::AddCustomCategory.</summary>
-</histogram>
-
-<histogram name="WinJumplistUpdater.AddTasksDuration" units="ms"
-    expires_after="2017-07-11">
-  <obsolete>
-    Obsolete 07/10/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in JumpListUpdater::AddTasks.</summary>
-</histogram>
-
-<histogram name="WinJumplistUpdater.BeginUpdateDuration" units="ms"
-    expires_after="2017-07-28">
-  <obsolete>
-    Obsolete 07/26/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in JumpListUpdater::BeginUpdate.</summary>
-</histogram>
-
-<histogram name="WinJumplistUpdater.CommitUpdateDuration" units="ms"
-    expires_after="2017-07-28">
-  <obsolete>
-    Obsolete 07/26/2017 as it's no longer needed.
-  </obsolete>
-  <owner>chengx@chromium.org</owner>
-  <summary>Time spent in JumpListUpdater::CommitUpdate.</summary>
-</histogram>
-
-<histogram name="WinTimeTicks.FailedToChangeCores" enum="WindowsVersion"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    Incremented each time the TimeTicks field trial runs on a machine with
-    multiple cores, but failed to change thread affinity. Broken down by Windows
-    version.
-  </summary>
-</histogram>
-
-<histogram name="WinTimeTicks.MinResolutionNanoseconds" units="nanoseconds"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The smallest non-zero delta reported by subsequent calls to
-    QueryPerformanceCounter.
-  </summary>
-</histogram>
-
-<histogram name="WinTimeTicks.NonStopTsc" units="units"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    True if the CPU's timestamp counter ticks at a constant rate regardless of
-    CPU frequency.
-  </summary>
-</histogram>
-
-<histogram name="WinTimeTicks.TickedBackwards" enum="WindowsVersion"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times the TimeTicks field trial failed because
-    QueryPerformanceCounter ticked backwards. Broken down by Windows version.
-  </summary>
-</histogram>
-
-<histogram name="WinTimeTicks.VersionSuccessful" enum="WindowsVersion"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times the TimeTicks field trial succeeded. Broken down by
-    Windows version.
-  </summary>
-</histogram>
-
-<histogram name="WinTimeTicks.VersionTotal" enum="WindowsVersion"
-    expires_after="2017-01-12">
-  <obsolete>
-    Removed 01/2017.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The number of times the TimeTicks field trial ran for comparison with
-    WinTimeTicks.VersionSuccess. Broken down by Windows version.
-  </summary>
-</histogram>
-
-<histogram name="Worker.TopLevelScript.OriginType.RequestUrl.DedicatedWorker"
-    enum="WorkerTopLevelScriptOriginType" expires_after="M80">
-  <obsolete>
-    Removed Jan 2020.
-  </obsolete>
-  <owner>hiroshige@chromium.org</owner>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>
-    Type of worker top-level script's request URL's origin, relative to parent
-    execution context's origin, recorded on each successful classic dedicated
-    worker creation.
-  </summary>
-</histogram>
-
-<histogram name="WorkerScheduler.WorkerThreadLoad" units="%"
-    expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    Worker thread load, i.e. percentage of time spent on running tasks. This
-    metric is emitted at most once per kWorkerThreadLoadTrackerReportingInterval
-    sec per worker thread amortized. E.g. if a worker ran a single task for X
-    seconds and then went to idle for Y seconds before it shuts down, and
-    assuming the interval rate was 1 sec, we get X samples for 100% and Y
-    samples for 0%.
-  </summary>
-</histogram>
-
-<histogram name="WorkerThread.DebuggerTask.Time" units="ms"
-    expires_after="2018-02-13">
-  <obsolete>
-    Removed on 2018-02.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>The time taken for running a debugger task on WorkerThread.</summary>
-</histogram>
-
-<histogram name="WorkerThread.Runtime" units="ms" expires_after="M80">
-  <obsolete>
-    Removed July 2019.
-  </obsolete>
-  <owner>kinuko@chromium.org</owner>
-  <summary>
-    The amount of time a worker thread ran for. Starts recording when a worker
-    scheduler for the thread is created, and stops when the scheduler is shut
-    down.
-  </summary>
-</histogram>
-
-<histogram name="WorkerThread.Task.Time" units="ms" expires_after="2018-02-13">
-  <obsolete>
-    Removed on 2018-02. The sample count was overflowing. crbug.com/809672.
-  </obsolete>
-  <owner>nhiroki@chromium.org</owner>
-  <summary>The time taken for running a worker task on WorkerThread.</summary>
-</histogram>
-
-<histogram name="WrenchMenu.OpeningAnimationFrameTimes" units="ms"
-    expires_after="M77">
-  <obsolete>
-    Removed on 2020-04. Bucket sizes are not very useful for measuring jank. The
-    only user of AnimationFrameTimeHistogram.
-  </obsolete>
-  <owner>kkimlabs@chromium.org</owner>
-  <summary>
-    Frame times of the Android wrench menu opening animation. For example, if
-    the menu opening animation runs exactly at 60fps for a second, then each
-    frame time is 16ms, and a total of 60 values of 16ms are recorded. If the
-    animation is janky, we will see values greater than 16ms in the histogram.
-  </summary>
-</histogram>
-
-<histogram name="XR.RuntimeAvailable" enum="XRRuntimeAvailable"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 03/2020
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Indicates which VR APIs are installed. Recorded shortly after startup.
-  </summary>
-</histogram>
-
-<histogram name="XR.VRSession.StartAction" enum="VRSessionStartAction"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 02/2020
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    The action that triggered the transition into Chrome in VR, either from 2D
-    or another VR app.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.ConsentFlow" enum="XRSessionRequestDialogAction"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Records the actions of a user consent dialog which is displayed on
-    requesting an XR session.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.ConsentFlowDuration.ConsentFlowAborted" units="ms"
-    expires_after="2020-07-01">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Time the user takes to abort the consent flow by clicking on the
-    window-close system button of a session request consent dialog.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.ConsentFlowDuration.ConsentGranted" units="ms"
-    expires_after="2020-10-11">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Time the user takes to click on the allow-and-enter-VR button on a session
-    request consent dialog.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.ConsentFlowDuration.ConsentNotGranted" units="ms"
-    expires_after="2020-10-11">
-  <obsolete>
-    Removed as of 06/2020.
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>mlamouri@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    Time the user takes to click on dont-allow button on a session request
-    consent dialog.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.PresentationSession" enum="VRPresentationStartAction"
-    expires_after="2020-08-30">
-  <obsolete>
-    Removed 02/2020
-  </obsolete>
-  <owner>alcooper@chromium.org</owner>
-  <owner>xr-dev@chromium.org</owner>
-  <summary>
-    The action that triggered VR presentation, which is the display of web
-    content on a VR device.
-  </summary>
-</histogram>
-
-<histogram name="XR.WebXR.RenderPath.Used" enum="XRRenderPath"
-    expires_after="M80">
-  <obsolete>
-    Removed July 2019. This was being tracked in case the assumptions about
-    feature availability based on platform version turned out to be incorrect,
-    but it appears that this is working as intended. The webxr-render-path flag
-    that could be used to override this at runtime was previously removed in
-    https://crrev.com/c/1487074.
-  </obsolete>
-  <owner>klausw@chromium.org</owner>
-  <summary>
-    Records the WebXR/WebVR render path used for presentation on presentation
-    start. The render path is affected by overrides and device capabilities.
-  </summary>
-</histogram>
-
-</histograms>
-
-</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index fbd8dbc6..ce8e112 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -4535,6 +4535,9 @@
 
 <histogram name="Crashpad.CrashReportPending" enum="CrashpadReportPending"
     expires_after="M85">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>
@@ -4543,6 +4546,9 @@
 </histogram>
 
 <histogram name="Crashpad.CrashReportSize" units="bytes" expires_after="M85">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The size of a crash report minidump on disk when captured.</summary>
@@ -4550,6 +4556,9 @@
 
 <histogram name="Crashpad.CrashUpload.AttemptSuccessful"
     enum="CrashpadUploadAttemptStatus" expires_after="M85">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>Logs whether a crash uploaded succeeded or failed.</summary>
@@ -4557,6 +4566,9 @@
 
 <histogram name="Crashpad.CrashUpload.Skipped"
     enum="CrashpadUploadSkippedReason" expires_after="M85">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The reason that a crash report upload was skipped.</summary>
@@ -4564,6 +4576,9 @@
 
 <histogram name="Crashpad.ExceptionCaptureResult"
     enum="CrashpadExceptionCaptureResult" expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The outcome of execution of the Crashpad exception handler.</summary>
@@ -4571,6 +4586,9 @@
 
 <histogram name="Crashpad.ExceptionCode.Mac" enum="CrashpadMacExceptionCodes"
     expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>mark@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The exception code encountered in a crash on Mac OS X.</summary>
@@ -4578,6 +4596,9 @@
 
 <histogram name="Crashpad.ExceptionCode.Win" enum="CrashpadWinExceptionCodes"
     expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The exception code encountered in a crash on Windows.</summary>
@@ -4585,6 +4606,9 @@
 
 <histogram name="Crashpad.ExceptionEncountered"
     enum="CrashpadExceptionProcessingState" expires_after="2021-08-22">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>
@@ -4595,6 +4619,9 @@
 
 <histogram name="Crashpad.HandlerCrash.ExceptionCode.Mac"
     enum="CrashpadMacExceptionCodes" expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>mark@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>
@@ -4605,6 +4632,9 @@
 
 <histogram name="Crashpad.HandlerCrash.ExceptionCode.Win"
     enum="CrashpadWinExceptionCodes" expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>
@@ -4615,6 +4645,9 @@
 
 <histogram name="Crashpad.HandlerLifetimeMilestone"
     enum="CrashpadLifetimeMilestone" expires_after="M90">
+  <expired_intentionally>
+    Kept as a diagnostic metric.
+  </expired_intentionally>
   <owner>jperaza@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>Handler start/crash/exit events.</summary>
@@ -13675,6 +13708,25 @@
   </summary>
 </histogram>
 
+<histogram name="SSL.Experimental.SubresourceResponse"
+    enum="SSLSubresourceResponseType" expires_after="2023-02-03">
+  <owner>amanvr@chromium.org</owner>
+  <owner>carlscab@chromium.org</owner>
+  <owner>woa-performance@google.com</owner>
+  <summary>
+    The histogram is being used to track the number of messages
+    (content::mojom::FrameHost::SubresourceResponseStarted IPCs) resulting in
+    no-op (i.e. returning without doing anything) but requiring an IPC vs
+    messages which revoke exceptions after seeing a good certificate when
+    calling SSLManager::DidStartResourceResponse() from
+    RenderFrameHostImpl::SubresourceResponseStarted(). We are not interested in
+    calls to SSLManager::DidStartResourceResponse() from ReadyToCommitNavigation
+    since they don't involve mojo messages. From local benchmarks, we observe
+    this request causes significant IPC chatter, and this histogram will help us
+    understand it better.
+  </summary>
+</histogram>
+
 <histogram name="SSL.InsecureContent" enum="InsecureContentType"
     expires_after="2020-02-23">
   <obsolete>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 06fda3fc..1d745da 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -446,6 +446,10 @@
 
 <histogram name="PasswordManager.AccountStorage.ClearedOnStartup"
     enum="PasswordAccountStoreClearedOnStartup" expires_after="2023-04-16">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -454,6 +458,16 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.AccountStorage.ClearedOnStartup2"
+    enum="PasswordAccountStoreClearedOnStartup" expires_after="2023-04-16">
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <summary>
+    Records whether the account-scoped password storage had to be cleared during
+    regular profile initialization.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.AccountStorage.ClearedOptInForAllAccounts"
     units="accounts" expires_after="2023-02-12">
   <owner>mamir@chromium.org</owner>
@@ -584,6 +598,10 @@
 
 <histogram name="PasswordManager.AccountStoreVsProfileStore3.{DifferenceType}"
     units="accounts" expires_after="2023-05-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -609,6 +627,33 @@
   </token>
 </histogram>
 
+<histogram name="PasswordManager.AccountStoreVsProfileStore4.{DifferenceType}"
+    units="accounts" expires_after="2023-05-01">
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <summary>
+    The number of accounts {DifferenceType}. Recorded soon after startup at most
+    one per day for regular profiles and only if user opted in to the
+    account-scoped storage.
+  </summary>
+  <token key="DifferenceType">
+    <variant name="Additional"
+        summary="stored in the password manager's account-scoped store that
+                 don't exist in the profile-scoped store"/>
+    <variant name="Conflicting"
+        summary="stored in the password manager with a conflicting password
+                 between the account-scoped store and profile-scoped store
+                 (i.e. the signon realm and username match, but the password
+                 does not)"/>
+    <variant name="Identical"
+        summary="stored in both the password manager's account-scoped store
+                 and profile-scoped store"/>
+    <variant name="Missing"
+        summary="stored in the password manager's profile-scoped store that
+                 don't exist in the account-scoped store"/>
+  </token>
+</histogram>
+
 <histogram name="PasswordManager.AddCredentialFromSettings.AccountStoreUsed"
     enum="Boolean" expires_after="2023-03-19">
   <owner>lizapopova@google.com</owner>
@@ -851,6 +896,10 @@
 
 <histogram name="PasswordManager.BiometricAuthBeforeFillingEnabled"
     enum="BooleanEnabled" expires_after="M112">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vsemeniuk@google.com</owner>
   <summary>
@@ -860,6 +909,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.BiometricAuthBeforeFillingEnabled2"
+    enum="BooleanEnabled" expires_after="M112">
+  <owner>kazinova@google.com</owner>
+  <owner>vsemeniuk@google.com</owner>
+  <summary>
+    Indicates whether biometric authentication before filling is enabled.
+    Recorded 30 seconds after PasswordStore is created which happens at most
+    once per day for regular profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.BiometricAuthPwdFill.AuthResult"
     enum="BiometricAuthResult" expires_after="2023-02-12">
   <owner>ioanap@chromium.org</owner>
@@ -896,6 +956,10 @@
 
 <histogram name="PasswordManager.BubbleSuppression.AccountsInStatisticsTable"
     units="accounts" expires_after="2023-04-23">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -906,6 +970,19 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.BubbleSuppression.AccountsInStatisticsTable2"
+    units="accounts" expires_after="2023-04-23">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The number of accounts stored in password_manager::StatisticsTable. These
+    are accounts for which the user ignored the save bubble at least once. The
+    count is recorded once per browser start-up for regular profiles. (In case
+    of multiple profiles, the counts are for the profile that first has a
+    WebContents created.)
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.BulkCheck.CanceledTime" units="ms"
     expires_after="2023-05-07">
   <owner>vasilii@chromium.org</owner>
@@ -1089,7 +1166,11 @@
 </histogram>
 
 <histogram name="PasswordManager.CompromisedCredentials2.{Issue}"
-    units="credentials" expires_after="M114">
+    units="credentials" expires_after="M110">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>vasilii@chromium.org</owner>
   <owner>vsemeniuk@google.com</owner>
   <summary>
@@ -1105,6 +1186,22 @@
   </token>
 </histogram>
 
+<histogram name="PasswordManager.CompromisedCredentials3.{Issue}"
+    units="credentials" expires_after="M114">
+  <owner>vasilii@chromium.org</owner>
+  <owner>vsemeniuk@google.com</owner>
+  <summary>
+    Count of known {Issue}. Recorded at most once per day for regular profiles.
+  </summary>
+  <token key="Issue">
+    <variant name="CountLeaked" summary="leaked credentials in the database"/>
+    <variant name="CountLeakedAfterBulkCheck"
+        summary="leaked credentials in the database if password bulk check
+                 was executed at least once"/>
+    <variant name="CountPhished" summary="phished credentials in the database"/>
+  </token>
+</histogram>
+
 <histogram name="PasswordManager.CredentialEditError"
     enum="CredentialEditError" expires_after="2023-04-23">
   <owner>ioanap@chromium.org</owner>
@@ -1201,6 +1298,10 @@
 
 <histogram name="PasswordManager.CredentialsWithDuplicates2" units="units"
     expires_after="2023-03-19">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1213,8 +1314,26 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.CredentialsWithDuplicates3" units="units"
+    expires_after="2023-03-19">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The number of stored (non-blacklisted) credentials for which
+    &quot;duplicates&quot; exist. A duplicate is a credential with the same
+    signon realm, username, and password - i.e. indistinguishable from the
+    user's point of view. This records the number of *sets* of duplicated
+    credentials; the number of credentials in each set of duplicates is not
+    recorded. Recorded at most once per day for regular profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.CredentialsWithMismatchedDuplicates2"
     units="units" expires_after="2023-04-09">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1227,6 +1346,20 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.CredentialsWithMismatchedDuplicates3"
+    units="units" expires_after="2023-04-09">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The number of stored (non-blacklisted) credentials for which
+    &quot;mismatched duplicates&quot; exist. A mismatched duplicate is a
+    credential with the same signon realm and username, but different password.
+    This records the number of *sets* of duplicated credentials; the number of
+    credentials in each set of duplicates is not recorded. Recorded at most once
+    per day for regular profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.DefaultPasswordStoreSet"
     enum="PasswordManager.Store" expires_after="2023-04-23">
   <owner>mamir@chromium.org</owner>
@@ -1283,7 +1416,11 @@
 </histogram>
 
 <histogram name="PasswordManager.Enabled3" enum="BooleanEnabled"
-    expires_after="2023-05-07">
+    expires_after="2023-03-05">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1293,6 +1430,16 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.Enabled4" enum="BooleanEnabled"
+    expires_after="2023-05-07">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Indicates whether the password manager is enabled. Recorded 30 seconds after
+    PasswordStore is created at most once per day for regular profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.ErrorMessageDismissalReason"
     enum="MessageDismissReason" expires_after="2023-04-30">
   <owner>izuzic@google.com</owner>
@@ -1461,18 +1608,37 @@
 
 <histogram name="PasswordManager.HttpCredentials"
     enum="PasswordManagerHttpCredentialType" expires_after="2023-03-26">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
     Breakdown of HTTP credentials with regard to the existence of a HTTPS
     credential with the same username and whether the corresponding website has
-    HSTS enabled. Recorded once for each HTTP credential of the profile on
-    startup.
+    HSTS enabled. Recorded once for each HTTP credential on profile open.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.HttpCredentials2"
+    enum="PasswordManagerHttpCredentialType" expires_after="2023-03-26">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Breakdown of HTTP credentials with regard to the existence of a HTTPS
+    credential with the same username and whether the corresponding website has
+    HSTS enabled. Recorded once for each HTTP credential on regular profile
+    open.
   </summary>
 </histogram>
 
 <histogram name="PasswordManager.HttpPasswordMigrationCount"
     units="saved credentials" expires_after="2023-03-19">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1481,8 +1647,23 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.HttpPasswordMigrationCount2"
+    units="saved credentials" expires_after="2023-03-19">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Number of HTTP saved passwords that were migrated to HTTPS. Recorded for the
+    regular profiles on HTTPS password form load when there are no credentials
+    saved.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.HttpPasswordMigrationMode"
     enum="HttpPasswordMigrationMode" expires_after="2023-03-26">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1491,6 +1672,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.HttpPasswordMigrationMode2"
+    enum="HttpPasswordMigrationMode" expires_after="2023-03-26">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The mode of migration applied to HTTP passwords migrating to HTTPS. Recorded
+    for the regular profiles on HTTPS password form load when there are no
+    credentials saved.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.Import.DesktopInteractions"
     enum="PasswordsImportDesktopInteractions" expires_after="2023-04-09">
   <owner>eliaskh@chromium.org</owner>
@@ -1737,12 +1929,26 @@
 </histogram>
 
 <histogram name="PasswordManager.LoginDatabaseInit"
-    enum="LoginDatabaseInitError" expires_after="2023-04-30">
+    enum="LoginDatabaseInitError" expires_after="2023-02-26">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>vasilii@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
   <summary>An error on LoginDatabase initialization.</summary>
 </histogram>
 
+<histogram name="PasswordManager.LoginDatabaseInit2"
+    enum="LoginDatabaseInitError" expires_after="2023-04-30">
+  <owner>vasilii@chromium.org</owner>
+  <owner>mamir@chromium.org</owner>
+  <summary>
+    An error on LoginDatabase initialization. Recorded when error was
+    encountered during login database initialization.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.ManagePasswordsReferrer"
     enum="ManagePasswordsReferrer" expires_after="2023-04-30">
   <owner>kazinova@google.com</owner>
@@ -2472,7 +2678,11 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordStoreInitResult" enum="BooleanSuccess"
-    expires_after="2023-07-30">
+    expires_after="M110">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>vasilii@chromium.org</owner>
   <owner>src/components/password_manager/OWNERS</owner>
   <summary>
@@ -2481,6 +2691,19 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.PasswordStoreInitResult2"
+    enum="BooleanSuccess" expires_after="M110">
+  <owner>vasilii@chromium.org</owner>
+  <owner>src/components/password_manager/OWNERS</owner>
+  <summary>
+    Success rate of initialization of password store. Recorded for every user
+    once on the Chrome profile startup. Only recorded for &quot;regular&quot;
+    profiles, i.e. those in which Password Manager might actually work. This
+    excludes incognito profiles, guest profiles, system profiles (used for the
+    profile picker), lockscreen profiles, etc.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.PasswordStoreProxyBackend.{Function}.Fallback"
     enum="Boolean" expires_after="M114">
   <owner>maxan@google.com</owner>
@@ -2701,6 +2924,10 @@
 
 <histogram name="PasswordManager.PasswordSyncState2" enum="PasswordSyncState"
     expires_after="2023-04-30">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2709,6 +2936,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.PasswordSyncState3" enum="PasswordSyncState"
+    expires_after="2023-04-30">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Whether the passwords are syncing and, if not, then what's causing sync
+    failures. Recorded after the first sync attempt either succeeds or fails for
+    the regular profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.PasswordViewPage.UserActions"
     enum="PasswordViewPageInteractions" expires_after="2023-05-07">
   <owner>derinel@google.com</owner>
@@ -2801,8 +3039,32 @@
   </summary>
 </histogram>
 
+<histogram
+    name="PasswordManager.SavedGaiaPasswordHashCount2{SyncConsentStatus}"
+    units="count" expires_after="2023-03-26">
+  <owner>vsemeniuk@google.com</owner>
+  <owner>chrome-counter-abuse-alerts@google.com</owner>
+  <summary>
+    Records the number of Gaia password hashes that have been saved for password
+    reuse detection {SyncConsentStatus}. This is logged during the
+    initialization of the PasswordReuseManagerImpl class.
+  </summary>
+  <token key="SyncConsentStatus">
+    <variant name="" summary=""/>
+    <variant name=".SignedInNonSync"
+        summary="when the primary account for the profile does not have Sync
+                 consent"/>
+    <variant name=".Sync"
+        summary="when the primary account for the profile has Sync consent"/>
+  </token>
+</histogram>
+
 <histogram name="PasswordManager.SavedGaiaPasswordHashCount{SyncConsentStatus}"
     units="count" expires_after="2023-03-26">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>vsemeniuk@google.com</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -3063,6 +3325,10 @@
 
 <histogram name="PasswordManager.SyncingAccountState2"
     enum="PasswordManagerSyncingAccountState" expires_after="2023-04-30">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <owner>chrome-password-manager-metrics-alerts@google.com</owner>
@@ -3073,8 +3339,24 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.SyncingAccountState3"
+    enum="PasswordManagerSyncingAccountState" expires_after="2023-04-30">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <owner>chrome-password-manager-metrics-alerts@google.com</owner>
+  <summary>
+    Information about the user's current sync status crossed with whether their
+    synced password is saved. Recorded at most once per day for regular
+    profiles.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.SyncMetadataReadError"
     enum="PasswordSyncMetadataReadError" expires_after="2023-04-23">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>mamir@chromium.org</owner>
   <owner>mastiz@chromium.org</owner>
   <summary>
@@ -3083,6 +3365,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.SyncMetadataReadError2"
+    enum="PasswordSyncMetadataReadError" expires_after="2023-04-23">
+  <owner>mamir@chromium.org</owner>
+  <owner>mastiz@chromium.org</owner>
+  <summary>
+    This metric reports the error observed when trying to read the Sync metadata
+    from the password store during the start of Password sync. Recorded only if
+    password store was created.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.SyncPasswordHashChange"
     enum="GaiaPasswordHashChange" expires_after="2023-04-16">
   <owner>drubery@chromium.org</owner>
@@ -3224,12 +3517,16 @@
 </histogram>
 
 <histogram name="PasswordManager.UnifiedPasswordManager.ActiveStatus"
-    enum="UnifiedPasswordManagerActiveStatus" expires_after="M114">
+    enum="UnifiedPasswordManagerActiveStatus" expires_after="2023-03-19">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>fhorschig@chromium.org</owner>
   <owner>kazinova@google.com</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
-    Recorded on startup after the sync service is initialized and once per
+    Recorded on profile open after the sync service is initialized and once per
     profile. It is recorded for clients that have UPM enabled and logs whether
     UPM is actually active for them. Reasons why UPM might be inactive are:
     passwords sync off or client unenrolled due to unresolvable errors. Note a
@@ -3239,6 +3536,22 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.UnifiedPasswordManager.ActiveStatus2"
+    enum="UnifiedPasswordManagerActiveStatus" expires_after="M114">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>kazinova@google.com</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Recorded on profile open after the sync service is initialized and once per
+    regular profile. It is recorded for clients that have UPM enabled and logs
+    whether UPM is actually active for them. Reasons why UPM might be inactive
+    are: passwords sync off or client unenrolled due to unresolvable errors.
+    Note a client can have both sync off and be unenrolled, in which case it
+    will still only appear in the sync off bucket, since this is considered the
+    main reason why the client is inactive for UPM.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.UnifiedPasswordManager.WasMigrationDone"
     enum="BooleanSuccess" expires_after="M114">
   <owner>fhorschig@chromium.org</owner>
@@ -3405,6 +3718,10 @@
 <histogram
     name="PasswordManager.{Store}BlacklistedSitesHiRes2{CustomPassphraseStatus}"
     units="sites" expires_after="2023-05-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
@@ -3418,14 +3735,49 @@
   <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
 </histogram>
 
+<histogram
+    name="PasswordManager.{Store}BlacklistedSitesHiRes3{CustomPassphraseStatus}"
+    units="sites" expires_after="2023-05-01">
+  <owner>kazinova@google.com</owner>
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The total number of sites that the user has blocklisted in the password
+    manager's {Store}. Recorded by iterating over stored passwords at most once
+    per day for regular profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+  <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
+</histogram>
+
 <histogram name="PasswordManager.{Store}InaccessiblePasswords"
     units="saved passwords" expires_after="2023-06-26">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
+  <owner>derinel@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <owner>mamir@chromium.org</owner>
+  <summary>
+    The number of saved passwords that could not be decrypted in the password
+    manager's {Store}. Recorded once for the profile when it's opened.
+  </summary>
+  <token key="Store">
+    <variant name="" summary="profile-scoped store"/>
+    <variant name="AccountStore." summary="account-scoped store"/>
+  </token>
+</histogram>
+
+<histogram name="PasswordManager.{Store}InaccessiblePasswords2"
+    units="saved passwords" expires_after="2023-06-26">
   <owner>derinel@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
   <summary>
     The number of saved passwords that could not be decrypted in the password
-    manager's {Store}. Recorded once for the profile on startup.
+    manager's {Store}. Recorded once for the regular profile when it's opened.
   </summary>
   <token key="Store">
     <variant name="" summary="profile-scoped store"/>
@@ -3436,6 +3788,10 @@
 <histogram
     name="PasswordManager.{Store}PasswordNotes.CountCredentialsWithNonEmptyNotes"
     units="count" expires_after="2023-01-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>derinel@google.com</owner>
   <owner>mamir@chromium.org</owner>
   <summary>
@@ -3445,8 +3801,24 @@
   <token key="Store" variants="Store"/>
 </histogram>
 
+<histogram
+    name="PasswordManager.{Store}PasswordNotes.CountCredentialsWithNonEmptyNotes2"
+    units="count" expires_after="2023-01-01">
+  <owner>derinel@google.com</owner>
+  <owner>mamir@chromium.org</owner>
+  <summary>
+    Total number of credentials with non-empty notes in the password manager's
+    {Store}. Recorded at most once per day for regular profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+</histogram>
+
 <histogram name="PasswordManager.{Store}PasswordNotes.CountNotesPerCredential"
     units="count" expires_after="2023-01-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>derinel@google.com</owner>
   <owner>mamir@chromium.org</owner>
   <summary>
@@ -3457,9 +3829,25 @@
   <token key="Store" variants="Store"/>
 </histogram>
 
+<histogram name="PasswordManager.{Store}PasswordNotes.CountNotesPerCredential2"
+    units="count" expires_after="2023-01-01">
+  <owner>derinel@google.com</owner>
+  <owner>mamir@chromium.org</owner>
+  <summary>
+    Total number of notes attached to a password in the password manager's
+    {Store}. Recorded once for each credential at most once per day for regular
+    profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+</histogram>
+
 <histogram
     name="PasswordManager.{Store}TimesPasswordUsed2.{PasswordType}{CustomPassphraseStatus}"
     units="PasswordUses" expires_after="2023-06-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
@@ -3476,8 +3864,31 @@
   <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
 </histogram>
 
+<histogram
+    name="PasswordManager.{Store}TimesPasswordUsed3.{PasswordType}{CustomPassphraseStatus}"
+    units="PasswordUses" expires_after="2023-06-01">
+  <owner>kazinova@google.com</owner>
+  <owner>battre@chromium.org</owner>
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <summary>
+    The number of times each saved password from the {Store} has been used to
+    log in. Split by whether created by the user or generated by Chrome, and
+    further by whether the user used sync with custom passphrase or not.
+    Recorded by iterating over stored passwords soon after startup, at most once
+    per day for regular profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+  <token key="PasswordType" variants="PasswordType"/>
+  <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
+</histogram>
+
 <histogram name="PasswordManager.{Store}TotalAccountsHiRes2.WithScheme{Scheme}"
     units="accounts" expires_after="2023-11-30">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>battre@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
@@ -3492,9 +3903,29 @@
   <token key="Scheme" variants="Scheme"/>
 </histogram>
 
+<histogram name="PasswordManager.{Store}TotalAccountsHiRes3.WithScheme{Scheme}"
+    units="accounts" expires_after="2023-11-30">
+  <owner>battre@chromium.org</owner>
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    The number of accounts stored in the password manager's {Store} (across all
+    sites) for origins with the scheme (e.g., HTTP, HTTPS, FTP) as given in the
+    histogram suffix. For each scheme, the count is recorded at most once per
+    day for regular profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+  <token key="Scheme" variants="Scheme"/>
+</histogram>
+
 <histogram
     name="PasswordManager.{Store}{Metric2}.{PasswordType}{CustomPassphraseStatus}"
     units="units" expires_after="2023-05-01">
+  <obsolete>
+    Obsolete in M110 after PasswordStore is no longer created for non-regular,
+    guest, system and incognito profiles.
+  </obsolete>
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
@@ -3515,6 +3946,29 @@
   <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
 </histogram>
 
+<histogram
+    name="PasswordManager.{Store}{Metric3}.{PasswordType}{CustomPassphraseStatus}"
+    units="units" expires_after="2023-05-01">
+  <owner>kazinova@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <owner>mamir@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <owner>battre@chromium.org</owner>
+  <summary>
+    The number of accounts stored {Metric3} in the password manager's {Store}. ,
+    split by whether created by the user or generated by Chrome, and further by
+    whether the user use sync with custom passphrase or not. Recorded during
+    browser start-up, at most once per day for regular profiles.
+  </summary>
+  <token key="Store" variants="Store"/>
+  <token key="Metric3">
+    <variant name="AccountsPerSiteHiRes3" summary="per site"/>
+    <variant name="TotalAccountsHiRes3.ByType" summary="across all sites"/>
+  </token>
+  <token key="PasswordType" variants="PasswordType"/>
+  <token key="CustomPassphraseStatus" variants="CustomPassphraseStatus"/>
+</histogram>
+
 <histogram name="PasswordProtection.InterstitialAction"
     enum="PasswordProtectionWarningAction" expires_after="2023-05-14">
   <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index b2c2f743..6471604b 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -813,18 +813,6 @@
   </summary>
 </histogram>
 
-<histogram name="Power.BatteryDischargeMode2{UsageScenario}"
-    enum="BatteryDischargeMode" expires_after="2023-03-31">
-  <owner>etiennep@chromium.org</owner>
-  <owner>olivierli@chromium.org</owner>
-  <summary>
-    Battery discharge mode describing whether BatteryDischargeRate2 could be
-    reported or not, and why. This is recorded every 2 minutes for
-    {UsageScenario} (see go/chrome_power_use_per_scenario).
-  </summary>
-  <token key="UsageScenario" variants="UsageScenario"/>
-</histogram>
-
 <histogram name="Power.BatteryDischargeMode5{UsageScenario}{IntervalType}"
     enum="BatteryDischargeMode" expires_after="2023-03-31">
   <owner>etiennep@chromium.org</owner>
@@ -841,11 +829,6 @@
     This is recorded for {UsageScenario}.
 
     This contains {IntervalType}.
-
-    There are 2 differences with Power.BatteryDischargeRate2. 1: When possible,
-    the intervals are aligned with battery discharge notifications from the OS
-    (MacOS only for now), and 2: Intervals represents only 1 minute of Chrome
-    runtime (as opposed to 2 minutes).
   </summary>
   <token key="UsageScenario" variants="UsageScenario"/>
   <token key="IntervalType" variants="IntervalType"/>
@@ -861,23 +844,6 @@
   </summary>
 </histogram>
 
-<histogram name="Power.BatteryDischargeRate2{UsageScenario}"
-    units="hundredth of percent" expires_after="2023-03-31">
-  <owner>etiennep@chromium.org</owner>
-  <owner>olivierli@chromium.org</owner>
-  <owner>lgrey@chromium.org</owner>
-  <summary>
-    Battery discharge rate per minute, with 1/10000 of full charge resolution,
-    example: - Battery capacity = 4000 mAh; - Battery charge at the beginning of
-    the interval: 3900 mAh; - Battery charge at the end of the interval: 3700
-    mAh; - Discharge proportion: (3900-3700) / 4000 = 0.05 - Reported value:
-    500. This metric is only recorded when on battery power. This is reported on
-    Mac and Windows. This is recorded every 2 minutes for {UsageScenario} (see
-    go/chrome_power_use_per_scenario).
-  </summary>
-  <token key="UsageScenario" variants="UsageScenario"/>
-</histogram>
-
 <histogram
     name="Power.BatteryDischargeRateMilliwatts5{UsageScenario}{IntervalType}"
     units="milliwatts" expires_after="2023-03-31">
@@ -897,12 +863,6 @@
     This is recorded for {UsageScenario}.
 
     This contains {IntervalType}.
-
-    There are 3 differences with Power.BatteryDischargeRate2. 1: When possible,
-    the intervals are aligned with battery discharge notifications from the OS
-    (MacOS only for now), 2: Intervals represents only 1 minute of Chrome
-    runtime (as opposed to 2 minutes), and 3: The discharge rate is emitted in
-    milliwatts instead of hundredth of a percent.
   </summary>
   <token key="UsageScenario" variants="UsageScenario"/>
   <token key="IntervalType" variants="IntervalType"/>
@@ -929,11 +889,6 @@
     This is recorded for {UsageScenario}.
 
     This contains {IntervalType}.
-
-    There are 2 differences with Power.BatteryDischargeRate2. 1: When possible,
-    the intervals are aligned with battery discharge notifications from the OS
-    (MacOS only for now), and 2: Intervals represents only 1 minute of Chrome
-    runtime (as opposed to 2 minutes).
   </summary>
   <token key="UsageScenario" variants="UsageScenario"/>
   <token key="IntervalType" variants="IntervalType"/>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index cb86f5e6..cf35fca 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -1175,70 +1175,6 @@
 </histogram>
 
 <histogram
-    name="TabManager.Experimental.BackgroundTabOpening.CompressedPagesPerSecond"
-    units="pages/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of pages compressed per second when opening background tabs. This
-    is recorded at the end of the background tab opening session as an average
-    over the entire period (the duration of time from when the browser starts to
-    open background tabs until the time the browser has finished loading those
-    tabs or otherwise decided to stop loading them). The metric is not recorded
-    when the session overlaps with session restore. Only recorded on macOS.
-    Warning: This metric is a ratio and the session interval differs for each
-    session. It is hard to tell if it is average rate for each second in the
-    interval or it has a huge spike.
-  </summary>
-</histogram>
-
-<histogram
-    name="TabManager.Experimental.BackgroundTabOpening.DecompressedPagesPerSecond"
-    units="pages/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of pages decompressed per second when opening background tabs.
-    This is recorded at the end of the background tab opening session as an
-    average over the entire period (the duration of time from when the browser
-    starts to open background tabs until the time the browser has finished
-    loading those tabs or otherwise decided to stop loading them). The metric is
-    not recorded when the session overlaps with session restore. Only recorded
-    on macOS. Warning: This metric is a ratio and the session interval differs
-    for each session. It is hard to tell if it is average rate for each second
-    in the interval or it has a huge spike.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Experimental.BackgroundTabOpening.SwapInPerSecond"
-    units="swaps/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of swap-ins per second when opening background tabs. This is
-    recorded at the end of the background tab opening session as an average over
-    the entire period (the duration of time from when the browser starts to open
-    background tabs until the time the browser has finished loading those tabs
-    or otherwise decided to stop loading them). The metric is not recorded when
-    the session overlaps with session restore. Warning: This metric is a ratio
-    and the session interval differs for each session. It is hard to tell if it
-    is average rate for each second in the interval or it has a huge spike.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Experimental.BackgroundTabOpening.SwapOutPerSecond"
-    units="swaps/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of swap-outs per second when opening background tabs. This is
-    recorded at the end of the background tab opening session as an average over
-    the entire period (the duration of time from when the browser starts to open
-    background tabs until the time the browser has finished loading those tabs
-    or otherwise decided to stop loading them). The metric is not recorded when
-    the session overlaps with session restore. Warning: This metric is a ratio
-    and the session interval differs for each session. It is hard to tell if it
-    is average rate for each second in the interval or it has a huge spike.
-  </summary>
-</histogram>
-
-<histogram
     name="TabManager.Experimental.BackgroundTabOpening.TabSwitchLoadTime.UntilTabIsLoaded"
     units="ms" expires_after="M79">
   <owner>chrisha@chromium.org</owner>
@@ -1260,42 +1196,6 @@
 </histogram>
 
 <histogram
-    name="TabManager.Experimental.SessionRestore.CompressedPagesPerSecond"
-    units="pages/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of pages compressed per second during session restore. Recorded
-    at the end of session restore as an average over the entire period, defined
-    as the period of time when session restore is actively loading tabs, which
-    ends when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. The metric is not recorded when the session overlaps with
-    background tab opening session. Only recorded on macOS. Warning: This metric
-    is a ratio and the session interval differs for each session. It is hard to
-    tell if it is average rate for each second in the interval or it has a huge
-    spike.
-  </summary>
-</histogram>
-
-<histogram
-    name="TabManager.Experimental.SessionRestore.DecompressedPagesPerSecond"
-    units="pages/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of pages decompressed per second during session restore. Recorded
-    at the end of session restore as an average over the entire period, defined
-    as the period of time when session restore is actively loading tabs, which
-    ends when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. The metric is not recorded when the session overlaps with
-    background tab opening session. Only recorded on macOS. Warning: This metric
-    is a ratio and the session interval differs for each session. It is hard to
-    tell if it is average rate for each second in the interval or it has a huge
-    spike.
-  </summary>
-</histogram>
-
-<histogram
     name="TabManager.Experimental.SessionRestore.ForegroundTab.FirstContentfulPaint"
     units="ms" expires_after="M79">
   <owner>chrisha@chromium.org</owner>
@@ -1325,38 +1225,6 @@
   </summary>
 </histogram>
 
-<histogram name="TabManager.Experimental.SessionRestore.SwapInPerSecond"
-    units="swaps/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of swap-ins per second during session restore. Recorded at the
-    end of session restore as an average over the entire period, defined as the
-    period of time when session restore is actively loading tabs, which ends
-    when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. The metric is not recorded when the session overlaps with
-    background tab opening session. Warning: This metric is a ratio and the
-    session interval differs for each session. It is hard to tell if it is
-    average rate for each second in the interval or it has a huge spike.
-  </summary>
-</histogram>
-
-<histogram name="TabManager.Experimental.SessionRestore.SwapOutPerSecond"
-    units="swaps/s" expires_after="M79">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    The number of swap-outs per second during session restore. Recorded at the
-    end of session restore as an average over the entire period, defined as the
-    period of time when session restore is actively loading tabs, which ends
-    when either all tabs have been loaded and their pages rendered, or tab
-    loading needs to be deferred in cases where the system is under memory
-    pressure. The metric is not recorded when the session overlaps with
-    background tab opening session. Warning: This metric is a ratio and the
-    session interval differs for each session. It is hard to tell if it is
-    average rate for each second in the interval or it has a huge spike.
-  </summary>
-</histogram>
-
 <histogram
     name="TabManager.Experimental.SessionRestore.TabSwitchLoadTime.UntilTabIsLoaded"
     units="ms" expires_after="M79">
@@ -1428,19 +1296,6 @@
   </summary>
 </histogram>
 
-<histogram name="TabManager.SessionOverlap.SessionRestore"
-    enum="BooleanOverlap" expires_after="M77">
-  <owner>chrisha@chromium.org</owner>
-  <summary>
-    Whether session restore is overlapped with other types of session, e.g.,
-    background tab opening. Session restore is the duration from the time when
-    the browser starts to restore tabs until the time when the browser has
-    finished loading those tabs or when the browser stops loading tabs due to
-    memory pressure. This metric helps to understand how often session restore
-    has overlap with other sessions.
-  </summary>
-</histogram>
-
 <histogram name="TabManager.SessionRestore.SwitchToTab" enum="TabLoadingState"
     expires_after="M79">
   <owner>chrisha@chromium.org</owner>
diff --git a/tools/metrics/histograms/pretty_print.py b/tools/metrics/histograms/pretty_print.py
index d218fbb..ac99828b 100755
--- a/tools/metrics/histograms/pretty_print.py
+++ b/tools/metrics/histograms/pretty_print.py
@@ -197,8 +197,7 @@
                                         PrettyPrintEnums)
 
   elif 'histograms' in args.filepath:
-    # Specify the individual directory of histograms.xml or
-    # obsolete_histograms.xml.
+    # Specify the individual directory of histograms.xml.
     status = presubmit_util.DoPresubmit(
         sys.argv,
         args.filepath,
diff --git a/tools/metrics/histograms/split_xml.py b/tools/metrics/histograms/split_xml.py
index 234529f1..4ba9ef9 100644
--- a/tools/metrics/histograms/split_xml.py
+++ b/tools/metrics/histograms/split_xml.py
@@ -77,8 +77,7 @@
 
 def _ParseMergedXML():
   """Parses merged xml into different types of nodes"""
-  merged_histograms = merge_xml.MergeFiles(histogram_paths.HISTOGRAMS_XMLS +
-                                           [histogram_paths.OBSOLETE_XML])
+  merged_histograms = merge_xml.MergeFiles(histogram_paths.HISTOGRAMS_XMLS)
   histogram_nodes = merged_histograms.getElementsByTagName('histogram')
   variants_nodes = merged_histograms.getElementsByTagName('variants')
   histogram_suffixes_nodes = merged_histograms.getElementsByTagName(
@@ -277,27 +276,6 @@
   return document_dict
 
 
-def _SeparateObsoleteHistogram(histogram_nodes):
-  """Separates a NodeList of histograms into obsolete and non-obsolete.
-
-  Args:
-    histogram_nodes: A NodeList object containing histogram nodes.
-
-  Returns:
-    obsolete_nodes: A list of obsolete nodes.
-    non_obsolete_nodes: A list of non-obsolete nodes.
-  """
-  obsolete_nodes = []
-  non_obsolete_nodes = []
-  for histogram in histogram_nodes:
-    obsolete_tag_nodelist = histogram.getElementsByTagName('obsolete')
-    if len(obsolete_tag_nodelist) > 0:
-      obsolete_nodes.append(histogram)
-    else:
-      non_obsolete_nodes.append(histogram)
-  return obsolete_nodes, non_obsolete_nodes
-
-
 def SplitIntoMultipleHistogramXMLs(output_base_dir):
   """Splits a large histograms.xml and writes out the split xmls.
 
@@ -313,14 +291,7 @@
   _CreateXMLFile('histogram suffixes', 'histogram_suffixes_list',
                  histogram_suffixes_nodes, output_base_dir,
                  'histogram_suffixes_list.xml')
-
-  obsolete_nodes, non_obsolete_nodes = _SeparateObsoleteHistogram(
-      histogram_nodes)
-  # Create separate XML file for obsolete histograms.
-  _CreateXMLFile('obsolete histograms', 'histograms', obsolete_nodes,
-                 output_base_dir, 'obsolete_histograms.xml')
-
-  document_dict = _BuildDocumentDict(non_obsolete_nodes + variants_nodes, 0)
+  document_dict = _BuildDocumentDict(histogram_nodes + variants_nodes, 0)
 
   _WriteDocumentDict(document_dict, output_base_dir)
 
diff --git a/tools/metrics/histograms/suffixes_to_variants.py b/tools/metrics/histograms/suffixes_to_variants.py
index c608bbd3..1a141a8 100644
--- a/tools/metrics/histograms/suffixes_to_variants.py
+++ b/tools/metrics/histograms/suffixes_to_variants.py
@@ -297,9 +297,6 @@
       name = os.path.basename(os.path.dirname(path))
       if args.start <= name[0] <= args.end:
         paths.append(path)
-
-  if args.obsolete:
-    paths.append(histogram_paths.OBSOLETE_XML)
   return paths
 
 
@@ -349,9 +346,6 @@
   parser.add_argument('--end',
                       help='End migration at a certain character (inclusive).',
                       default='z')
-  parser.add_argument('--obsolete',
-                      help='Whether to migrate obsolete_histograms.xml',
-                      default=False)
   args = parser.parse_args()
   assert len(args.start) == 1 and len(args.end) == 1, (
       'start and end flag should only contain a single letter.')
diff --git a/tools/metrics/histograms/validate_format.py b/tools/metrics/histograms/validate_format.py
index 8e4b2756..7dca1148 100755
--- a/tools/metrics/histograms/validate_format.py
+++ b/tools/metrics/histograms/validate_format.py
@@ -22,10 +22,7 @@
 def CheckNamespaces():
   namespaces = {}
   has_errors = False
-  # Iterate over HISTOGRAMS_XMLS rather than ALL_XMLS because it's fine for
-  # histogram namespaces in obsolete_histograms.xml to also appear in
-  # non-obsolete histograms.xml files.
-  for path in histogram_paths.HISTOGRAMS_XMLS:
+  for path in histogram_paths.ALL_XMLS:
     tree = xml.dom.minidom.parse(path)
 
     def _GetNamespace(node):
diff --git a/tools/metrics/histograms/validate_obsolete_histograms.py b/tools/metrics/histograms/validate_obsolete_histograms.py
deleted file mode 100755
index bc84c772..0000000
--- a/tools/metrics/histograms/validate_obsolete_histograms.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2020 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Verifies that all the histograms in obsolete histograms XML are obsolete."""
-
-import logging
-import os
-import sys
-import xml.dom.minidom
-
-import extract_histograms
-import histogram_paths
-import split_xml
-
-
-def ValidateObsoleteXml():
-  """Checks that all the histograms in the obsolete file are obsolete.
-
-  Returns:
-    True if at least a histogram is not obsolete, False otherwise.
-  """
-  has_obsolete_error = False
-  tree = xml.dom.minidom.parse(histogram_paths.OBSOLETE_XML)
-
-  for node in extract_histograms.IterElementsWithTag(tree, 'histogram', 3):
-    obsolete_tag_nodelist = node.getElementsByTagName('obsolete')
-    if len(obsolete_tag_nodelist) > 0:
-      continue
-
-    has_obsolete_error = True
-    # If histogram is not obsolete, find out the directory that it should be
-    # placed in.
-    correct_dir = split_xml.GetDirForNode(node)
-    histogram_name = node.getAttribute('name')
-
-    logging.error(
-        'Histogram of name %s is not obsolete, please move it to the '
-        'metadata/%s directory.', histogram_name, correct_dir)
-
-  return has_obsolete_error
-
-
-if __name__ == '__main__':
-  sys.exit(ValidateObsoleteXml())
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index ebbc952..0dfa1c673 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@
         },
         "win": {
             "hash": "ac865f031812fd089c0f6f62b177687fea2483fd",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/d74cb19ee888e97725e7dd9b051d558a7aaf4bda/trace_processor_shell.exe"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/31d7f4d96753a1a7e9a04b733e8e7e66fb8e2221/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
@@ -14,7 +14,7 @@
         },
         "mac": {
             "hash": "962d7d09b1bfec0adede446e816481ba44919bb9",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/d74cb19ee888e97725e7dd9b051d558a7aaf4bda/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/31d7f4d96753a1a7e9a04b733e8e7e66fb8e2221/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "92318bea34f5c9beec69d2d826a9a92ec9d3cdcd",
diff --git a/tools/rust/README.md b/tools/rust/README.md
index b31e3d8..879e763 100644
--- a/tools/rust/README.md
+++ b/tools/rust/README.md
@@ -7,14 +7,142 @@
 [TOC]
 
 
-## Rolling Rust compiler and other Rust tools
+## Background
 
-Steps to roll the Rust compiler (and other Rust tools like `rustfmt`) to
-a new version:
-- Locally, update `RUST_REVISION` in `update_rust.py`.
-  (Update `RUST_SUB_REVISION` when the build or packaging is changed, but
-  the upstream Rust revision we build from is not changed.)
-- Follow the general roll process below
+Like with Clang, Chromium uses bleeding edge Rust tooling. We track the upstream
+projects' latest development as closely as possible. However, Chromium cannot
+use official Rust builds for various reasons which require us to match the Rust
+LLVM backend version with the Clang we use. 
+
+It would not be reasonable to build the tooling for every Chromium build, so we
+build it centrally (with the scripts here) and distribute it for all to use
+(also fetched with the scripts here).
+
+
+## Rust build overview
+
+Each Rust package is built from an official Rust nightly source release and a
+corresponding LLVM revision. Hence a new Rust package must be built whenever
+either Rust or Clang is updated.
+
+Chromium's Clang build process leaves behind several artifacts needed for the
+Rust build. Each Rust build begins after a Clang build and uses these artifacts,
+which include `clang`, LLVM libraries, etc.
+
+A special CI job is used to build Clang and Rust from the revisions specified in
+the Chromium source tree. These are uploaded to a storage bucket. After being
+manually blessed by a developer, they can then be fetched by Chromium checkouts.
+
+Scripts are provided in tree to fetch the packages for the specified revisions.
+
+Whenever a Chromium checkout is updated, `gclient` hooks will update the
+toolchain packages to match the revisions listed in tree.
+
+
+## Updating Rust
+
+### Set the revision
+
+First, pick a new instance of the [CIPD `rust_src`
+package](https://chrome-infra-packages.appspot.com/p/chromium/third_party/rust_src/+/).
+Click it and copy the version ID (e.g. `version:2@2022-01-01`) to the `//DEPS` entry for
+`src/third_party/rust_src/src`. For example (though don't change the other parts
+of the entry):
+
+```
+  'src/third_party/rust_src/src': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/rust_src',
+        'version': 'version:2@2022-01-01',
+      },
+    ],
+    'dep_type': 'cipd',
+    'condition': 'checkout_rust_toolchain_deps or use_rust',
+  },
+```
+
+Similarly, update the `RUST_REVISION` named in `//tools/rust/update_rust.py`,
+removing dashes from the date (e.g. `version:2@2022-01-01` becomes
+`RUST_REVISION = '20220101'`). Reset `RUST_SUB_REVISION = 1`.
+
+Run the following to check for changes to Rust's `src/stage0.json`, which
+contains revisions of upstream binaries to be fetched and used in the Rust
+build:
+
+```
+tools/rust/build_rust.py --verify-stage0-hash
+```
+
+If it exists without printing anything, the stage0 hash is up-to-date and
+nothing needs to be done. Otherwise, it will print the actual hash like so:
+
+```
+...
+Actual hash:   6b1c61d494ad447f41c8ae3b9b3239626eecac00e0f0b793b844e0761133dc37
+...
+```
+
+...in which case you should check the `stage0.json` changes for trustworthiness
+(criteria TBD) and then update `STAGE0_JSON_SHA256` in update_rust.py with the
+new hash. Re-run the above and confirm it succeeds.
+
+
+### Optional: build locally and run tests
+
+This step is not strictly necessary since the CI tooling will catch any errors.
+But the CI build process is slow and this can save some time.
+
+Running this will do a full build and provide a local toolchain that works for
+the host machine, albeit not the same as the CI-provided one:
+
+```
+tools/rust/build_rust.py --fetch-llvm-libs --use-final-llvm-build-dir
+```
+
+To do a full build, first build Clang locally (TODO: provide instructions) then
+simply run `tools/rust/build_rust.py` with no arguments.
+
+However, for most cases simply doing
+
+```
+tools/rust/build_rust.py --fetch-llvm-libs --use-final-llvm-build-dir --run-xpy -- build --stage 1 library/std
+```
+
+will catch most errors and will be fast.
+
+### Upload CL and build package
+
+Upload a CL with the changes, which in the simplest case will only have two
+changes: one line in `//DEPS`, one line in `//tools/rust/update_rust.py`. Add the
+following line to the end of the CL description, which ensures the new toolchain
+will be tested on appropriate Rust tryjobs:
+
+```
+Cq-Include-Trybots: luci.chromium.try:android-rust-arm-dbg,android-rust-arm-rel,linux-rust-x64-dbg,linux-rust-x64-rel
+```
+
+From Gerrit run the `linux_upload_clang` tryjob on the CL and wait for it to
+finish. Check that it's successful; it is **not** sufficient to check the
+result in Gerrit as a Rust failure will not surface here. Check the build page
+(e.g.
+https://ci.chromium.org/ui/p/chromium/builders/try/linux_upload_clang/2611/overview)
+and confirm the "package rust" step succeeded. If it did not, further
+investigation is needed.
+
+After the package is built, a developer with permissions must bless the package
+for use. As of writing this is anyone in [Clang
+OWNERS](/tools/clang/scripts/OWNERS) or collinbaker@chromium.org.
+
+
+### Submit CL
+
+Once the package has been uploaded and blessed, it is ready to be fetched from
+any Chromium checkout.
+
+Submit the CL. CQ tryjobs will use the specified toolchain package
+version. Any build failures will need to be investigated, as these indicate
+breaking changes to Rust.
 
 
 ## Rolling Crubit tools
@@ -35,35 +163,6 @@
   be made obsolete once Rust-specific tryjobs cover Crubit
   tests.
 
-- Follow the general roll process below
-
-
-## General roll process
-
-- Author a CL that updates `CRUBIT_REVISION` and/or `RUST_REVISION`
-  (see one of the sections above for details).
-
-- Upload the CL to Gerrit.
-  Ask [CQ](//docs/infra/cq.md) for Rust-specific tryjobs in the CL description:
-  `Cq-Include-Trybots: luci.chromium.try:linux-rust-x64-rel,linux-rust-x64-dbg,android-rust-arm-rel,android-rust-arm-dbg`.
-
-- Run `linux_upload_clang` tryjob.  This will run `package_rust.py` which will
-  `build_rust.py` and then upload a new version of the Rust toolchain package to
-  the staging bucket.  This step runs `build_crubit.py` but doesn't (yet) package
-  the built binaries.
-  TODO(https://crbug.com/1329611): Update the docs once Crubit also gets packaged.
-
-- Move the new toolchain package from staging to prod.
-  (A small set of people have the permission for this.  There are
-  some Google-internal docs with more details.)
-
-- Run CQ (see also `Cq-Include-Trybots` suggested above).
-  This step will test that `gclient sync` can fetch the new Rust toolchain
-  package + that the new package works fine in Chromium build.
-
-- Land the CL.  The new package won't be used outside of this CL
-  until this step.
-
 
 ## Building and testing the tools locally
 
diff --git a/tools/rust/update_rust.py b/tools/rust/update_rust.py
index af236146..5d96d70 100755
--- a/tools/rust/update_rust.py
+++ b/tools/rust/update_rust.py
@@ -45,7 +45,7 @@
 # This should almost always be None. When a breakage happens the fallback should
 # be temporary. Once fixed, the applicable revision(s) above should be updated
 # and FALLBACK_CLANG_VERSION should be reset to None.
-FALLBACK_CLANG_VERSION = None
+FALLBACK_CLANG_VERSION = 'llvmorg-16-init-9369-g87a20868-1'
 
 # Hash of src/stage0.json, which itself contains the stage0 toolchain hashes.
 # We trust the Rust build system checks, but to ensure it is not tampered with
diff --git a/ui/chromeos/strings/network/network_element_localized_strings_provider.cc b/ui/chromeos/strings/network/network_element_localized_strings_provider.cc
index f7bb865e..f1d4233 100644
--- a/ui/chromeos/strings/network/network_element_localized_strings_provider.cc
+++ b/ui/chromeos/strings/network/network_element_localized_strings_provider.cc
@@ -315,6 +315,7 @@
       {"apnMenuDisable", IDS_SETTINGS_APN_MENU_DISABLE},
       {"apnMenuRemove", IDS_SETTINGS_APN_MENU_REMOVE},
       {"apnMoreActionsTitle", IDS_SETTINGS_APN_MORE_ACTIONS_TITLE},
+      {"apnDetailAddApnDialogTitle", IDS_SETTINGS_ADD_APN_DIALOG_TITLE},
       {"hidePassword", IDS_SETTINGS_PASSWORD_HIDE},
       {"showPassword", IDS_SETTINGS_PASSWORD_SHOW},
       {"networkProxy", IDS_SETTINGS_INTERNET_NETWORK_PROXY_PROXY},
diff --git a/ui/chromeos/styles/cros_sys_colors.json5 b/ui/chromeos/styles/cros_sys_colors.json5
index f601511..87f9c8f 100644
--- a/ui/chromeos/styles/cros_sys_colors.json5
+++ b/ui/chromeos/styles/cros_sys_colors.json5
@@ -126,7 +126,8 @@
     },
     'app-base-elevated': {
       light: '$cros.ref.neutralvariant100',
-      dark:  'blend(rgba($black.rgb, 0.4), $cros.ref.neutral10)',
+      /* In dark mode we layer primary80 @ 11% ontop of neutral80 @ 2% ontop of neutral 10. */
+      dark: 'blend(rgba($cros.ref.primary80.rgb, .11), blend(rgba($cros.ref.neutral80.rgb, .02), $cros.ref.neutral10))',
       generate_per_mode: true,
     },
 
diff --git a/ui/color/color_id.h b/ui/color/color_id.h
index 524f145..b00b229 100644
--- a/ui/color/color_id.h
+++ b/ui/color/color_id.h
@@ -240,11 +240,6 @@
   E_CPONLY(kColorOverlayScrollbarStrokeHoveredLight) \
   E_CPONLY(kColorProgressBar) \
   E_CPONLY(kColorProgressBarPaused) \
-  E_CPONLY(kColorReadAnythingBackground) \
-  E_CPONLY(kColorReadAnythingBackgroundDark) \
-  E_CPONLY(kColorReadAnythingBackgroundLight) \
-  E_CPONLY(kColorReadAnythingBackgroundYellow) \
-  E_CPONLY(kColorReadAnythingForeground) \
   E_CPONLY(kColorReadAnythingForegroundDark) \
   E_CPONLY(kColorReadAnythingForegroundLight) \
   E_CPONLY(kColorReadAnythingForegroundYellow) \
diff --git a/ui/color/ui_color_mixer.cc b/ui/color/ui_color_mixer.cc
index c2bf7af..51e008a 100644
--- a/ui/color/ui_color_mixer.cc
+++ b/ui/color/ui_color_mixer.cc
@@ -154,15 +154,6 @@
                gfx::kGoogleGreyAlpha500);
   mixer[kColorProgressBarPaused] = {kColorDisabledForeground};
   mixer[kColorProgressBar] = {kColorAccent};
-  mixer[kColorReadAnythingBackground] = {
-      dark_mode ? kColorReadAnythingBackgroundDark
-                : kColorReadAnythingBackgroundLight};
-  mixer[kColorReadAnythingBackgroundDark] = {gfx::kGoogleGrey900};
-  mixer[kColorReadAnythingBackgroundLight] = {gfx::kGoogleGrey050};
-  mixer[kColorReadAnythingBackgroundYellow] = {gfx::kGoogleYellow200};
-  mixer[kColorReadAnythingForeground] = {
-      dark_mode ? kColorReadAnythingForegroundDark
-                : kColorReadAnythingForegroundLight};
   mixer[kColorReadAnythingForegroundDark] = {gfx::kGoogleGrey200};
   mixer[kColorReadAnythingForegroundLight] = {gfx::kGoogleGrey800};
   mixer[kColorReadAnythingForegroundYellow] = {gfx::kGoogleGrey800};
diff --git a/ui/compositor/test/test_utils.cc b/ui/compositor/test/test_utils.cc
index 9e558a3..94f0598e 100644
--- a/ui/compositor/test/test_utils.cc
+++ b/ui/compositor/test/test_utils.cc
@@ -54,13 +54,12 @@
                                    absl::optional<base::TimeDelta> timeout) {
   bool frames_presented = false;
   base::RunLoop runloop;
-  base::CancelableOnceCallback<void(const gfx::PresentationFeedback&)>
-      cancelable_callback(base::BindLambdaForTesting(
-          [&](const gfx::PresentationFeedback& feedback) {
-            frames_presented = true;
-            runloop.Quit();
-          }));
-  compositor->RequestPresentationTimeForNextFrame(
+  base::CancelableOnceCallback<void(base::TimeTicks)> cancelable_callback(
+      base::BindLambdaForTesting([&](base::TimeTicks presentation_timestamp) {
+        frames_presented = true;
+        runloop.Quit();
+      }));
+  compositor->RequestSuccessfulPresentationTimeForNextFrame(
       cancelable_callback.callback());
 
   absl::optional<base::OneShotTimer> timer;
diff --git a/ui/display/manager/display_configurator_unittest.cc b/ui/display/manager/display_configurator_unittest.cc
index 26e0623..d601c49d 100644
--- a/ui/display/manager/display_configurator_unittest.cc
+++ b/ui/display/manager/display_configurator_unittest.cc
@@ -1005,6 +1005,48 @@
   EXPECT_EQ(outputs_[1]->current_mode(), cached[1]->current_mode());
 }
 
+TEST_F(DisplayConfiguratorTest, VerifyInternalPanelIsAtTheTopOfTheList) {
+  InitWithOutputs(&small_mode_);
+
+  // Initialize with 3 displays where the internal panel is not at the top of
+  // the display list.
+  outputs_[0] = FakeDisplaySnapshot::Builder()
+                    .SetId(1L)
+                    .SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
+                    .SetNativeMode(big_mode_.Clone())
+                    .Build();
+  outputs_[1] = FakeDisplaySnapshot::Builder()
+                    .SetId(2L)
+                    .SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
+                    .SetNativeMode(small_mode_.Clone())
+                    .Build();
+  outputs_[2] = FakeDisplaySnapshot::Builder()
+                    .SetId(3L)
+                    .SetType(DISPLAY_CONNECTION_TYPE_HDMI)
+                    .SetNativeMode(big_mode_.Clone())
+                    .Build();
+
+  native_display_delegate_->set_max_configurable_pixels(
+      big_mode_.size().GetArea());
+  UpdateOutputs(3, true);
+
+  // We expect the internal display to be at the top of DisplayConfigurator's
+  // |cached_displays_| list post configuration. The rest of the display should
+  // be in the original order from DRM.
+  const DisplayConfigurator::DisplayStateList& cached =
+      configurator_.cached_displays();
+  ASSERT_EQ(cached.size(), 3U);
+
+  EXPECT_EQ(cached[0]->display_id(), 2L);
+  EXPECT_EQ(cached[0]->type(), DISPLAY_CONNECTION_TYPE_INTERNAL);
+
+  EXPECT_EQ(cached[1]->display_id(), 1L);
+  EXPECT_EQ(cached[1]->type(), DISPLAY_CONNECTION_TYPE_DISPLAYPORT);
+
+  EXPECT_EQ(cached[2]->display_id(), 3L);
+  EXPECT_EQ(cached[2]->type(), DISPLAY_CONNECTION_TYPE_HDMI);
+}
+
 TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) {
   InitWithOutputs(&small_mode_);
 
diff --git a/ui/display/manager/update_display_configuration_task.cc b/ui/display/manager/update_display_configuration_task.cc
index 9230a5a..0edfb6b 100644
--- a/ui/display/manager/update_display_configuration_task.cc
+++ b/ui/display/manager/update_display_configuration_task.cc
@@ -37,6 +37,29 @@
   // No internal displays
   return false;
 }
+
+// Move all internal panel displays to the front of the display list. Otherwise,
+// the list remains in order.
+void MoveInternalDisplaysToTheFront(std::vector<DisplaySnapshot*>& displays) {
+  DisplayConfigurator::DisplayStateList sorted_displays;
+
+  // First pass for internal panels.
+  for (DisplaySnapshot* display : displays) {
+    if (display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
+      sorted_displays.push_back(display);
+  }
+
+  // Second pass for the rest.
+  for (DisplaySnapshot* display : displays) {
+    if (display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
+      continue;
+
+    sorted_displays.push_back(display);
+  }
+
+  displays.swap(sorted_displays);
+}
+
 }  // namespace
 
 UpdateDisplayConfigurationTask::UpdateDisplayConfigurationTask(
@@ -89,6 +112,7 @@
 void UpdateDisplayConfigurationTask::OnDisplaysUpdated(
     const std::vector<DisplaySnapshot*>& displays) {
   cached_displays_ = displays;
+  MoveInternalDisplaysToTheFront(cached_displays_);
   requesting_displays_ = false;
 
   // If the user hasn't requested a display state, update it using the requested
diff --git a/ui/display/screen.h b/ui/display/screen.h
index 6589747..fb589cd5 100644
--- a/ui/display/screen.h
+++ b/ui/display/screen.h
@@ -121,7 +121,7 @@
   Display GetDisplayForNewWindows() const;
 
   // Sets the suggested display to use when creating a new window.
-  void SetDisplayForNewWindows(int64_t display_id);
+  virtual void SetDisplayForNewWindows(int64_t display_id);
 
   // Returns ScreenInfos, attempting to set the current ScreenInfo to the
   // display corresponding to `nearest_id`.  The returned result is guaranteed
@@ -203,6 +203,9 @@
 
  protected:
   void set_shutdown(bool shutdown) { shutdown_ = shutdown; }
+  int64_t display_id_for_new_windows() const {
+    return display_id_for_new_windows_;
+  }
 
  private:
   friend class ScopedDisplayForNewWindows;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index ee00b6a..340d4f3 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -285,7 +285,6 @@
 
 #directory-tree .tree-item[disabled] > .tree-row {
   cursor: default;
-  opacity: var(--cros-disabled-opacity);
 }
 
 #directory-tree .tree-row > .align-right-icon {
@@ -1952,7 +1951,10 @@
 body[type='folder'] .file,
 body[type='upload-folder'] .file,
 .dialog-container[connection='OFFLINE'] .dim-offline,
-body[block-hosted-docs] .file.dim-hosted {
+body[block-hosted-docs] .file.dim-hosted,
+.thumbnail-grid [disabled],
+#detail-table [disabled],
+#directory-tree .tree-item[disabled] > .tree-row {
   opacity: var(--cros-disabled-opacity);
 }
 
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
index 9de320c9..d9d7b89 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
@@ -288,7 +288,6 @@
 
 #directory-tree .tree-item[disabled] > .tree-row {
   cursor: default;
-  opacity: var(--cros-disabled-opacity);
 }
 
 #directory-tree .tree-row > .align-right-icon {
@@ -1926,7 +1925,10 @@
 body[type='folder'] .file,
 body[type='upload-folder'] .file,
 .dialog-container[connection='OFFLINE'] .dim-offline,
-body[block-hosted-docs] .file.dim-hosted {
+body[block-hosted-docs] .file.dim-hosted,
+.thumbnail-grid [disabled],
+#detail-table [disabled],
+#directory-tree .tree-item[disabled] > .tree-row {
   opacity: var(--cros-disabled-opacity);
 }
 
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
index 21672ef..ffa5a9b 100644
--- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -408,7 +408,8 @@
     if (this.dialogType_ === DialogType.SELECT_SAVEAS_FILE) {
       if (selection.directoryCount === 1 && selection.fileCount === 0) {
         this.dialogFooter_.okButtonLabel.textContent = str('OPEN_LABEL');
-        this.dialogFooter_.okButton.disabled = false;
+        this.dialogFooter_.okButton.disabled =
+            this.fileSelectionHandler_.isDlpBlocked();
       } else {
         this.dialogFooter_.okButtonLabel.textContent = str('SAVE_LABEL');
         this.dialogFooter_.okButton.disabled =
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js
index 58fc43b..5c6f71f 100644
--- a/ui/file_manager/file_manager/foreground/js/file_selection.js
+++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -312,6 +312,41 @@
     return this.allowedPaths_ !== AllowedPaths.ANY_PATH_OR_URL &&
         this.selection.anyFilesHosted;
   }
+
+  /**
+   * Returns true if any file/directory in the selection is blocked by DLP
+   * policy.
+   * @return {boolean}
+   */
+  isDlpBlocked() {
+    const selectedIndexes =
+        this.directoryModel_.getFileListSelection().selectedIndexes;
+    const selectedEntries = selectedIndexes.map(index => {
+      return /** @type {!Entry} */ (
+          this.directoryModel_.getFileList().item(index));
+    });
+
+    for (const entry of selectedEntries) {
+      if (!entry.isDirectory) {
+        // TODO(b/259183224): Add proper checks; files are blocked if their
+        // source is not allowed to be opened by the files app dialog caller.
+        return false;
+      }
+      // The entry is a directory, which can only be blocked if it's a
+      // disabled volume/DLP component.
+      // TODO(b/259184588): Properly handle case when VolumeInfo is not
+      // available. E.g. for Crostini we might not have VolumeInfo before it's
+      // mounted.
+      const volumeInfo = this.volumeManager_.getVolumeInfo(entry);
+      if (!volumeInfo) {
+        continue;
+      }
+      if (this.volumeManager_.isDisabled(volumeInfo.volumeType)) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js
index 708e0f2..f4036e5 100644
--- a/ui/file_manager/file_manager/foreground/js/main_window_component.js
+++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -261,6 +261,11 @@
       this.showFailedToOpenTrashItemDialog_(trashEntries);
       return false;
     }
+    // If the selection is blocked by DLP restrictions, we don't allow to change
+    // directory or the default action.
+    if (this.selectionHandler_.isDlpBlocked()) {
+      return false;
+    }
     const entry = selection.entries[0];
     if (entry.isDirectory) {
       this.directoryModel_.changeDirectoryEntry(
@@ -455,20 +460,28 @@
         break;
 
       case 'Enter':  // Enter => Change directory or perform default action.
+                     // If the selection is blocked by DLP restrictions, we
+                     // don't allow to
+        // change directory or the default action.
+        if (this.selectionHandler_.isDlpBlocked()) {
+          break;
+        }
         const selection = this.selectionHandler_.selection;
         if (selection.totalCount === 1 && selection.entries[0].isDirectory &&
             !isFolderDialogType(this.dialogType_) &&
             !selection.entries.some(util.isTrashEntry)) {
           const item = this.ui_.listContainer.currentList.getListItemByIndex(
               selection.indexes[0]);
-          // If the item is in renaming process, we don't allow to change
+          // If the item is in renaming process we don't allow to change
           // directory.
           if (item && !item.hasAttribute('renaming')) {
             event.preventDefault();
             this.directoryModel_.changeDirectoryEntry(
                 /** @type {!DirectoryEntry} */ (selection.entries[0]));
           }
-        } else if (this.acceptSelection_()) {
+          break;
+        }
+        if (this.acceptSelection_()) {
           event.preventDefault();
         }
         break;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
index dfe5320..e33a6c8 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -465,6 +465,7 @@
     "//ui/file_manager/file_manager/common/js:util",
     "//ui/file_manager/file_manager/externs:entry_location",
     "//ui/file_manager/file_manager/externs:files_app_entry_interfaces",
+    "//ui/file_manager/file_manager/externs:volume_manager",
     "//ui/file_manager/file_manager/foreground/js:file_list_model",
     "//ui/file_manager/file_manager/foreground/js/metadata:metadata_model",
     "//ui/webui/resources/js:assert",
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
index 85ded4a..6831b0e1 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -774,7 +774,8 @@
   decorateThumbnail_(li, entry) {
     li.className = 'thumbnail-item';
     if (entry) {
-      filelist.decorateListItem(li, entry, assert(this.metadataModel_));
+      filelist.decorateListItem(
+          li, entry, assert(this.metadataModel_), assert(this.volumeManager_));
     }
 
     const frame = li.ownerDocument.createElement('div');
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
index e366229..23caf9df 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -1018,7 +1018,8 @@
     const typeId = item.id + '-type';
     const dateId = item.id + '-date';
     const dlpId = item.id + '-dlp-managed-icon';
-    filelist.decorateListItem(item, entry, assert(this.metadataModel_));
+    filelist.decorateListItem(
+        item, entry, assert(this.metadataModel_), assert(this.volumeManager_));
     item.setAttribute('file-name', entry.name);
     item.querySelector('.detail-name').setAttribute('id', nameId);
     item.querySelector('.size').setAttribute('id', sizeId);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
index 69524a3..7aa5c7ce 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -8,6 +8,7 @@
 import {str, strf, util} from '../../../common/js/util.js';
 import {EntryLocation} from '../../../externs/entry_location.js';
 import {FilesAppEntry} from '../../../externs/files_app_entry_interfaces.js';
+import {VolumeManager} from '../../../externs/volume_manager.js';
 import {FileListModel} from '../file_list_model.js';
 import {MetadataModel} from '../metadata/metadata_model.js';
 
@@ -346,9 +347,10 @@
  * @param {ListItem} li List item.
  * @param {Entry|FilesAppEntry} entry The entry.
  * @param {!MetadataModel} metadataModel Cache to
- *     retrieve metadada.
+ *     retrieve metadata.
+ * @param {!VolumeManager} volumeManager Used to retrieve VolumeInfo.
  */
-filelist.decorateListItem = (li, entry, metadataModel) => {
+filelist.decorateListItem = (li, entry, metadataModel, volumeManager) => {
   li.classList.add(entry.isDirectory ? 'directory' : 'file');
   // The metadata may not yet be ready. In that case, the list item will be
   // updated when the metadata is ready via updateListItemsMetadata. For files
@@ -369,6 +371,7 @@
   // Overriding the default role 'list' to 'listbox' for better
   // accessibility on ChromeOS.
   li.setAttribute('role', 'option');
+  li.toggleAttribute('disabled', filelist.isDlpBlocked_(entry, volumeManager));
 
   Object.defineProperty(li, 'selected', {
     /**
@@ -393,6 +396,30 @@
 };
 
 /**
+ * Returns true if `entry` is blocked by DLP.
+ * @param {Entry|FilesAppEntry} entry The entry.
+ * @param {!VolumeManager} volumeManager Used to retrieve VolumeInfo.
+ * @return {boolean}
+ */
+filelist.isDlpBlocked_ = (entry, volumeManager) => {
+  if (!entry.isDirectory) {
+    // TODO(b/259183224): Add proper checks; files are blocked if their source
+    // is not allowed to be opened by the files app dialog caller.
+    return false;
+  }
+  // The entry is a directory, which can only be blocked if it's a
+  // disabled volume/DLP component.
+  // TODO(b/259184588): Properly handle case when VolumeInfo is not
+  // available. E.g. for Crostini we might not have VolumeInfo before it's
+  // mounted.
+  const volumeInfo = volumeManager.getVolumeInfo(assert(entry));
+  if (!volumeInfo) {
+    return false;
+  }
+  return volumeManager.isDisabled(volumeInfo.volumeType);
+};
+
+/**
  * Render the type column of the detail table.
  * @param {!Document} doc Owner document.
  * @param {!Entry} entry The Entry object to render.
diff --git a/ui/file_manager/integration_tests/file_manager/dlp.js b/ui/file_manager/integration_tests/file_manager/dlp.js
index 17270d2..c5eca44 100644
--- a/ui/file_manager/integration_tests/file_manager/dlp.js
+++ b/ui/file_manager/integration_tests/file_manager/dlp.js
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {ENTRIES, RootPath, sendTestMessage} from '../test_util.js';
+import {addEntries, ENTRIES, RootPath, sendTestMessage} from '../test_util.js';
 import {testcase} from '../testcase.js';
 
-import {navigateWithDirectoryTree, remoteCall, setupAndWaitUntilReady} from './background.js';
+import {navigateWithDirectoryTree, openAndWaitForClosingDialog, remoteCall, setupAndWaitUntilReady} from './background.js';
 import {BASIC_LOCAL_ENTRY_SET} from './test_data.js';
 
 
@@ -110,3 +110,70 @@
           ' [command="#dlp-restriction-details"]' +
           ':not([hidden]):not([disabled])');
 };
+
+/**
+ * Tests the save dialogs properly show DLP blocked volumes/directories. If a
+ * volume is blocked by DLP, it should be marked as disabled both in the
+ * navigation list and in the details list. If such a volume is selected, the
+ * "Open" dialog button should be disabled, i.e. changing the directory is
+ * prevented.
+ */
+testcase.saveAsDlpRestrictedDirectory = async () => {
+  // Setup the restrictions.
+  await sendTestMessage({name: 'setBlockedComponents'});
+
+  const type = {type: 'saveFile'};
+
+  const okButton = '.button-panel button.ok:enabled';
+  const disabledOkButton = '.button-panel button.ok:disabled';
+  const cancelButton = '.button-panel button.cancel';
+
+  // Add entries to Downloads.
+  await addEntries(['local'], [ENTRIES.hello]);
+
+  const closer = async (dialog) => {
+    // Verify that the button is enabled when a file is selected.
+    await remoteCall.waitUntilSelected(dialog, ENTRIES.hello.targetPath);
+    await remoteCall.waitForElement(dialog, okButton);
+
+    // Select My Files folder and wait for file list to display Downloads, Play
+    // files, and Linux files.
+    const myFilesQuery = '#directory-tree [entry-label="My files"]';
+    const isDriveQuery = false;
+    chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+        'selectInDirectoryTree', dialog, [myFilesQuery, isDriveQuery]));
+
+    // Wait for file list to display Downloads, Android, and Crostini.
+    const downloadsRow = ['Downloads', '--', 'Folder'];
+    const playFilesRow = ['Play files', '--', 'Folder'];
+    const linuxFilesRow = ['Linux files', '--', 'Folder'];
+    await remoteCall.waitForFiles(
+        dialog, [downloadsRow, playFilesRow, linuxFilesRow],
+        {ignoreFileSize: true, ignoreLastModifiedTime: true});
+
+    // Only one directory, Android files, should be disabled, both as the tree
+    // item and the directory in the main list.
+    const directoryFileList = '.directory[disabled]';
+    const directoryTreeQuery = '.tree-item[disabled]';
+    await remoteCall.waitForElementsCount(dialog, [directoryFileList], 1);
+    await remoteCall.waitForElementsCount(dialog, [directoryTreeQuery], 1);
+
+    // Verify that the button is enabled when a non-blocked volume is selected.
+    await remoteCall.waitUntilSelected(dialog, 'Downloads');
+    await remoteCall.waitForElement(dialog, okButton);
+
+    // Verify that the button is disabled when a blocked volume is selected.
+    await remoteCall.waitUntilSelected(dialog, 'Play files');
+    await remoteCall.waitForElement(dialog, disabledOkButton);
+
+    // Click the close button to dismiss the dialog.
+    await remoteCall.waitForElement(dialog, cancelButton);
+    const event = [cancelButton, 'click'];
+    await remoteCall.callRemoteTestUtil('fakeEvent', dialog, event);
+  };
+
+  chrome.test.assertEq(
+      undefined,
+      await openAndWaitForClosingDialog(
+          type, 'downloads', [ENTRIES.hello], closer));
+};
diff --git a/ui/gfx/geometry/axis_transform2d.h b/ui/gfx/geometry/axis_transform2d.h
index ecb2aff..e950e82 100644
--- a/ui/gfx/geometry/axis_transform2d.h
+++ b/ui/gfx/geometry/axis_transform2d.h
@@ -36,10 +36,10 @@
     return AxisTransform2d(scale, translation);
   }
 
-  bool operator==(const AxisTransform2d& other) const {
+  constexpr bool operator==(const AxisTransform2d& other) const {
     return scale_ == other.scale_ && translation_ == other.translation_;
   }
-  bool operator!=(const AxisTransform2d& other) const {
+  constexpr bool operator!=(const AxisTransform2d& other) const {
     return !(*this == other);
   }
 
@@ -111,8 +111,8 @@
   // It's a simplified version of Matrix44::Decompose2d().
   DecomposedTransform Decompose() const;
 
-  const Vector2dF& scale() const { return scale_; }
-  const Vector2dF& translation() const { return translation_; }
+  constexpr const Vector2dF& scale() const { return scale_; }
+  constexpr const Vector2dF& translation() const { return translation_; }
 
   std::string ToString() const;
 
diff --git a/ui/gfx/geometry/matrix44.h b/ui/gfx/geometry/matrix44.h
index 87cf7ebf..cc3cb7c 100644
--- a/ui/gfx/geometry/matrix44.h
+++ b/ui/gfx/geometry/matrix44.h
@@ -43,27 +43,17 @@
       : matrix_{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}} {}
 
   // The parameters are in col-major order.
-  Matrix44(double r0c0,
-           double r1c0,
-           double r2c0,
-           double r3c0,
-           double r0c1,
-           double r1c1,
-           double r2c1,
-           double r3c1,
-           double r0c2,
-           double r1c2,
-           double r2c2,
-           double r3c2,
-           double r0c3,
-           double r1c3,
-           double r2c3,
-           double r3c3)
+  // clang-format off
+  constexpr Matrix44(double r0c0, double r1c0, double r2c0, double r3c0,
+                     double r0c1, double r1c1, double r2c1, double r3c1,
+                     double r0c2, double r1c2, double r2c2, double r3c2,
+                     double r0c3, double r1c3, double r2c3, double r3c3)
       // matrix_ is indexed by [col][row] (i.e. col-major).
       : matrix_{{r0c0, r1c0, r2c0, r3c0},
                 {r0c1, r1c1, r2c1, r3c1},
                 {r0c2, r1c2, r2c2, r3c2},
                 {r0c3, r1c3, r2c3, r3c3}} {}
+  // clang-format on
 
   bool operator==(const Matrix44& other) const {
     return AllTrue(Col(0) == other.Col(0)) && AllTrue(Col(1) == other.Col(1)) &&
@@ -109,7 +99,7 @@
   bool Is2dTransform() const { return IsFlat() && !HasPerspective(); }
 
   // Gets a value at |row|, |col| from the matrix.
-  double rc(int row, int col) const {
+  constexpr double rc(int row, int col) const {
     DCHECK_LE(static_cast<unsigned>(row), 3u);
     DCHECK_LE(static_cast<unsigned>(col), 3u);
     return matrix_[col][row];
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc
index d40feab7..9b16a74 100644
--- a/ui/gfx/geometry/transform.cc
+++ b/ui/gfx/geometry/transform.cc
@@ -102,12 +102,6 @@
           0, 0, 0, 1) {}
 // clang-format on
 
-// static
-const Transform& Transform::Identity() {
-  static const Transform kIdentity;
-  return kIdentity;
-}
-
 Matrix44 Transform::GetFullMatrix() const {
   if (LIKELY(!full_matrix_))
     return AxisTransform2dToMatrix44(axis_2d_);
diff --git a/ui/gfx/geometry/transform.h b/ui/gfx/geometry/transform.h
index 1b2affe..f454626 100644
--- a/ui/gfx/geometry/transform.h
+++ b/ui/gfx/geometry/transform.h
@@ -50,22 +50,12 @@
 
   // Creates a transform from explicit 16 matrix elements in row-major order.
   // Always creates a double precision 4x4 matrix.
-  static Transform RowMajor(double r0c0,
-                            double r0c1,
-                            double r0c2,
-                            double r0c3,
-                            double r1c0,
-                            double r1c1,
-                            double r1c2,
-                            double r1c3,
-                            double r2c0,
-                            double r2c1,
-                            double r2c2,
-                            double r2c3,
-                            double r3c0,
-                            double r3c1,
-                            double r3c2,
-                            double r3c3) {
+  // clang-format off
+  static constexpr Transform RowMajor(
+      double r0c0, double r0c1, double r0c2, double r0c3,
+      double r1c0, double r1c1, double r1c2, double r1c3,
+      double r2c0, double r2c1, double r2c2, double r2c3,
+      double r3c0, double r3c1, double r3c2, double r3c3) {
     return Transform(r0c0, r1c0, r2c0, r3c0,   // col 0
                      r0c1, r1c1, r2c1, r3c1,   // col 1
                      r0c2, r1c2, r2c2, r3c2,   // col 2
@@ -75,39 +65,29 @@
   // Creates a transform from explicit 16 matrix elements in col-major order.
   // Always creates a double precision 4x4 matrix.
   // See also ColMajor(double[]) and ColMajorF(float[]).
-  static Transform ColMajor(double r0c0,
-                            double r1c0,
-                            double r2c0,
-                            double r3c0,
-                            double r0c1,
-                            double r1c1,
-                            double r2c1,
-                            double r3c1,
-                            double r0c2,
-                            double r1c2,
-                            double r2c2,
-                            double r3c2,
-                            double r0c3,
-                            double r1c3,
-                            double r2c3,
-                            double r3c3) {
+  static constexpr Transform ColMajor(
+      double r0c0, double r1c0, double r2c0, double r3c0,
+      double r0c1, double r1c1, double r2c1, double r3c1,
+      double r0c2, double r1c2, double r2c2, double r3c2,
+      double r0c3, double r1c3, double r2c3, double r3c3) {
     return Transform(r0c0, r1c0, r2c0, r3c0,   // col 0
                      r0c1, r1c1, r2c1, r3c1,   // col 1
                      r0c2, r1c2, r2c2, r3c2,   // col 2
                      r0c3, r1c3, r2c3, r3c3);  // col 3
   }
+  // clang-format on
 
   // Creates a transform from explicit 2d elements. All other matrix elements
   // remain the same as the corresponding elements of an identity matrix.
   // Always creates a double precision 4x4 matrix.
   // TODO(crbug.com/1359528): Revisit the above statement. Evaluate performance
   // and precision requirements of SVG and CSS transform:matrix().
-  static Transform Affine(double a,    // a.k.a. r0c0 or scale_x
-                          double b,    // a.k.a. r1c0 or tan(skew_y)
-                          double c,    // a.k.a. r0c1 or tan(skew_x)
-                          double d,    // a.k.a  r1c1 or scale_y
-                          double e,    // a.k.a  r0c3 or translation_x
-                          double f) {  // a.k.a  r1c3 or translaiton_y
+  static constexpr Transform Affine(double a,    // a.k.a. r0c0 or scale_x
+                                    double b,    // a.k.a. r1c0 or tan(skew_y)
+                                    double c,    // a.k.a. r0c1 or tan(skew_x)
+                                    double d,    // a.k.a  r1c1 or scale_y
+                                    double e,    // a.k.a  r0c3 or translation_x
+                                    double f) {  // a.k.a  r1c3 or translaiton_y
     return ColMajor(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1);
   }
 
@@ -115,7 +95,7 @@
   explicit Transform(const Quaternion& q);
 
   // Creates a transform as a 2d translation.
-  static Transform MakeTranslation(float tx, float ty) {
+  static constexpr Transform MakeTranslation(float tx, float ty) {
     return Transform(1, 1, tx, ty);
   }
   static Transform MakeTranslation(const Vector2dF& v) {
@@ -123,22 +103,23 @@
   }
 
   // Creates a transform as a 2d scale.
-  static Transform MakeScale(float scale) { return MakeScale(scale, scale); }
-  static Transform MakeScale(float sx, float sy) {
+  static constexpr Transform MakeScale(float scale) {
+    return MakeScale(scale, scale);
+  }
+  static constexpr Transform MakeScale(float sx, float sy) {
     return Transform(sx, sy, 0, 0);
   }
 
   // Accurately rotate by 90, 180 or 270 degrees about the z axis.
-  static Transform Make90degRotation() { return Affine(0, 1, -1, 0, 0, 0); }
-  static Transform Make180degRotation() { return MakeScale(-1); }
-  static Transform Make270degRotation() { return Affine(0, -1, 1, 0, 0, 0); }
-
-  // Returns a const reference to an identity transform. If you just need an
-  // identity transform as a value, the default constructor is better.
-  static const Transform& Identity();
+  static constexpr Transform Make90degRotation() {
+    return Affine(0, 1, -1, 0, 0, 0);
+  }
+  static constexpr Transform Make180degRotation() { return MakeScale(-1); }
+  static constexpr Transform Make270degRotation() {
+    return Affine(0, -1, 1, 0, 0, 0);
+  }
 
   // Resets this transform to the identity transform.
-  // TODO(crbug.com/1359528): Rename this to SetIdentity or remove it.
   void MakeIdentity() {
     full_matrix_ = false;
     axis_2d_ = AxisTransform2d();
@@ -154,7 +135,7 @@
   bool operator!=(const Transform& rhs) const { return !(*this == rhs); }
 
   // Gets a value at |row|, |col| from the matrix.
-  double rc(int row, int col) const {
+  constexpr double rc(int row, int col) const {
     DCHECK_LE(static_cast<unsigned>(row), 3u);
     DCHECK_LE(static_cast<unsigned>(col), 3u);
     if (LIKELY(!full_matrix_)) {
@@ -565,10 +546,10 @@
  private:
   // Used internally to construct Transform with parameters in col-major order.
   // clang-format off
-  Transform(double r0c0, double r1c0, double r2c0, double r3c0,
-            double r0c1, double r1c1, double r2c1, double r3c1,
-            double r0c2, double r1c2, double r2c2, double r3c2,
-            double r0c3, double r1c3, double r2c3, double r3c3)
+  constexpr Transform(double r0c0, double r1c0, double r2c0, double r3c0,
+                      double r0c1, double r1c1, double r2c1, double r3c1,
+                      double r0c2, double r1c2, double r2c2, double r3c2,
+                      double r0c3, double r1c3, double r2c3, double r3c3)
       : full_matrix_(true),
         matrix_(r0c0, r1c0, r2c0, r3c0,
                 r0c1, r1c1, r2c1, r3c1,
@@ -576,7 +557,10 @@
                 r0c3, r1c3, r2c3, r3c3) {}
   // clang-format on
 
-  Transform(float scale_x, float scale_y, float trans_x, float trans_y)
+  constexpr Transform(float scale_x,
+                      float scale_y,
+                      float trans_x,
+                      float trans_y)
       : axis_2d_(AxisTransform2d::FromScaleAndTranslation(
             Vector2dF(scale_x, scale_y),
             Vector2dF(trans_x, trans_y))) {}
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc
index b8334302..824ff11 100644
--- a/ui/gfx/geometry/transform_unittest.cc
+++ b/ui/gfx/geometry/transform_unittest.cc
@@ -27,25 +27,49 @@
 
 namespace {
 
-#define EXPECT_ROW1_EQ(a, b, c, d, transform) \
+#define STATIC_ROW0_EQ(a, b, c, d, transform) \
+  static_assert((a) == (transform).rc(0, 0)); \
+  static_assert((b) == (transform).rc(0, 1)); \
+  static_assert((c) == (transform).rc(0, 2)); \
+  static_assert((d) == (transform).rc(0, 3));
+
+#define STATIC_ROW1_EQ(a, b, c, d, transform) \
+  static_assert((a) == (transform).rc(1, 0)); \
+  static_assert((b) == (transform).rc(1, 1)); \
+  static_assert((c) == (transform).rc(1, 2)); \
+  static_assert((d) == (transform).rc(1, 3));
+
+#define STATIC_ROW2_EQ(a, b, c, d, transform) \
+  static_assert((a) == (transform).rc(2, 0)); \
+  static_assert((b) == (transform).rc(2, 1)); \
+  static_assert((c) == (transform).rc(2, 2)); \
+  static_assert((d) == (transform).rc(2, 3));
+
+#define STATIC_ROW3_EQ(a, b, c, d, transform) \
+  static_assert((a) == (transform).rc(3, 0)); \
+  static_assert((b) == (transform).rc(3, 1)); \
+  static_assert((c) == (transform).rc(3, 2)); \
+  static_assert((d) == (transform).rc(3, 3));
+
+#define EXPECT_ROW0_EQ(a, b, c, d, transform) \
   EXPECT_FLOAT_EQ((a), (transform).rc(0, 0)); \
   EXPECT_FLOAT_EQ((b), (transform).rc(0, 1)); \
   EXPECT_FLOAT_EQ((c), (transform).rc(0, 2)); \
   EXPECT_FLOAT_EQ((d), (transform).rc(0, 3));
 
-#define EXPECT_ROW2_EQ(a, b, c, d, transform) \
+#define EXPECT_ROW1_EQ(a, b, c, d, transform) \
   EXPECT_FLOAT_EQ((a), (transform).rc(1, 0)); \
   EXPECT_FLOAT_EQ((b), (transform).rc(1, 1)); \
   EXPECT_FLOAT_EQ((c), (transform).rc(1, 2)); \
   EXPECT_FLOAT_EQ((d), (transform).rc(1, 3));
 
-#define EXPECT_ROW3_EQ(a, b, c, d, transform) \
+#define EXPECT_ROW2_EQ(a, b, c, d, transform) \
   EXPECT_FLOAT_EQ((a), (transform).rc(2, 0)); \
   EXPECT_FLOAT_EQ((b), (transform).rc(2, 1)); \
   EXPECT_FLOAT_EQ((c), (transform).rc(2, 2)); \
   EXPECT_FLOAT_EQ((d), (transform).rc(2, 3));
 
-#define EXPECT_ROW4_EQ(a, b, c, d, transform) \
+#define EXPECT_ROW3_EQ(a, b, c, d, transform) \
   EXPECT_FLOAT_EQ((a), (transform).rc(3, 0)); \
   EXPECT_FLOAT_EQ((b), (transform).rc(3, 1)); \
   EXPECT_FLOAT_EQ((c), (transform).rc(3, 2)); \
@@ -54,19 +78,19 @@
 // Checking float values for equality close to zero is not robust using
 // EXPECT_FLOAT_EQ (see gtest documentation). So, to verify rotation matrices,
 // we must use a looser absolute error threshold in some places.
-#define EXPECT_ROW1_NEAR(a, b, c, d, transform, errorThreshold) \
+#define EXPECT_ROW0_NEAR(a, b, c, d, transform, errorThreshold) \
   EXPECT_NEAR((a), (transform).rc(0, 0), (errorThreshold));     \
   EXPECT_NEAR((b), (transform).rc(0, 1), (errorThreshold));     \
   EXPECT_NEAR((c), (transform).rc(0, 2), (errorThreshold));     \
   EXPECT_NEAR((d), (transform).rc(0, 3), (errorThreshold));
 
-#define EXPECT_ROW2_NEAR(a, b, c, d, transform, errorThreshold) \
+#define EXPECT_ROW1_NEAR(a, b, c, d, transform, errorThreshold) \
   EXPECT_NEAR((a), (transform).rc(1, 0), (errorThreshold));     \
   EXPECT_NEAR((b), (transform).rc(1, 1), (errorThreshold));     \
   EXPECT_NEAR((c), (transform).rc(1, 2), (errorThreshold));     \
   EXPECT_NEAR((d), (transform).rc(1, 3), (errorThreshold));
 
-#define EXPECT_ROW3_NEAR(a, b, c, d, transform, errorThreshold) \
+#define EXPECT_ROW2_NEAR(a, b, c, d, transform, errorThreshold) \
   EXPECT_NEAR((a), (transform).rc(2, 0), (errorThreshold));     \
   EXPECT_NEAR((b), (transform).rc(2, 1), (errorThreshold));     \
   EXPECT_NEAR((c), (transform).rc(2, 2), (errorThreshold));     \
@@ -91,54 +115,42 @@
   return true;
 }
 
-void InitializeTestMatrix(Transform* transform) {
-  transform->set_rc(0, 0, 10.f);
-  transform->set_rc(1, 0, 11.f);
-  transform->set_rc(2, 0, 12.f);
-  transform->set_rc(3, 0, 13.f);
-  transform->set_rc(0, 1, 14.f);
-  transform->set_rc(1, 1, 15.f);
-  transform->set_rc(2, 1, 16.f);
-  transform->set_rc(3, 1, 17.f);
-  transform->set_rc(0, 2, 18.f);
-  transform->set_rc(1, 2, 19.f);
-  transform->set_rc(2, 2, 20.f);
-  transform->set_rc(3, 2, 21.f);
-  transform->set_rc(0, 3, 22.f);
-  transform->set_rc(1, 3, 23.f);
-  transform->set_rc(2, 3, 24.f);
-  transform->set_rc(3, 3, 25.f);
+Transform GetTestMatrix1() {
+  // clang-format off
+  constexpr Transform transform = Transform::ColMajor(10.0, 11.0, 12.0, 13.0,
+                                                      14.0, 15.0, 16.0, 17.0,
+                                                      18.0, 19.0, 20.0, 21.0,
+                                                      22.0, 23.0, 24.0, 25.0);
+  // clang-format on
 
-  // Sanity check
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, (*transform));
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, (*transform));
-  EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, (*transform));
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, (*transform));
+  STATIC_ROW0_EQ(10.0, 14.0, 18.0, 22.0, transform);
+  STATIC_ROW1_EQ(11.0, 15.0, 19.0, 23.0, transform);
+  STATIC_ROW2_EQ(12.0, 16.0, 20.0, 24.0, transform);
+  STATIC_ROW3_EQ(13.0, 17.0, 21.0, 25.0, transform);
+
+  EXPECT_ROW0_EQ(10.0, 14.0, 18.0, 22.0, transform);
+  EXPECT_ROW1_EQ(11.0, 15.0, 19.0, 23.0, transform);
+  EXPECT_ROW2_EQ(12.0, 16.0, 20.0, 24.0, transform);
+  EXPECT_ROW3_EQ(13.0, 17.0, 21.0, 25.0, transform);
+  return transform;
 }
 
-void InitializeTestMatrix2(Transform* transform) {
-  transform->set_rc(0, 0, 30.f);
-  transform->set_rc(1, 0, 31.f);
-  transform->set_rc(2, 0, 32.f);
-  transform->set_rc(3, 0, 33.f);
-  transform->set_rc(0, 1, 34.f);
-  transform->set_rc(1, 1, 35.f);
-  transform->set_rc(2, 1, 36.f);
-  transform->set_rc(3, 1, 37.f);
-  transform->set_rc(0, 2, 38.f);
-  transform->set_rc(1, 2, 39.f);
-  transform->set_rc(2, 2, 40.f);
-  transform->set_rc(3, 2, 41.f);
-  transform->set_rc(0, 3, 42.f);
-  transform->set_rc(1, 3, 43.f);
-  transform->set_rc(2, 3, 44.f);
-  transform->set_rc(3, 3, 45.f);
+Transform GetTestMatrix2() {
+  constexpr Transform transform =
+      Transform::RowMajor(30.0, 34.0, 38.0, 42.0, 31.0, 35.0, 39.0, 43.0, 32.0,
+                          36.0, 40.0, 44.0, 33.0, 37.0, 41.0, 45.0);
+  // clang-format on
 
-  // Sanity check
-  EXPECT_ROW1_EQ(30.0f, 34.0f, 38.0f, 42.0f, (*transform));
-  EXPECT_ROW2_EQ(31.0f, 35.0f, 39.0f, 43.0f, (*transform));
-  EXPECT_ROW3_EQ(32.0f, 36.0f, 40.0f, 44.0f, (*transform));
-  EXPECT_ROW4_EQ(33.0f, 37.0f, 41.0f, 45.0f, (*transform));
+  STATIC_ROW0_EQ(30.0, 34.0, 38.0, 42.0, transform);
+  STATIC_ROW1_EQ(31.0, 35.0, 39.0, 43.0, transform);
+  STATIC_ROW2_EQ(32.0, 36.0, 40.0, 44.0, transform);
+  STATIC_ROW3_EQ(33.0, 37.0, 41.0, 45.0, transform);
+
+  EXPECT_ROW0_EQ(30.0, 34.0, 38.0, 42.0, transform);
+  EXPECT_ROW1_EQ(31.0, 35.0, 39.0, 43.0, transform);
+  EXPECT_ROW2_EQ(32.0, 36.0, 40.0, 44.0, transform);
+  EXPECT_ROW3_EQ(33.0, 37.0, 41.0, 45.0, transform);
+  return transform;
 }
 
 Transform ApproxIdentityMatrix(double error) {
@@ -319,8 +331,7 @@
 
 TEST(XFormTest, Equality) {
   Transform lhs, interpolated;
-  auto rhs = Transform::RowMajor(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-                                 15, 16);
+  auto rhs = GetTestMatrix1();
   interpolated = lhs;
   for (int i = 0; i <= 100; ++i) {
     for (int row = 0; row < 4; ++row) {
@@ -964,26 +975,26 @@
   to = Transform();
   to.Translate3d(200.0, 100.0, 300.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 125.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 175.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 150.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 125.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 175.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 150.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Translate3d(200.0, 100.0, 300.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 150.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 150.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 200.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 150.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 150.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 200.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Translate3d(200.0, 100.0, 300.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 200.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 100.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 300.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 200.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 100.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 300.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, VerifyBlendForScale) {
@@ -999,26 +1010,26 @@
   to = Transform();
   to.Scale3d(200.0, 100.0, 300.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_EQ(125.0f, 0.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 175.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 150.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(125.0f, 0.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 175.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 150.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Scale3d(200.0, 100.0, 300.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_EQ(150.0f, 0.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 150.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 200.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(150.0f, 0.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 150.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 200.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Scale3d(200.0, 100.0, 300.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_EQ(200.0f, 0.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 100.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 300.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(200.0f, 0.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 100.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 300.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, VerifyBlendForSkew) {
@@ -1035,26 +1046,26 @@
   to = Transform();
   to.Skew(45.0, 0.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_EQ(1.0f, 0.5f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 0.5f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Skew(45.0, 0.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_EQ(1.0f, 0.25f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 0.25f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Skew(45.0, 0.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0f, 1.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix
   // is inherently underconstrained, and so it does not always compute the
@@ -1099,8 +1110,8 @@
   EXPECT_FLOAT_EQ(0.0, to.rc(1, 2));
   EXPECT_FLOAT_EQ(0.0, to.rc(1, 3));
 
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Skew(0.0, 45.0);
@@ -1120,16 +1131,16 @@
   EXPECT_FLOAT_EQ(0.0, to.rc(1, 2));
   EXPECT_FLOAT_EQ(0.0, to.rc(1, 3));
 
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.Skew(0.0, 45.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW2_NEAR(1.0, 1.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_NEAR(1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW1_NEAR(1.0, 1.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, BlendForRotationAboutX) {
@@ -1151,31 +1162,31 @@
   to = Transform();
   to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, to);
-  EXPECT_ROW2_NEAR(0.0, std::cos(expectedRotationAngle),
+  EXPECT_ROW0_EQ(1.0, 0.0, 0.0, 0.0, to);
+  EXPECT_ROW1_NEAR(0.0, std::cos(expectedRotationAngle),
                    -std::sin(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW3_NEAR(0.0, std::sin(expectedRotationAngle),
+  EXPECT_ROW2_NEAR(0.0, std::sin(expectedRotationAngle),
                    std::cos(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   expectedRotationAngle = gfx::DegToRad(45.0);
   to = Transform();
   to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, to);
-  EXPECT_ROW2_NEAR(0.0, std::cos(expectedRotationAngle),
+  EXPECT_ROW0_EQ(1.0, 0.0, 0.0, 0.0, to);
+  EXPECT_ROW1_NEAR(0.0, std::cos(expectedRotationAngle),
                    -std::sin(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW3_NEAR(0.0, std::sin(expectedRotationAngle),
+  EXPECT_ROW2_NEAR(0.0, std::sin(expectedRotationAngle),
                    std::cos(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, to);
-  EXPECT_ROW2_NEAR(0.0, 0.0, -1.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW3_NEAR(0.0, 1.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_EQ(1.0, 0.0, 0.0, 0.0, to);
+  EXPECT_ROW1_NEAR(0.0, 0.0, -1.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW2_NEAR(0.0, 1.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, BlendForRotationAboutY) {
@@ -1192,31 +1203,31 @@
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 0.0,
+  EXPECT_ROW0_NEAR(std::cos(expectedRotationAngle), 0.0,
                    std::sin(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW2_EQ(0.0, 1.0, 0.0, 0.0, to);
-  EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), 0.0,
+  EXPECT_ROW1_EQ(0.0, 1.0, 0.0, 0.0, to);
+  EXPECT_ROW2_NEAR(-std::sin(expectedRotationAngle), 0.0,
                    std::cos(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   expectedRotationAngle = gfx::DegToRad(45.0);
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 0.0,
+  EXPECT_ROW0_NEAR(std::cos(expectedRotationAngle), 0.0,
                    std::sin(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW2_EQ(0.0, 1.0, 0.0, 0.0, to);
-  EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), 0.0,
+  EXPECT_ROW1_EQ(0.0, 1.0, 0.0, 0.0, to);
+  EXPECT_ROW2_NEAR(-std::sin(expectedRotationAngle), 0.0,
                    std::cos(expectedRotationAngle), 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_NEAR(0.0, 0.0, 1.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW2_EQ(0.0, 1.0, 0.0, 0.0, to);
-  EXPECT_ROW3_NEAR(-1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_NEAR(0.0, 0.0, 1.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW1_EQ(0.0, 1.0, 0.0, 0.0, to);
+  EXPECT_ROW2_NEAR(-1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, BlendForRotationAboutZ) {
@@ -1233,35 +1244,35 @@
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
   to.Blend(from, 0.25);
-  EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
+  EXPECT_ROW0_NEAR(std::cos(expectedRotationAngle),
                    -std::sin(expectedRotationAngle), 0.0, 0.0, to,
                    kErrorThreshold);
-  EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
+  EXPECT_ROW1_NEAR(std::sin(expectedRotationAngle),
                    std::cos(expectedRotationAngle), 0.0, 0.0, to,
                    kErrorThreshold);
-  EXPECT_ROW3_EQ(0.0, 0.0, 1.0, 0.0, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW2_EQ(0.0, 0.0, 1.0, 0.0, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   expectedRotationAngle = gfx::DegToRad(45.0);
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
   to.Blend(from, 0.5);
-  EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
+  EXPECT_ROW0_NEAR(std::cos(expectedRotationAngle),
                    -std::sin(expectedRotationAngle), 0.0, 0.0, to,
                    kErrorThreshold);
-  EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
+  EXPECT_ROW1_NEAR(std::sin(expectedRotationAngle),
                    std::cos(expectedRotationAngle), 0.0, 0.0, to,
                    kErrorThreshold);
-  EXPECT_ROW3_EQ(0.0, 0.0, 1.0, 0.0, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW2_EQ(0.0, 0.0, 1.0, 0.0, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 
   to = Transform();
   to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
   to.Blend(from, 1.0);
-  EXPECT_ROW1_NEAR(0.0, -1.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW2_NEAR(1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
-  EXPECT_ROW3_EQ(0.0, 0.0, 1.0, 0.0, to);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
+  EXPECT_ROW0_NEAR(0.0, -1.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, kErrorThreshold);
+  EXPECT_ROW2_EQ(0.0, 0.0, 1.0, 0.0, to);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
 }
 
 TEST(XFormTest, BlendForCompositeTransform) {
@@ -1759,10 +1770,10 @@
     Transform inverse_translation;
     bool is_invertible = translation.GetInverse(&inverse_translation);
     EXPECT_TRUE(is_invertible);
-    EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, -2.0f, inverse_translation);
-    EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, -3.0f, inverse_translation);
-    EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, -4.0f, inverse_translation);
-    EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_translation);
+    EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, -2.0f, inverse_translation);
+    EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, -3.0f, inverse_translation);
+    EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, -4.0f, inverse_translation);
+    EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_translation);
 
     EXPECT_EQ(inverse_translation, translation.InverseOrIdentity());
 
@@ -1780,10 +1791,10 @@
     Transform inverse_scale;
     bool is_invertible = scale.GetInverse(&inverse_scale);
     EXPECT_TRUE(is_invertible);
-    EXPECT_ROW1_EQ(0.25f, 0.0f, 0.0f, 0.0f, inverse_scale);
-    EXPECT_ROW2_EQ(0.0f, 0.1f, 0.0f, 0.0f, inverse_scale);
-    EXPECT_ROW3_EQ(0.0f, 0.0f, 0.01f, 0.0f, inverse_scale);
-    EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_scale);
+    EXPECT_ROW0_EQ(0.25f, 0.0f, 0.0f, 0.0f, inverse_scale);
+    EXPECT_ROW1_EQ(0.0f, 0.1f, 0.0f, 0.0f, inverse_scale);
+    EXPECT_ROW2_EQ(0.0f, 0.0f, 0.01f, 0.0f, inverse_scale);
+    EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_scale);
 
     EXPECT_EQ(inverse_scale, scale.InverseOrIdentity());
   }
@@ -1841,10 +1852,10 @@
     bool is_invertible = uninvertible.GetInverse(&inverse_of_uninvertible);
     EXPECT_FALSE(is_invertible);
     EXPECT_TRUE(inverse_of_uninvertible.IsIdentity());
-    EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, inverse_of_uninvertible);
-    EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, inverse_of_uninvertible);
-    EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, inverse_of_uninvertible);
-    EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_of_uninvertible);
+    EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, inverse_of_uninvertible);
+    EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, inverse_of_uninvertible);
+    EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, inverse_of_uninvertible);
+    EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_of_uninvertible);
 
     EXPECT_EQ(inverse_of_uninvertible, uninvertible.InverseOrIdentity());
   }
@@ -1926,73 +1937,93 @@
 }
 
 TEST(XFormTest, verifyDefaultConstructorCreatesIdentityMatrix) {
-  Transform A;
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  constexpr Transform A;
+  STATIC_ROW0_EQ(1.0, 0.0, 0.0, 0.0, A);
+  STATIC_ROW1_EQ(0.0, 1.0, 0.0, 0.0, A);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, A);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, A);
   EXPECT_TRUE(A.IsIdentity());
 }
 
 TEST(XFormTest, verifyCopyConstructor) {
-  Transform A;
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
 
   // Copy constructor should produce exact same elements as matrix A.
   Transform B(A);
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, B);
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, B);
-  EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, B);
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, B);
+  EXPECT_EQ(A, B);
+  EXPECT_ROW0_EQ(10.0, 14.0, 18.0, 22.0, B);
+  EXPECT_ROW1_EQ(11.0, 15.0, 19.0, 23.0, B);
+  EXPECT_ROW2_EQ(12.0, 16.0, 20.0, 24.0, B);
+  EXPECT_ROW3_EQ(13.0, 17.0, 21.0, 25.0, B);
 }
 
-TEST(XFormTest, RowMajor) {
-  auto transform =
-      Transform::RowMajor(2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
-                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0);
+// ColMajor() and RowMajor() are tested in GetTestMatrix1() and
+// GetTestTransform2().
 
-  EXPECT_ROW1_EQ(2.0f, 3.0f, 4.0f, 5.0f, transform);
-  EXPECT_ROW2_EQ(6.0f, 7.0f, 8.0f, 9.0f, transform);
-  EXPECT_ROW3_EQ(10.0f, 11.0f, 12.0f, 13.0f, transform);
-  EXPECT_ROW4_EQ(14.0f, 15.0f, 16.0f, 17.0f, transform);
-}
-
-TEST(XFormTest, ColMajor) {
-  auto transform =
-      Transform::ColMajor(2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
-                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0);
-
-  EXPECT_ROW1_EQ(2.0, 6.0, 10.0, 14.0, transform);
-  EXPECT_ROW2_EQ(3.0, 7.0, 11.0, 15.0, transform);
-  EXPECT_ROW3_EQ(4.0, 8.0, 12.0, 16.0, transform);
-  EXPECT_ROW4_EQ(5.0, 9.0, 13.0, 17.0, transform);
+TEST(XFormTest, GetColMajor) {
+  auto transform = GetTestMatrix1();
 
   double data[16];
   transform.GetColMajor(data);
   for (int i = 0; i < 16; i++) {
-    EXPECT_EQ(i + 2.0, data[i]);
+    EXPECT_EQ(i + 10.0, data[i]);
     EXPECT_EQ(data[i], transform.ColMajorData(i));
   }
   EXPECT_EQ(transform, Transform::ColMajor(data));
 }
 
 TEST(XFormTest, Affine) {
-  auto transform = Transform::Affine(2.0, 3.0, 4.0, 5.0, 6.0, 7.0);
+  constexpr auto transform = Transform::Affine(2.0, 3., 4.0, 5.0, 6.0, 7.0);
+  STATIC_ROW0_EQ(2.0, 4.0, 0.0, 6.0, transform);
+  STATIC_ROW1_EQ(3.0, 5.0, 0.0, 7.0, transform);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, transform);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, transform);
+}
 
-  EXPECT_ROW1_EQ(2.0, 4.0, 0.0, 6.0, transform);
-  EXPECT_ROW2_EQ(3.0, 5.0, 0.0, 7.0, transform);
-  EXPECT_ROW3_EQ(0.0, 0.0, 1.0, 0.0, transform);
-  EXPECT_ROW4_EQ(0.0, 0.0, 0.0, 1.0, transform);
+TEST(XFormTest, MakeTranslation) {
+  constexpr auto t = Transform::MakeTranslation(3.5, 4.75);
+  STATIC_ROW0_EQ(1.0, 0.0, 0.0, 3.5, t);
+  STATIC_ROW1_EQ(0.0, 1.0, 0.0, 4.75, t);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, t);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, t);
+}
+
+TEST(XFormTest, MakeScale) {
+  constexpr auto s = Transform::MakeScale(3.5, 4.75);
+  STATIC_ROW0_EQ(3.5, 0.0, 0.0, 0, s);
+  STATIC_ROW1_EQ(0.0, 4.75, 0.0, 0, s);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, s);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, s);
+}
+
+TEST(XFormTest, MakeRotation) {
+  constexpr auto r1 = Transform::Make90degRotation();
+  STATIC_ROW0_EQ(0.0, -1.0, 0.0, 0, r1);
+  STATIC_ROW1_EQ(1.0, 0.0, 0.0, 0, r1);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, r1);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, r1);
+
+  constexpr auto r2 = Transform::Make180degRotation();
+  STATIC_ROW0_EQ(-1.0, 0.0, 0.0, 0, r2);
+  STATIC_ROW1_EQ(0.0, -1.0, 0.0, 0, r2);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, r2);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, r2);
+
+  constexpr auto r3 = Transform::Make270degRotation();
+  STATIC_ROW0_EQ(0.0, 1.0, 0.0, 0, r3);
+  STATIC_ROW1_EQ(-1.0, 0.0, 0.0, 0, r3);
+  STATIC_ROW2_EQ(0.0, 0.0, 1.0, 0.0, r3);
+  STATIC_ROW3_EQ(0.0, 0.0, 0.0, 1.0, r3);
 }
 
 TEST(XFormTest, ColMajorF) {
   float data[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
   auto transform = Transform::ColMajorF(data);
 
-  EXPECT_ROW1_EQ(2.0, 6.0, 10.0, 14.0, transform);
-  EXPECT_ROW2_EQ(3.0, 7.0, 11.0, 15.0, transform);
-  EXPECT_ROW3_EQ(4.0, 8.0, 12.0, 16.0, transform);
-  EXPECT_ROW4_EQ(5.0, 9.0, 13.0, 17.0, transform);
+  EXPECT_ROW0_EQ(2.0, 6.0, 10.0, 14.0, transform);
+  EXPECT_ROW1_EQ(3.0, 7.0, 11.0, 15.0, transform);
+  EXPECT_ROW2_EQ(4.0, 8.0, 12.0, 16.0, transform);
+  EXPECT_ROW3_EQ(5.0, 9.0, 13.0, 17.0, transform);
 
   float data1[16];
   transform.GetColMajorF(data1);
@@ -2003,44 +2034,37 @@
 
 TEST(XFormTest, FromQuaternion) {
   Transform t(Quaternion(1, 2, 3, 4));
-  EXPECT_ROW1_EQ(-25.f, -20.f, 22.f, 0.f, t);
-  EXPECT_ROW2_EQ(28.f, -19.f, 4.f, 0.f, t);
-  EXPECT_ROW3_EQ(-10.f, 20.f, -9.f, 0.f, t);
-  EXPECT_ROW4_EQ(0.f, 0.f, 0.f, 1.f, t);
+  EXPECT_ROW0_EQ(-25.f, -20.f, 22.f, 0.f, t);
+  EXPECT_ROW1_EQ(28.f, -19.f, 4.f, 0.f, t);
+  EXPECT_ROW2_EQ(-10.f, 20.f, -9.f, 0.f, t);
+  EXPECT_ROW3_EQ(0.f, 0.f, 0.f, 1.f, t);
 }
 
 TEST(XFormTest, verifyAssignmentOperator) {
-  Transform A;
-  InitializeTestMatrix(&A);
-  Transform B;
-  InitializeTestMatrix2(&B);
-  Transform C;
-  InitializeTestMatrix2(&C);
+  Transform A = GetTestMatrix1();
+  Transform B = GetTestMatrix2();
+  Transform C = GetTestMatrix2();
   C = B = A;
 
   // Both B and C should now have been re-assigned to the value of A.
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, B);
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, B);
-  EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, B);
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, B);
+  EXPECT_ROW0_EQ(10.0f, 14.0f, 18.0f, 22.0f, B);
+  EXPECT_ROW1_EQ(11.0f, 15.0f, 19.0f, 23.0f, B);
+  EXPECT_ROW2_EQ(12.0f, 16.0f, 20.0f, 24.0f, B);
+  EXPECT_ROW3_EQ(13.0f, 17.0f, 21.0f, 25.0f, B);
 
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, C);
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, C);
-  EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, C);
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, C);
+  EXPECT_ROW0_EQ(10.0f, 14.0f, 18.0f, 22.0f, C);
+  EXPECT_ROW1_EQ(11.0f, 15.0f, 19.0f, 23.0f, C);
+  EXPECT_ROW2_EQ(12.0f, 16.0f, 20.0f, 24.0f, C);
+  EXPECT_ROW3_EQ(13.0f, 17.0f, 21.0f, 25.0f, C);
 }
 
 TEST(XFormTest, verifyEqualsBooleanOperator) {
-  Transform A;
-  InitializeTestMatrix(&A);
-
-  Transform B;
-  InitializeTestMatrix(&B);
+  Transform A = GetTestMatrix1();
+  Transform B = GetTestMatrix1();
   EXPECT_TRUE(A == B);
 
   // Modifying multiple elements should cause equals operator to return false.
-  Transform C;
-  InitializeTestMatrix2(&C);
+  Transform C = GetTestMatrix2();
   EXPECT_FALSE(A == C);
 
   // Modifying any one individual element should cause equals operator to
@@ -2112,34 +2136,28 @@
 }
 
 TEST(XFormTest, verifyMultiplyOperator) {
-  Transform A;
-  InitializeTestMatrix(&A);
-
-  Transform B;
-  InitializeTestMatrix2(&B);
+  Transform A = GetTestMatrix1();
+  Transform B = GetTestMatrix2();
 
   Transform C = A * B;
-  EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, C);
-  EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, C);
-  EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, C);
-  EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, C);
+  EXPECT_ROW0_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, C);
+  EXPECT_ROW1_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, C);
+  EXPECT_ROW2_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, C);
+  EXPECT_ROW3_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, C);
 
   // Just an additional sanity check; matrix multiplication is not commutative.
   EXPECT_FALSE(A * B == B * A);
 }
 
 TEST(XFormTest, verifyMultiplyAndAssignOperator) {
-  Transform A;
-  InitializeTestMatrix(&A);
-
-  Transform B;
-  InitializeTestMatrix2(&B);
+  Transform A = GetTestMatrix1();
+  Transform B = GetTestMatrix2();
 
   A *= B;
-  EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
-  EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
-  EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
-  EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
+  EXPECT_ROW0_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
+  EXPECT_ROW1_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
+  EXPECT_ROW2_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
+  EXPECT_ROW3_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
 
   // Just an additional sanity check; matrix multiplication is not commutative.
   Transform C = A;
@@ -2150,46 +2168,42 @@
 }
 
 TEST(XFormTest, PreConcat) {
-  Transform A;
-  InitializeTestMatrix(&A);
-
-  Transform B;
-  InitializeTestMatrix2(&B);
+  Transform A = GetTestMatrix1();
+  Transform B = GetTestMatrix2();
 
   A.PreConcat(B);
-  EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
-  EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
-  EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
-  EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
+  EXPECT_ROW0_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
+  EXPECT_ROW1_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
+  EXPECT_ROW2_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
+  EXPECT_ROW3_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
 }
 
 TEST(XFormTest, verifyMakeIdentiy) {
-  Transform A;
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
   A.MakeIdentity();
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
   EXPECT_TRUE(A.IsIdentity());
 }
 
 TEST(XFormTest, verifyTranslate) {
   Transform A;
   A.Translate(2.0, 3.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that Translate() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale(5.0, 5.0);
   A.Translate(2.0, 3.0);
-  EXPECT_ROW1_EQ(5.0f, 0.0f, 0.0f, 10.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 5.0f, 0.0f, 15.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(5.0f, 0.0f, 0.0f, 10.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 5.0f, 0.0f, 15.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   Transform B;
   B.Scale(5.0, 5.0);
@@ -2200,19 +2214,19 @@
 TEST(XFormTest, verifyPostTranslate) {
   Transform A;
   A.PostTranslate(2.0, 3.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that PostTranslate() pre-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale(5.0, 5.0);
   A.PostTranslate(2.0, 3.0);
-  EXPECT_ROW1_EQ(5.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 5.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(5.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 5.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   Transform B;
   B.Scale(5.0, 5.0);
@@ -2223,19 +2237,19 @@
 TEST(XFormTest, verifyTranslate3d) {
   Transform A;
   A.Translate3d(2.0, 3.0, 4.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that Translate3d() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.Translate3d(2.0, 3.0, 4.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 12.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 21.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 32.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 12.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 21.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 32.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   Transform B;
   B.Scale3d(6.0, 7.0, 8.0);
@@ -2246,19 +2260,19 @@
 TEST(XFormTest, verifyPostTranslate3d) {
   Transform A;
   A.PostTranslate3d(2.0, 3.0, 4.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that PostTranslate3d() pre-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.PostTranslate3d(2.0, 3.0, 4.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   Transform B;
   B.Scale3d(6.0, 7.0, 8.0);
@@ -2269,73 +2283,73 @@
 TEST(XFormTest, verifyScale) {
   Transform A;
   A.Scale(6.0, 7.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that Scale() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Translate3d(2.0, 3.0, 4.0);
   A.Scale(6.0, 7.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyScale3d) {
   Transform A;
   A.Scale3d(6.0, 7.0, 8.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that scale3d() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Translate3d(2.0, 3.0, 4.0);
   A.Scale3d(6.0, 7.0, 8.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyPostScale3d) {
   Transform A;
   A.PostScale3d(6.0, 7.0, 8.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that PostScale3d() pre-multiplies the existing matrix.
   A.MakeIdentity();
   A.Translate3d(2.0, 3.0, 4.0);
   A.PostScale3d(6.0, 7.0, 8.0);
-  EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 12.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 21.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 32.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 0.0f, 0.0f, 12.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 21.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 32.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, Rotate) {
   Transform A;
   A.Rotate(90.0);
-  EXPECT_ROW1_EQ(0.0, -1.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(1.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -1.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that Rotate() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.Rotate(90.0);
-  EXPECT_ROW1_EQ(0.0, -6.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(7.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -6.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(7.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, RotateAboutXAxis) {
@@ -2345,26 +2359,26 @@
 
   A.MakeIdentity();
   A.RotateAboutXAxis(90.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0, 0.0, -1.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0, 1.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0, 0.0, -1.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0, 1.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   A.MakeIdentity();
   A.RotateAboutXAxis(45.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_NEAR(0.0, cos45, -sin45, 0.0, A, kErrorThreshold);
-  EXPECT_ROW3_NEAR(0.0, sin45, cos45, 0.0, A, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_NEAR(0.0, cos45, -sin45, 0.0, A, kErrorThreshold);
+  EXPECT_ROW2_NEAR(0.0, sin45, cos45, 0.0, A, kErrorThreshold);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that RotateAboutXAxis(angle) post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.RotateAboutXAxis(90.0);
-  EXPECT_ROW1_EQ(6.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(0.0, 0.0, -7.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0, 8.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(0.0, 0.0, -7.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0, 8.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, RotateAboutYAxis) {
@@ -2376,26 +2390,26 @@
   // about x axis or z axis.
   A.MakeIdentity();
   A.RotateAboutYAxis(90.0);
-  EXPECT_ROW1_EQ(0.0, 0.0, 1.0, 0.0, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(-1.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, 0.0, 1.0, 0.0, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(-1.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   A.MakeIdentity();
   A.RotateAboutYAxis(45.0);
-  EXPECT_ROW1_NEAR(cos45, 0.0, sin45, 0.0, A, kErrorThreshold);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_NEAR(-sin45, 0.0, cos45, 0.0, A, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_NEAR(cos45, 0.0, sin45, 0.0, A, kErrorThreshold);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_NEAR(-sin45, 0.0, cos45, 0.0, A, kErrorThreshold);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that RotateAboutYAxis(angle) post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.RotateAboutYAxis(90.0);
-  EXPECT_ROW1_EQ(0.0, 0.0, 6.0, 0.0, A);
-  EXPECT_ROW2_EQ(0.0, 7.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(-8.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, 0.0, 6.0, 0.0, A);
+  EXPECT_ROW1_EQ(0.0, 7.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(-8.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, RotateAboutZAxis) {
@@ -2405,26 +2419,26 @@
 
   A.MakeIdentity();
   A.RotateAboutZAxis(90.0);
-  EXPECT_ROW1_EQ(0.0, -1.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(1.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -1.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   A.MakeIdentity();
   A.RotateAboutZAxis(45.0);
-  EXPECT_ROW1_NEAR(cos45, -sin45, 0.0, 0.0, A, kErrorThreshold);
-  EXPECT_ROW2_NEAR(sin45, cos45, 0.0, 0.0, A, kErrorThreshold);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_NEAR(cos45, -sin45, 0.0, 0.0, A, kErrorThreshold);
+  EXPECT_ROW1_NEAR(sin45, cos45, 0.0, 0.0, A, kErrorThreshold);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that RotateAboutZAxis(angle) post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.RotateAboutZAxis(90.0);
-  EXPECT_ROW1_EQ(0.0, -6.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(7.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -6.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(7.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, RotateAboutForAlignedAxes) {
@@ -2433,49 +2447,49 @@
   // Check rotation about z-axis
   A.MakeIdentity();
   A.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
-  EXPECT_ROW1_EQ(0.0, -1.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(1.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -1.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(1.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Check rotation about x-axis
   A.MakeIdentity();
   A.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0, 0.0, -1.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0, 1.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0, 0.0, -1.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0, 1.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Check rotation about y-axis. Note carefully, the expected pattern is
   // inverted compared to rotating about x axis or z axis.
   A.MakeIdentity();
   A.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
-  EXPECT_ROW1_EQ(0.0, 0.0, 1.0, 0.0, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(-1.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, 0.0, 1.0, 0.0, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(-1.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that rotate3d(axis, angle) post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.RotateAboutZAxis(90.0);
-  EXPECT_ROW1_EQ(0.0, -6.0, 0.0, 0.0, A);
-  EXPECT_ROW2_EQ(7.0, 0.0, 0.0, 0.0, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(0.0, -6.0, 0.0, 0.0, A);
+  EXPECT_ROW1_EQ(7.0, 0.0, 0.0, 0.0, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyRotateAboutForArbitraryAxis) {
   // Check rotation about an arbitrary non-axis-aligned vector.
   Transform A;
   A.RotateAbout(Vector3dF(1.0, 1.0, 1.0), 90.0);
-  EXPECT_ROW1_NEAR(0.3333333333333334258519187, -0.2440169358562924717404030,
+  EXPECT_ROW0_NEAR(0.3333333333333334258519187, -0.2440169358562924717404030,
                    0.9106836025229592124219380, 0.0, A, kErrorThreshold);
-  EXPECT_ROW2_NEAR(0.9106836025229592124219380, 0.3333333333333334258519187,
+  EXPECT_ROW1_NEAR(0.9106836025229592124219380, 0.3333333333333334258519187,
                    -0.2440169358562924717404030, 0.0, A, kErrorThreshold);
-  EXPECT_ROW3_NEAR(-0.2440169358562924717404030, 0.9106836025229592124219380,
+  EXPECT_ROW2_NEAR(-0.2440169358562924717404030, 0.9106836025229592124219380,
                    0.3333333333333334258519187, 0.0, A, kErrorThreshold);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyRotateAboutForDegenerateAxis) {
@@ -2487,32 +2501,32 @@
   // Verify that A remains unchanged.
   EXPECT_TRUE(A.IsIdentity());
 
-  InitializeTestMatrix(&A);
+  A = GetTestMatrix1();
   A.RotateAbout(Vector3dF(0.0, 0.0, 0.0), 35.0);
 
   // Verify that A remains unchanged.
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, A);
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, A);
-  EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, A);
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, A);
+  EXPECT_ROW0_EQ(10.0f, 14.0f, 18.0f, 22.0f, A);
+  EXPECT_ROW1_EQ(11.0f, 15.0f, 19.0f, 23.0f, A);
+  EXPECT_ROW2_EQ(12.0f, 16.0f, 20.0f, 24.0f, A);
+  EXPECT_ROW3_EQ(13.0f, 17.0f, 21.0f, 25.0f, A);
 }
 
 TEST(XFormTest, verifySkew) {
   // Test a skew along X axis only
   Transform A;
   A.Skew(45.0, 0.0);
-  EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Test a skew along Y axis only
   A.MakeIdentity();
   A.Skew(0.0, 45.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Verify that skew() post-multiplies the existing matrix. Row 1, column 2,
   // would incorrectly have value "7" if the matrix is pre-multiplied instead
@@ -2520,36 +2534,36 @@
   A.MakeIdentity();
   A.Scale3d(6.0, 7.0, 8.0);
   A.Skew(45.0, 0.0);
-  EXPECT_ROW1_EQ(6.0f, 6.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(6.0f, 6.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 
   // Test a skew along X and Y axes both
   A.MakeIdentity();
   A.Skew(45.0, 45.0);
+  EXPECT_ROW0_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
   EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyPerspectiveDepth) {
   Transform A;
   A.ApplyPerspectiveDepth(1.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
 
   // Verify that PerspectiveDepth() post-multiplies the existing matrix.
   A.MakeIdentity();
   A.Translate3d(2.0, 3.0, 4.0);
   A.ApplyPerspectiveDepth(1.0);
-  EXPECT_ROW1_EQ(1.0f, 0.0f, -2.0f, 2.0f, A);
-  EXPECT_ROW2_EQ(0.0f, 1.0f, -3.0f, 3.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, -3.0f, 4.0f, A);
-  EXPECT_ROW4_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
+  EXPECT_ROW0_EQ(1.0f, 0.0f, -2.0f, 2.0f, A);
+  EXPECT_ROW1_EQ(0.0f, 1.0f, -3.0f, 3.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, -3.0f, 4.0f, A);
+  EXPECT_ROW3_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
 }
 
 TEST(XFormTest, verifyHasPerspective) {
@@ -2653,9 +2667,7 @@
 }
 
 TEST(XFormTest, verifyIsIdentity) {
-  Transform A;
-
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
   EXPECT_FALSE(A.IsIdentity());
 
   A.MakeIdentity();
@@ -2729,9 +2741,7 @@
 }
 
 TEST(XFormTest, verifyIsIdentityOrTranslation) {
-  Transform A;
-
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
   EXPECT_FALSE(A.IsIdentityOrTranslation());
 
   A.MakeIdentity();
@@ -2937,8 +2947,7 @@
   EXPECT_TRUE((Transform::MakeTranslation(4, 5) * Transform::MakeScale(2, 3))
                   .IsScaleOrTranslation());
 
-  Transform A;
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
   EXPECT_FALSE(A.IsScaleOrTranslation());
 
   // Modifying any non-scale or non-translation components should cause
@@ -3046,22 +3055,20 @@
 }
 
 TEST(XFormTest, Flatten) {
-  Transform A;
-  InitializeTestMatrix(&A);
+  Transform A = GetTestMatrix1();
   EXPECT_FALSE(A.IsFlat());
 
   A.Flatten();
-  EXPECT_ROW1_EQ(10.0f, 14.0f, 0.0f, 22.0f, A);
-  EXPECT_ROW2_EQ(11.0f, 15.0f, 0.0f, 23.0f, A);
-  EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
-  EXPECT_ROW4_EQ(13.0f, 17.0f, 0.0f, 25.0f, A);
+  EXPECT_ROW0_EQ(10.0f, 14.0f, 0.0f, 22.0f, A);
+  EXPECT_ROW1_EQ(11.0f, 15.0f, 0.0f, 23.0f, A);
+  EXPECT_ROW2_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
+  EXPECT_ROW3_EQ(13.0f, 17.0f, 0.0f, 25.0f, A);
 
   EXPECT_TRUE(A.IsFlat());
 }
 
 TEST(XFormTest, IsFlat) {
-  Transform transform;
-  InitializeTestMatrix(&transform);
+  Transform transform = GetTestMatrix1();
 
   // A transform with all entries non-zero isn't flat.
   EXPECT_FALSE(transform.IsFlat());
@@ -4042,7 +4049,7 @@
   EXPECT_EQ(Point3F(1, 2, 3), transform.MapPoint(Point3F(1, 2, 3)));
   EXPECT_EQ(Point3F(-1, -4, -9), transform.MapPoint(Point3F(0, 0, 0)));
 
-  InitializeTestMatrix(&transform);
+  transform = GetTestMatrix1();
   Vector3dF origin(5.f, 6.f, 7.f);
   Transform with_origin = transform;
   Point3F p(41.f, 43.f, 47.f);
@@ -4052,8 +4059,7 @@
 }
 
 TEST(XFormTest, Zoom) {
-  Transform transform;
-  InitializeTestMatrix(&transform);
+  Transform transform = GetTestMatrix1();
   auto zoomed = transform;
   zoomed.Zoom(2.f);
   Point3F p(41.f, 43.f, 47.f);
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
index 1360a56..28f5b65b 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -272,12 +272,15 @@
     pointer_delegate_->OnPointerMotionEvent(
         location, wl::EventDispatchPolicy::kImmediate);
   } else {
-    base::TimeTicks timestamp = base::TimeTicks::Now();
-    auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
-    DCHECK_EQ(touch_pointer_ids.size(), 1u);
-    touch_delegate_->OnTouchMotionEvent(location, timestamp,
-                                        touch_pointer_ids[0],
-                                        wl::EventDispatchPolicy::kImmediate);
+    const auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
+    LOG_IF(WARNING, touch_pointer_ids.size() != 1u)
+        << "Unexpected touch drag motion. Active touch_points: "
+        << touch_pointer_ids.size();
+    if (!touch_pointer_ids.empty()) {
+      touch_delegate_->OnTouchMotionEvent(location, base::TimeTicks::Now(),
+                                          touch_pointer_ids[0],
+                                          wl::EventDispatchPolicy::kImmediate);
+    }
   }
 }
 
@@ -324,18 +327,18 @@
     pointer_delegate_->OnPointerMotionEvent(
         {pointer_location_.x(), -1}, wl::EventDispatchPolicy::kImmediate);
   } else {
-    base::TimeTicks timestamp = base::TimeTicks::Now();
-    auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
-    DCHECK_EQ(touch_pointer_ids.size(), 1u);
-
-    // If an user starts dragging a tab horizontally with touch, Chrome enters
-    // in "horizontal snapping" mode (see ScrollSnapController for details).
-    // Hence, in case of touch driven dragging, use a higher negative dy
-    // to work around the threshold in ScrollSnapController otherwise,
-    // the drag event is discarded.
-    touch_delegate_->OnTouchMotionEvent(
-        {pointer_location_.x(), kHorizontalRailExitThreshold}, timestamp,
-        touch_pointer_ids[0], wl::EventDispatchPolicy::kImmediate);
+    const auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
+    if (!touch_pointer_ids.empty()) {
+      // If an user starts dragging a tab horizontally with touch, Chrome enters
+      // in "horizontal snapping" mode (see ScrollSnapController for details).
+      // Hence, in case of touch driven dragging, use a higher negative dy
+      // to work around the threshold in ScrollSnapController otherwise,
+      // the drag event is discarded.
+      touch_delegate_->OnTouchMotionEvent(
+          {pointer_location_.x(), kHorizontalRailExitThreshold},
+          base::TimeTicks::Now(), touch_pointer_ids[0],
+          wl::EventDispatchPolicy::kImmediate);
+    }
   }
 }
 
@@ -501,11 +504,12 @@
           wl::EventDispatchPolicy::kImmediate);
     }
   } else {
-    auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
-    DCHECK_EQ(touch_pointer_ids.size(), 1u);
-    touch_delegate_->OnTouchReleaseEvent(base::TimeTicks::Now(),
-                                         touch_pointer_ids[0],
-                                         wl::EventDispatchPolicy::kImmediate);
+    const auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
+    if (!touch_pointer_ids.empty()) {
+      touch_delegate_->OnTouchReleaseEvent(base::TimeTicks::Now(),
+                                           touch_pointer_ids[0],
+                                           wl::EventDispatchPolicy::kImmediate);
+    }
   }
 
   pointer_grab_owner_ = nullptr;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc
index a0796dc..f845ad87 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc
@@ -9,6 +9,7 @@
 #include "ui/events/event.h"
 #include "ui/events/platform/platform_event_observer.h"
 #include "ui/ozone/platform/wayland/host/wayland_event_source.h"
+#include "ui/ozone/platform/wayland/host/wayland_seat.h"
 #include "ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h"
 #include "ui/ozone/platform/wayland/test/mock_pointer.h"
 #include "ui/ozone/platform/wayland/test/mock_surface.h"
@@ -57,7 +58,7 @@
 
 class WaylandPointerGesturesTest : public WaylandTest {
  public:
-  WaylandPointerGesturesTest() = default;
+  WaylandPointerGesturesTest() : WaylandTest(TestServerMode::kAsync) {}
   WaylandPointerGesturesTest(const WaylandPointerGesturesTest&) = delete;
   WaylandPointerGesturesTest& operator=(const WaylandPointerGesturesTest&) =
       delete;
@@ -67,11 +68,12 @@
     WaylandTest::SetUp();
 
     // Pointer capability is required for gesture objects to be initialised.
-    wl_seat_send_capabilities(server_.seat()->resource(),
-                              WL_SEAT_CAPABILITY_POINTER);
+    PostToServerAndWait([](wl::TestWaylandServerThread* server) {
+      wl_seat_send_capabilities(server->seat()->resource(),
+                                WL_SEAT_CAPABILITY_POINTER);
+    });
 
-    Sync();
-
+    ASSERT_TRUE(connection_->seat()->pointer());
     ASSERT_TRUE(connection_->wayland_zwp_pointer_gestures());
   }
 };
@@ -88,33 +90,42 @@
 //
 // See https://crbug.com/1283652
 TEST_P(WaylandPointerGesturesTest, PinchZoomScale) {
-  auto* const mock_surface = server_.GetObject<wl::MockSurface>(
-      window_->root_surface()->get_surface_id());
+  PostToServerAndWait([surface_id = window_->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const pointer = server->seat()->pointer()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
 
-  uint32_t serial = 0;
-  auto* pointer = server_.seat()->pointer();
-  wl_pointer_send_enter(pointer->resource(), ++serial, mock_surface->resource(),
-                        wl_fixed_from_int(50), wl_fixed_from_int(50));
-  wl_pointer_send_frame(pointer->resource());
+    wl_pointer_send_enter(pointer, server->GetNextSerial(), surface,
+                          wl_fixed_from_int(50), wl_fixed_from_int(50));
+    wl_pointer_send_frame(pointer);
+  });
 
   PinchEventScaleRecorder observer;
 
-  auto* pinch_resource = server_.wp_pointer_gestures().pinch()->resource();
-  zwp_pointer_gesture_pinch_v1_send_begin(pinch_resource, ++serial,
-                                          /* time */ 0,
-                                          mock_surface->resource(),
-                                          /* fingers */ 2);
-  Sync();
+  PostToServerAndWait([surface_id = window_->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const pinch = server->wp_pointer_gestures().pinch()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
+
+    zwp_pointer_gesture_pinch_v1_send_begin(pinch, server->GetNextSerial(),
+                                            server->GetNextTime(), surface,
+                                            /* fingers */ 2);
+  });
 
   constexpr double kScales[] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.4,
                                 1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7,
                                 0.6, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};
   [[maybe_unused]] auto previous_scale = kScales[0];
   for (auto scale : kScales) {
-    zwp_pointer_gesture_pinch_v1_send_update(
-        pinch_resource, /* time */ 0, /* dx */ 0, /* dy */ 0,
-        wl_fixed_from_double(scale), /* rotation */ 0);
-    Sync();
+    PostToServerAndWait([scale](wl::TestWaylandServerThread* server) {
+      auto* const pinch = server->wp_pointer_gestures().pinch()->resource();
+
+      zwp_pointer_gesture_pinch_v1_send_update(
+          pinch, /* time */ 0, /* dx */ 0, /* dy */ 0,
+          wl_fixed_from_double(scale), /* rotation */ 0);
+    });
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
     EXPECT_FLOAT_EQ(observer.latest_scale_update(),
                     wl_fixed_to_double(wl_fixed_from_double(scale)));
diff --git a/ui/ozone/platform/wayland/test/wayland_test.h b/ui/ozone/platform/wayland/test/wayland_test.h
index a91e8b5..fed9a7d 100644
--- a/ui/ozone/platform/wayland/test/wayland_test.h
+++ b/ui/ozone/platform/wayland/test/wayland_test.h
@@ -11,6 +11,7 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/buildflags.h"
 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
@@ -129,7 +130,7 @@
   wl::TestWaylandServerThread server_;
   raw_ptr<wl::MockSurface> surface_;
 
-  MockWaylandPlatformWindowDelegate delegate_;
+  ::testing::NiceMock<MockWaylandPlatformWindowDelegate> delegate_;
   std::unique_ptr<ScopedKeyboardLayoutEngine> scoped_keyboard_layout_engine_;
   std::unique_ptr<WaylandSurfaceFactory> surface_factory_;
   std::unique_ptr<WaylandBufferManagerGpu> buffer_manager_gpu_;
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.html b/ui/webui/resources/cr_components/history_clusters/url_visit.html
index b5a5d0d..ee08f05 100644
--- a/ui/webui/resources/cr_components/history_clusters/url_visit.html
+++ b/ui/webui/resources/cr_components/history_clusters/url_visit.html
@@ -44,13 +44,14 @@
   #link-container {
     align-items: center;
     display: flex;
+    margin-inline-end: var(--cluster-padding-horizontal);
     min-width: 0;
     outline: none;
-    padding-inline-end: var(--cluster-padding-horizontal);
+    padding-inline-end: 2px; /* So focus outline does not intersect text */
   }
 
   :host(:hover) #link-container {
-    padding-inline-end: 0;
+    margin-inline-end: 0;
   }
 
   :host-context(.focus-outline-visible) #link-container:focus {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
index acacff5..63df5ee 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -45,7 +45,6 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.compat.ApiHelperForO;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.metrics.RecordHistogram;
@@ -982,7 +981,7 @@
 
         PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> {
             ApplicationInfo appInfo = packageInfo.applicationInfo;
-            String[] splitNames = ApiHelperForO.getSplitNames(appInfo);
+            String[] splitNames = appInfo.splitNames;
             if (splitNames == null) {
                 return;
             }